├── Changelog ├── LICENSE ├── Makefile.in ├── Makefile.inc.in ├── OS_STATUS ├── README ├── TODO ├── YOU_REALLY_WANT_TO_INSTALL_THIS_LIBRARY ├── attic ├── adns_gnuanl.c ├── adns_gnuanl.h ├── gnu_adns ├── gnu_adns.c └── gnu_adns.h ├── config.h.in ├── configure ├── configure.ac ├── default.conf.in ├── dnspkt.h ├── docs ├── Makefile ├── man.1 ├── man.tex └── rfc1123.txt.gz ├── ext ├── _xdebug.c ├── _xdebug.h ├── _xmalloc.c ├── _xmalloc.h ├── chtbl.c ├── chtbl.h ├── cidr.c ├── cidr.h ├── fread.c ├── fread.h ├── hash.c ├── hash.h ├── standard_dns.c ├── standard_dns.h ├── xmalloc.c └── xmalloc.h ├── getopts.c ├── getopts.h ├── libs └── c-ares ├── main.c ├── main.h ├── misc.c ├── misc.h ├── myadns.c ├── myadns.h ├── readconf.c ├── readconf.h ├── scripts ├── _auto.sh ├── mkdist.sh ├── mkslackpkg └── runtests.sh ├── settings.h ├── sql └── pgsql_schema.sql └── wordlists ├── WARNING ├── dict_words.gz ├── dos.gz ├── etc-hosts.gz ├── fast.gz ├── jargon.gz ├── mit.edu.gz ├── movie-characters.gz ├── names.gz ├── oz.gz └── prune /Changelog: -------------------------------------------------------------------------------- 1 | 0.0.5 2 | 3 | 0.1.0 4 | add glibc adns (getaddrinfo_a) support 5 | 6 | 0.2.0 7 | change glibc adns to gnu-adns to c-ares async dns 8 | 9 | 0.2.1 10 | tidy up all features to a semi-working state 11 | make uninstall safer 12 | clean up makefile for destdir support, etc. 13 | 14 | 0.2.2 15 | autoconfify, attempt to guess about portability in some limited sense 16 | attempt to make discovery mode work 17 | 18 | 0.2.3 19 | document and pack for release 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | namedrop and associated utilities are GPL software. Please contact 2 | osace@dyadsecurity.com with questions about licensing. 3 | 4 | GNU GENERAL PUBLIC LICENSE 5 | Version 2, June 1991 6 | 7 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 8 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 9 | Everyone is permitted to copy and distribute verbatim copies 10 | of this license document, but changing it is not allowed. 11 | 12 | Preamble 13 | 14 | The licenses for most software are designed to take away your 15 | freedom to share and change it. By contrast, the GNU General Public 16 | License is intended to guarantee your freedom to share and change free 17 | software--to make sure the software is free for all its users. This 18 | General Public License applies to most of the Free Software 19 | Foundation's software and to any other program whose authors commit to 20 | using it. (Some other Free Software Foundation software is covered by 21 | the GNU Library General Public License instead.) You can apply it to 22 | your programs, too. 23 | 24 | When we speak of free software, we are referring to freedom, not 25 | price. Our General Public Licenses are designed to make sure that you 26 | have the freedom to distribute copies of free software (and charge for 27 | this service if you wish), that you receive source code or can get it 28 | if you want it, that you can change the software or use pieces of it 29 | in new free programs; and that you know you can do these things. 30 | 31 | To protect your rights, we need to make restrictions that forbid 32 | anyone to deny you these rights or to ask you to surrender the rights. 33 | These restrictions translate to certain responsibilities for you if you 34 | distribute copies of the software, or if you modify it. 35 | 36 | For example, if you distribute copies of such a program, whether 37 | gratis or for a fee, you must give the recipients all the rights that 38 | you have. You must make sure that they, too, receive or can get the 39 | source code. And you must show them these terms so they know their 40 | rights. 41 | 42 | We protect your rights with two steps: (1) copyright the software, and 43 | (2) offer you this license which gives you legal permission to copy, 44 | distribute and/or modify the software. 45 | 46 | Also, for each author's protection and ours, we want to make certain 47 | that everyone understands that there is no warranty for this free 48 | software. If the software is modified by someone else and passed on, we 49 | want its recipients to know that what they have is not the original, so 50 | that any problems introduced by others will not reflect on the original 51 | authors' reputations. 52 | 53 | Finally, any free program is threatened constantly by software 54 | patents. We wish to avoid the danger that redistributors of a free 55 | program will individually obtain patent licenses, in effect making the 56 | program proprietary. To prevent this, we have made it clear that any 57 | patent must be licensed for everyone's free use or not licensed at all. 58 | 59 | The precise terms and conditions for copying, distribution and 60 | modification follow. 61 | 62 | GNU GENERAL PUBLIC LICENSE 63 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 64 | 65 | 0. This License applies to any program or other work which contains 66 | a notice placed by the copyright holder saying it may be distributed 67 | under the terms of this General Public License. The "Program", below, 68 | refers to any such program or work, and a "work based on the Program" 69 | means either the Program or any derivative work under copyright law: 70 | that is to say, a work containing the Program or a portion of it, 71 | either verbatim or with modifications and/or translated into another 72 | language. (Hereinafter, translation is included without limitation in 73 | the term "modification".) Each licensee is addressed as "you". 74 | 75 | Activities other than copying, distribution and modification are not 76 | covered by this License; they are outside its scope. The act of 77 | running the Program is not restricted, and the output from the Program 78 | is covered only if its contents constitute a work based on the 79 | Program (independent of having been made by running the Program). 80 | Whether that is true depends on what the Program does. 81 | 82 | 1. You may copy and distribute verbatim copies of the Program's 83 | source code as you receive it, in any medium, provided that you 84 | conspicuously and appropriately publish on each copy an appropriate 85 | copyright notice and disclaimer of warranty; keep intact all the 86 | notices that refer to this License and to the absence of any warranty; 87 | and give any other recipients of the Program a copy of this License 88 | along with the Program. 89 | 90 | You may charge a fee for the physical act of transferring a copy, and 91 | you may at your option offer warranty protection in exchange for a fee. 92 | 93 | 2. You may modify your copy or copies of the Program or any portion 94 | of it, thus forming a work based on the Program, and copy and 95 | distribute such modifications or work under the terms of Section 1 96 | above, provided that you also meet all of these conditions: 97 | 98 | a) You must cause the modified files to carry prominent notices 99 | stating that you changed the files and the date of any change. 100 | 101 | b) You must cause any work that you distribute or publish, that in 102 | whole or in part contains or is derived from the Program or any 103 | part thereof, to be licensed as a whole at no charge to all third 104 | parties under the terms of this License. 105 | 106 | c) If the modified program normally reads commands interactively 107 | when run, you must cause it, when started running for such 108 | interactive use in the most ordinary way, to print or display an 109 | announcement including an appropriate copyright notice and a 110 | notice that there is no warranty (or else, saying that you provide 111 | a warranty) and that users may redistribute the program under 112 | these conditions, and telling the user how to view a copy of this 113 | License. (Exception: if the Program itself is interactive but 114 | does not normally print such an announcement, your work based on 115 | the Program is not required to print an announcement.) 116 | 117 | These requirements apply to the modified work as a whole. If 118 | identifiable sections of that work are not derived from the Program, 119 | and can be reasonably considered independent and separate works in 120 | themselves, then this License, and its terms, do not apply to those 121 | sections when you distribute them as separate works. But when you 122 | distribute the same sections as part of a whole which is a work based 123 | on the Program, the distribution of the whole must be on the terms of 124 | this License, whose permissions for other licensees extend to the 125 | entire whole, and thus to each and every part regardless of who wrote it. 126 | 127 | Thus, it is not the intent of this section to claim rights or contest 128 | your rights to work written entirely by you; rather, the intent is to 129 | exercise the right to control the distribution of derivative or 130 | collective works based on the Program. 131 | 132 | In addition, mere aggregation of another work not based on the Program 133 | with the Program (or with a work based on the Program) on a volume of 134 | a storage or distribution medium does not bring the other work under 135 | the scope of this License. 136 | 137 | 3. You may copy and distribute the Program (or a work based on it, 138 | under Section 2) in object code or executable form under the terms of 139 | Sections 1 and 2 above provided that you also do one of the following: 140 | 141 | a) Accompany it with the complete corresponding machine-readable 142 | source code, which must be distributed under the terms of Sections 143 | 1 and 2 above on a medium customarily used for software interchange; or, 144 | 145 | b) Accompany it with a written offer, valid for at least three 146 | years, to give any third party, for a charge no more than your 147 | cost of physically performing source distribution, a complete 148 | machine-readable copy of the corresponding source code, to be 149 | distributed under the terms of Sections 1 and 2 above on a medium 150 | customarily used for software interchange; or, 151 | 152 | c) Accompany it with the information you received as to the offer 153 | to distribute corresponding source code. (This alternative is 154 | allowed only for noncommercial distribution and only if you 155 | received the program in object code or executable form with such 156 | an offer, in accord with Subsection b above.) 157 | 158 | The source code for a work means the preferred form of the work for 159 | making modifications to it. For an executable work, complete source 160 | code means all the source code for all modules it contains, plus any 161 | associated interface definition files, plus the scripts used to 162 | control compilation and installation of the executable. However, as a 163 | special exception, the source code distributed need not include 164 | anything that is normally distributed (in either source or binary 165 | form) with the major components (compiler, kernel, and so on) of the 166 | operating system on which the executable runs, unless that component 167 | itself accompanies the executable. 168 | 169 | If distribution of executable or object code is made by offering 170 | access to copy from a designated place, then offering equivalent 171 | access to copy the source code from the same place counts as 172 | distribution of the source code, even though third parties are not 173 | compelled to copy the source along with the object code. 174 | 175 | 4. You may not copy, modify, sublicense, or distribute the Program 176 | except as expressly provided under this License. Any attempt 177 | otherwise to copy, modify, sublicense or distribute the Program is 178 | void, and will automatically terminate your rights under this License. 179 | However, parties who have received copies, or rights, from you under 180 | this License will not have their licenses terminated so long as such 181 | parties remain in full compliance. 182 | 183 | 5. You are not required to accept this License, since you have not 184 | signed it. However, nothing else grants you permission to modify or 185 | distribute the Program or its derivative works. These actions are 186 | prohibited by law if you do not accept this License. Therefore, by 187 | modifying or distributing the Program (or any work based on the 188 | Program), you indicate your acceptance of this License to do so, and 189 | all its terms and conditions for copying, distributing or modifying 190 | the Program or works based on it. 191 | 192 | 6. Each time you redistribute the Program (or any work based on the 193 | Program), the recipient automatically receives a license from the 194 | original licensor to copy, distribute or modify the Program subject to 195 | these terms and conditions. You may not impose any further 196 | restrictions on the recipients' exercise of the rights granted herein. 197 | You are not responsible for enforcing compliance by third parties to 198 | this License. 199 | 200 | 7. If, as a consequence of a court judgment or allegation of patent 201 | infringement or for any other reason (not limited to patent issues), 202 | conditions are imposed on you (whether by court order, agreement or 203 | otherwise) that contradict the conditions of this License, they do not 204 | excuse you from the conditions of this License. If you cannot 205 | distribute so as to satisfy simultaneously your obligations under this 206 | License and any other pertinent obligations, then as a consequence you 207 | may not distribute the Program at all. For example, if a patent 208 | license would not permit royalty-free redistribution of the Program by 209 | all those who receive copies directly or indirectly through you, then 210 | the only way you could satisfy both it and this License would be to 211 | refrain entirely from distribution of the Program. 212 | 213 | If any portion of this section is held invalid or unenforceable under 214 | any particular circumstance, the balance of the section is intended to 215 | apply and the section as a whole is intended to apply in other 216 | circumstances. 217 | 218 | It is not the purpose of this section to induce you to infringe any 219 | patents or other property right claims or to contest validity of any 220 | such claims; this section has the sole purpose of protecting the 221 | integrity of the free software distribution system, which is 222 | implemented by public license practices. Many people have made 223 | generous contributions to the wide range of software distributed 224 | through that system in reliance on consistent application of that 225 | system; it is up to the author/donor to decide if he or she is willing 226 | to distribute software through any other system and a licensee cannot 227 | impose that choice. 228 | 229 | This section is intended to make thoroughly clear what is believed to 230 | be a consequence of the rest of this License. 231 | 232 | 8. If the distribution and/or use of the Program is restricted in 233 | certain countries either by patents or by copyrighted interfaces, the 234 | original copyright holder who places the Program under this License 235 | may add an explicit geographical distribution limitation excluding 236 | those countries, so that distribution is permitted only in or among 237 | countries not thus excluded. In such case, this License incorporates 238 | the limitation as if written in the body of this License. 239 | 240 | 9. The Free Software Foundation may publish revised and/or new versions 241 | of the General Public License from time to time. Such new versions will 242 | be similar in spirit to the present version, but may differ in detail to 243 | address new problems or concerns. 244 | 245 | Each version is given a distinguishing version number. If the Program 246 | specifies a version number of this License which applies to it and "any 247 | later version", you have the option of following the terms and conditions 248 | either of that version or of any later version published by the Free 249 | Software Foundation. If the Program does not specify a version number of 250 | this License, you may choose any version ever published by the Free Software 251 | Foundation. 252 | 253 | 10. If you wish to incorporate parts of the Program into other free 254 | programs whose distribution conditions are different, write to the author 255 | to ask for permission. For software which is copyrighted by the Free 256 | Software Foundation, write to the Free Software Foundation; we sometimes 257 | make exceptions for this. Our decision will be guided by the two goals 258 | of preserving the free status of all derivatives of our free software and 259 | of promoting the sharing and reuse of software generally. 260 | 261 | NO WARRANTY 262 | 263 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 264 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 265 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 266 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 267 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 268 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 269 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 270 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 271 | REPAIR OR CORRECTION. 272 | 273 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 274 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 275 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 276 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 277 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 278 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 279 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 280 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 281 | POSSIBILITY OF SUCH DAMAGES. 282 | 283 | END OF TERMS AND CONDITIONS 284 | 285 | How to Apply These Terms to Your New Programs 286 | 287 | If you develop a new program, and you want it to be of the greatest 288 | possible use to the public, the best way to achieve this is to make it 289 | free software which everyone can redistribute and change under these terms. 290 | 291 | To do so, attach the following notices to the program. It is safest 292 | to attach them to the start of each source file to most effectively 293 | convey the exclusion of warranty; and each file should have at least 294 | the "copyright" line and a pointer to where the full notice is found. 295 | 296 | 297 | Copyright (C) 298 | 299 | This program is free software; you can redistribute it and/or modify 300 | it under the terms of the GNU General Public License as published by 301 | the Free Software Foundation; either version 2 of the License, or 302 | (at your option) any later version. 303 | 304 | This program is distributed in the hope that it will be useful, 305 | but WITHOUT ANY WARRANTY; without even the implied warranty of 306 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 307 | GNU General Public License for more details. 308 | 309 | You should have received a copy of the GNU General Public License 310 | along with this program; if not, write to the Free Software 311 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 312 | 313 | 314 | Also add information on how to contact you by electronic and paper mail. 315 | 316 | If the program is interactive, make it output a short notice like this 317 | when it starts in an interactive mode: 318 | 319 | Gnomovision version 69, Copyright (C) year name of author 320 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 321 | This is free software, and you are welcome to redistribute it 322 | under certain conditions; type `show c' for details. 323 | 324 | The hypothetical commands `show w' and `show c' should show the appropriate 325 | parts of the General Public License. Of course, the commands you use may 326 | be called something other than `show w' and `show c'; they could even be 327 | mouse-clicks or menu items--whatever suits your program. 328 | 329 | You should also get your employer (if you work as a programmer) or your 330 | school, if any, to sign a "copyright disclaimer" for the program, if 331 | necessary. Here is a sample; alter the names: 332 | 333 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 334 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 335 | 336 | , 1 April 1989 337 | Ty Coon, President of Vice 338 | 339 | This General Public License does not permit incorporating your program into 340 | proprietary programs. If your program is a subroutine library, you may 341 | consider it more useful to permit linking proprietary applications with the 342 | library. If this is what you want to do, use the GNU Library General 343 | Public License instead of this License. 344 | -------------------------------------------------------------------------------- /Makefile.in: -------------------------------------------------------------------------------- 1 | include Makefile.inc 2 | 3 | .c.o: 4 | $(CC) $(CFLAGS) -c -o $@ $< 5 | 6 | all: $(PROGNAME) default.conf docsd 7 | 8 | wrap: myadns 9 | 10 | SRCS=getopts.c readconf.c ext/cidr.c ext/fread.c ext/xmalloc.c ext/hash.c @EXTRA_SRCS@ ext/standard_dns.c main.c misc.c ext/chtbl.c 11 | 12 | HDRS=$(SRCS:.c=.h) settings.h 13 | OBJS=$(SRCS:.c=.o) 14 | 15 | $(OBJS): $(HDRS) Makefile 16 | 17 | WORDLISTS=dict_words.gz dos.gz etc-hosts.gz fast.gz jargon.gz mit.edu.gz movie-characters.gz names.gz oz.gz 18 | DEFWL=fast.gz 19 | 20 | docsd: 21 | $(USE_MAKE) -C docs 22 | 23 | $(PROGNAME): $(HDRS) Makefile $(OBJS) 24 | echo $(OBJS) 25 | $(CC) $(CFLAGS) $(LDFLAGS) -o $(PROGNAME) $(OBJS) $(LIBS) 26 | 27 | default.conf: default.conf.in 28 | cat default.conf.in | sed -e 's,@SHAREDIR@,'"$(SHAREDIR)"',g' -e 's,@PROGNAME@,'"$(PROGNAME)"',g' -e 's,@SYSCONFDIR@,'"$(SYSCONFDIR)"',g' > default.conf 29 | 30 | install: all 31 | mkdir -p $(DESTDIR)/$(BINDIR) 32 | $(INSTALL) -m755 $(PROGNAME) $(DESTDIR)/$(BINDIR) 33 | mkdir -p $(DESTDIR)/$(MAN1DIR) 34 | $(INSTALL) -m644 docs/man.1 $(DESTDIR)/$(MAN1DIR)/$(PROGNAME).$(MANSUF) 35 | $(MKDIR) $(DESTDIR)/$(SYSCONFDIR) 36 | if test -f $(DESTDIR)/$(SYSCONFDIR)/$(PROGNAME).conf; then \ 37 | $(INSTALL) -m644 default.conf $(DESTDIR)/$(SYSCONFDIR)/$(PROGNAME).conf.new; \ 38 | else\ 39 | $(INSTALL) -m644 default.conf $(DESTDIR)/$(SYSCONFDIR)/$(PROGNAME).conf;\ 40 | fi 41 | $(MKDIR) $(DESTDIR)/$(SHAREDIR) 42 | ( cd wordlists && \ 43 | for g in $(WORDLISTS); do \ 44 | $(INSTALL) -m644 $$g $(DESTDIR)/$(SHAREDIR)/; \ 45 | done \ 46 | ) 47 | ( cd $(DESTDIR)/$(SHAREDIR) && rm -f default.gz && $(LN) $(DEFWL) default.gz ) 48 | 49 | myadns: myadns.c ext/xmalloc.o misc.o 50 | $(CC) $(CFLAGS) -D_WRAP_ -c myadns.c 51 | $(CC) $(CFLAGS) -o myadns ext/xmalloc.o myadns.o misc.o $(LIBS) 52 | rm -f myadns.o 53 | 54 | ext/hash: ext/hash.c 55 | $(CC) $(CFLAGS) -D_WRAP_ -o ext/hash ext/hash.c 56 | 57 | debug: clean 58 | (cd ext && rm xmalloc.[ch] && ln -s _xdebug.c xmalloc.c && ln -s _xdebug.h xmalloc.h ) 59 | 60 | nodebug: clean 61 | (cd ext && rm xmalloc.[ch] && ln -s _xmalloc.c xmalloc.c && ln -s _xmalloc.h xmalloc.h ) 62 | 63 | uninstall: 64 | -rm -f $(BINDIR)/$(PROGNAME) 65 | -if test -d $(MAN1DIR); then \ 66 | rm -f $(MAN1DIR)/$(PROGNAME).$(MANSUF); \ 67 | fi 68 | -if test -d $(SHAREDIR); then \ 69 | ( cd $(SHAREDIR) && rm -f $(WORDLISTS) ); \ 70 | rmdir $(SHAREDIR); \ 71 | fi 72 | -if test -d $(SYSCONFDIR); then \ 73 | rm -f $(SYSCONFDIR)/$(PROGNAME).conf; \ 74 | rmdir $(SYSCONFDIR); \ 75 | fi 76 | 77 | tags: 78 | cscope -Rqb 79 | 80 | clean: 81 | rm -rf core $(OBJS) $(PROGNAME) cscope.* gmon.out myadns ext/hash default.conf 82 | $(USE_MAKE) -C docs clean 83 | 84 | slack: 85 | ./scripts/mkslackpkg 86 | 87 | check: all 88 | ./scripts/runtests.sh 89 | 90 | distclean: clean 91 | rm -rf configure Makefile.inc config.log config.status autom4te.cache config.h packages stage 92 | $(USE_MAKE) -C docs distclean 93 | 94 | dist: distclean 95 | ./scripts/mkdist.sh 96 | -------------------------------------------------------------------------------- /Makefile.inc.in: -------------------------------------------------------------------------------- 1 | # user configurable options below 2 | 3 | # if you dont have c-ares then change CARES to 0, no async requests will not be available 4 | HAVE_C_ARES=@HAVE_C_ARES@ 5 | 6 | USE_MAKE=@USE_MAKE@ 7 | 8 | prefix=@prefix@ 9 | exec_prefix=@exec_prefix@ 10 | 11 | # end of user configurable options 12 | 13 | # other options you may need to change below. 14 | 15 | # this should be gcc for gnu type platforms, or cc if that doesnt work generally 16 | CC=@CC@ 17 | 18 | CCINCS=-I. -I/usr/local/include 19 | CCDEFS=@DEFS@ -DHAVE_C_ARES=@HAVE_C_ARES@ -DBIGENDIAN=@BIGENDIAN@ 20 | CCOPTS=@CFLAGS@ 21 | CCWARNS=-Wall -Wshadow -Wcast-align -Wcast-qual -Wchar-subscripts -Wno-deprecated-declarations -Wformat-security -Wimplicit -Wsign-compare -Wuninitialized -Wunused -Wwrite-strings -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-braces -Wparentheses -Wsequence-point -Wno-format-y2k -DSTRICT #-Werror 22 | CCWARNS=-Wall 23 | 24 | LDFLAGS=-L/usr/local/lib 25 | LIBS=-lz @LIBS@ @EXTRA_LIBS@ 26 | 27 | INSTALL=install -o root 28 | MKDIR=mkdir -p -m 755 29 | 30 | LN=@LN_S@ 31 | 32 | MANSUF=1 33 | DESTDIR ?= 34 | 35 | PROGNAME=@PACKAGE_NAME@ 36 | 37 | SYSCONFDIR=@sysconfdir@/$(PROGNAME) 38 | SHAREDIR=@datadir@/$(PROGNAME) 39 | BINDIR=@bindir@ 40 | MAN1DIR=@mandir@/man1 41 | 42 | CFLAGS += $(CCWARNS) $(CCINCS) $(CCDEFS) $(CCOPTS) -DSYSCONFDIR=\"$(SYSCONFDIR)\" -DSHAREDIR=\"$(SHAREDIR)\" -DPROGNAME=\"$(PROGNAME)\" 43 | -------------------------------------------------------------------------------- /OS_STATUS: -------------------------------------------------------------------------------- 1 | Linux/Slackware 10.2/ia32 X 2 | Linux/Slackware 10.2/x86_64 X 3 | FreeBSD 6.0-RELEASE/ia32 X (Slow in sync mode) 4 | NetBSD 2.1 (GENERIC)/ia32 X 5 | OSX/Darwin 7.9.0/ppc X 6 | 7 | 8 | X - Full Pass 9 | x - Build OK/Most checks passed 10 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Building/Configuring/Whatever: 2 | 3 | SEE OS_STATUS FOR INFORMATION ABOUT YOUR SPECIFIC SYSTEM AND THIS SOFTWARE 4 | 5 | a) get and install c-ares ( http://daniel.haxx.se/projects/c-ares/ ) if at all possible 6 | b) run ./configure --with-your-arguments 7 | 1) you may need to run configure like: 8 | LDFLAGS="-L/usr/local/lib" CFLAGS="-I/usr/local/include" ./configure 9 | if you are running certain os'es that dont search /usr/local by default and have 10 | installed c-ares into /usr/local 11 | c) type make 12 | d) type make install 13 | e) goto http://www.dyadsecurity.com/s_softwarefeedback.html and please fill it in so we 14 | can make better software in the future. 15 | 16 | DESTDIR is supported for making packages, make uninstall also works to remove the software 17 | from your system. please note that the default config file is preserved, so if you make install 18 | twice, you will not overwrite your already present configuration file, if you uninstall this 19 | software you will need to manually remove the configuration file(s) (sysconfdir)/(progname)/(progname).conf.new 20 | 21 | basic usage: 22 | 23 | ### wordlist based A (forward) record brute force: 24 | 25 | namedrop -ve domain.tld 26 | 27 | ### wordlist (possibly $PREFIX/share/namedrop/oz or $PREFIX/share/namedrop/os.gz) based A record brute force: 28 | namedrop -ve -f oz domain.tld 29 | 30 | ### wordlist specifically with /usr/share/dict/words based A record brute force: 31 | namedrop -ve -f /usr/share/dict/words domain.tld 32 | 33 | ### to enable SQL output (for the same as above): 34 | (the schema you want is located inside sql/ ) 35 | 36 | namedrop -ves domain.tld 37 | 38 | the direction flag in the SQL output means: 39 | 0: Reverse Lookup 40 | 1: Forward Lookup 41 | 42 | ### to Brute force hostnames from 2 to 4 characters: (db.domain.tld -> www2.domain.tld) 43 | 44 | namedrop -ve -b2-4 domain.tld 45 | 46 | ### reverse dns based sweep of a cidr range: 47 | 48 | namedrop -v -r www.google.com/24 49 | 50 | ### reverse dns scanning a ipv6 range: 51 | 52 | namedrop -v -6r 6bone.net/114 53 | 54 | see man page for further usage 55 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | finish discovery mode 2 | -------------------------------------------------------------------------------- /YOU_REALLY_WANT_TO_INSTALL_THIS_LIBRARY: -------------------------------------------------------------------------------- 1 | libs/c-ares -------------------------------------------------------------------------------- /attic/adns_gnuanl.c: -------------------------------------------------------------------------------- 1 | #ifdef ASYNC 2 | 3 | #define _GNU_SOURCE 4 | 5 | #include "settings.h" 6 | 7 | #include 8 | 9 | #include "adns.h" 10 | 11 | static sig_atomic_t dns_present=0; 12 | 13 | #define ADNS_SLOTS_COUNT 16U 14 | #define ADNS_SIGNAL (SIGRTMIN + 3) 15 | #define ADNS_FINISHED 2 16 | 17 | static void addr_avail(int sig, siginfo_t *si, void *ptr) { 18 | 19 | ++dns_present; 20 | 21 | return; 22 | } 23 | 24 | int adns_gather(void (*)(const char *, const char *)); 25 | 26 | struct dnsq { 27 | struct sigevent se; 28 | struct gaicb *slots[ADNS_SLOTS_COUNT]; 29 | struct gaicb *free_slots[ADNS_SLOTS_COUNT]; 30 | unsigned int slots_free; 31 | unsigned int slots_cnt; 32 | struct sigaction sa; 33 | struct sigaction sa_old; 34 | unsigned int requested; 35 | unsigned int resolved; 36 | pthread_mutex_t slot_lock; 37 | } dnsq; 38 | 39 | void adns_init(void) { 40 | unsigned int j=0; 41 | pthread_mutexattr_t ma; 42 | 43 | dnsq.slots_cnt=ADNS_SLOTS_COUNT; 44 | dnsq.slots_free=ADNS_SLOTS_COUNT; 45 | 46 | for (j=0; j < ADNS_SLOTS_COUNT; j++) { 47 | dnsq.slots[j]=(struct gaicb *)malloc(sizeof(struct gaicb)); 48 | dnsq.free_slots[j]=dnsq.slots[j]; 49 | memset(dnsq.slots[j], 0, sizeof(struct gaicb)); 50 | } 51 | 52 | dnsq.sa.sa_sigaction=addr_avail; 53 | dnsq.sa.sa_flags=0; 54 | sigemptyset(&dnsq.sa.sa_mask); 55 | 56 | if (sigaction(ADNS_SIGNAL, &dnsq.sa, &dnsq.sa_old) < 0) { 57 | fprintf(stderr, "sigaction fails: %s", strerror(errno)); 58 | return; 59 | } 60 | 61 | dnsq.se.sigev_notify=SIGEV_SIGNAL; 62 | dnsq.se.sigev_signo=ADNS_SIGNAL; 63 | 64 | dnsq.requested=0; 65 | dnsq.resolved=0; 66 | 67 | if (pthread_mutexattr_init(&ma) < 0) { 68 | fprintf(stderr, "cant initialize mutex attribute: %s\n", strerror(errno)); 69 | return; 70 | } 71 | 72 | if (pthread_mutex_init(&dnsq.slot_lock, &ma) < 0) { 73 | fprintf(stderr, "cant init mutex lock: %s\n", strerror(errno)); 74 | return; 75 | } 76 | 77 | return; 78 | } 79 | 80 | void adns_fini(void) { 81 | unsigned int j=0; 82 | 83 | for (j=0; j < dnsq.slots_cnt; j++) { 84 | if (dnsq.slots[j] != NULL) { 85 | free(dnsq.slots[j]); 86 | if (dnsq.slots[j]->ar_result != NULL) { 87 | freeaddrinfo(dnsq.slots[j]->ar_result); 88 | if (dnsq.slots[j]->ar_name != NULL) { 89 | //free(dnsq.slots[j]->ar_name); 90 | dnsq.slots[j]->ar_name=NULL; 91 | } 92 | } 93 | } 94 | } 95 | 96 | sigaction(ADNS_SIGNAL, &dnsq.sa_old, NULL); 97 | 98 | return; 99 | } 100 | 101 | void adns_dump(void) { 102 | unsigned int j=0; 103 | 104 | assert(pthread_mutex_lock(&dnsq.slot_lock) == 0); 105 | 106 | for (j=0; j < dnsq.slots_cnt; j++) { 107 | printf("Slot %u at %p: ", j, dnsq.slots[j]); 108 | if (dnsq.slots[j] != NULL && dnsq.slots[j]->ar_name != NULL) { 109 | printf("waiting still for `%s'\n", dnsq.slots[j]->ar_name); 110 | } 111 | else { 112 | printf("\n"); 113 | } 114 | } 115 | 116 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 117 | 118 | } 119 | 120 | int adns_lookup(const char *name) { 121 | unsigned int idx=0; 122 | 123 | assert(pthread_mutex_lock(&dnsq.slot_lock) == 0); 124 | 125 | if (dnsq.slots_free > 0) { 126 | 127 | assert(dnsq.slots_free <= dnsq.slots_cnt); 128 | 129 | idx=dnsq.slots_cnt - dnsq.slots_free; 130 | 131 | dnsq.free_slots[idx]->ar_name=strdup(name); 132 | assert(dnsq.free_slots[idx]->ar_name != NULL); 133 | 134 | dnsq.free_slots[idx]->ar_service=NULL; 135 | dnsq.free_slots[idx]->ar_request=NULL; 136 | //fprintf(stderr, "using slot at %p\n", dnsq.free_slots[idx]); 137 | 138 | if (getaddrinfo_a(GAI_NOWAIT, &dnsq.free_slots[idx], 1, &dnsq.se) < 0) { 139 | //free(dnsq.free_slots[idx]->ar_name); 140 | dnsq.free_slots[idx]->ar_name=NULL; 141 | 142 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 143 | 144 | perror("getaddrinfo_a"); 145 | DBG("returning -1 cause stuff is broken"); 146 | return -1; 147 | } 148 | else { 149 | dnsq.requested++; 150 | --dnsq.slots_free; 151 | 152 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 153 | 154 | //printf("Looking up `%s'\n", name); 155 | DBG("returning 1 cause filled slot"); 156 | return 1; 157 | } 158 | } 159 | 160 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 161 | 162 | DBG("returning 0 cause no slots"); 163 | return 0; 164 | } 165 | 166 | int adns_gather(void (*fp)(const char *, const char *)) { 167 | unsigned int j=0, null=0; 168 | int ret=0; 169 | 170 | assert(pthread_mutex_lock(&dnsq.slot_lock) == 0); 171 | 172 | if (dnsq.resolved == dnsq.requested) { 173 | 174 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 175 | 176 | return 2; 177 | } 178 | 179 | for (j=0; dns_present > 0 && j < dnsq.slots_cnt; j++) { 180 | 181 | if (dnsq.slots[j] != NULL && dnsq.slots[j]->ar_name != NULL) { 182 | struct addrinfo *walk=NULL; 183 | char *nret=0; 184 | int r=0, good=0; 185 | char addr_str[1024]; 186 | union { 187 | void *p; 188 | struct sockaddr_in *in; 189 | struct sockaddr_in6 *in6; 190 | struct sockaddr *s; 191 | } s_u; 192 | 193 | r=gai_error(dnsq.slots[j]); 194 | 195 | //printf("Slot %u at %p for name `%s': ", j, dnsq.slots[j], dnsq.slots[j]->ar_name != NULL ? dnsq.slots[j]->ar_name : "None"); 196 | 197 | switch (r) { 198 | case EAI_INPROGRESS: 199 | //printf("in progress!\n"); 200 | break; 201 | case 0: 202 | good=1; 203 | break; 204 | case -2: 205 | good=-1; 206 | break; 207 | default: 208 | printf("Unknown status %d `%s'\n", r, gai_strerror(r)); 209 | break; 210 | } 211 | 212 | if (good == 0) { 213 | continue; 214 | } 215 | 216 | assert(dnsq.slots_free < ADNS_SLOTS_COUNT); 217 | 218 | dnsq.free_slots[dnsq.slots_free]=dnsq.slots[j]; 219 | if ((dnsq.slots_free + 1) < dnsq.slots_cnt) { 220 | dnsq.slots_free++; 221 | } 222 | ret++; 223 | 224 | for (walk=dnsq.slots[j]->ar_result; good == 1 && walk != NULL ; walk=walk->ai_next) { 225 | 226 | memset(addr_str, 0, sizeof(addr_str)); 227 | 228 | if (walk->ai_socktype != 3) { /* XXX what does 3 mean? */ 229 | continue; 230 | } 231 | 232 | s_u.p=walk->ai_addr; 233 | nret=NULL; 234 | nret=sockaddr_tostring(s_u.p); 235 | 236 | if (nret == NULL) { 237 | fprintf(stderr, "cant convert address family %d into string\n", walk->ai_family); 238 | } 239 | else { 240 | fp(dnsq.slots[j]->ar_name, nret); 241 | } 242 | } 243 | 244 | freeaddrinfo(dnsq.slots[j]->ar_result); 245 | dnsq.slots[j]->ar_result=NULL; 246 | 247 | if (dnsq.slots[j]->ar_name != NULL) { 248 | //free(dnsq.slots[j]->ar_name); 249 | dnsq.slots[j]->ar_name=NULL; 250 | } 251 | dns_present--; 252 | dnsq.resolved++; 253 | } 254 | else { 255 | //printf("Slot %u is %p with name %s\n", j, dnsq.slots[j], dnsq.slots[j] != NULL && dnsq.slots[j]->ar_name != NULL ? dnsq.slots[j]->ar_name : "Nothing"); 256 | null++; 257 | } 258 | } 259 | 260 | if (null == dnsq.slots_cnt) { 261 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 262 | return 2; 263 | } 264 | 265 | assert(pthread_mutex_unlock(&dnsq.slot_lock) == 0); 266 | 267 | return ret > 0 ? 1 : 0; 268 | } 269 | 270 | #ifdef _WRAP_ 271 | 272 | static void display(const char *name, const char *addr_str) { 273 | if (name != NULL && addr_str != NULL) { 274 | printf("%s has address %s\n", name, addr_str); 275 | } 276 | } 277 | 278 | int main(int argc, char **argv) { 279 | //struct sockaddr_in *sin=NULL; 280 | int j=0; 281 | 282 | adns_init(); 283 | 284 | j=1; 285 | 286 | for (;;) { 287 | for (; j < argc; j++) { 288 | if (adns_lookup(argv[j]) < 1) { 289 | break; 290 | } 291 | } 292 | if (adns_gather(display) == ADNS_FINISHED) { 293 | break; 294 | } 295 | } 296 | 297 | adns_dump(); 298 | 299 | //adns_fini(); 300 | 301 | exit(0); 302 | } 303 | 304 | #endif 305 | 306 | #endif 307 | -------------------------------------------------------------------------------- /attic/adns_gnuanl.h: -------------------------------------------------------------------------------- 1 | #ifndef _LIBC_ADNS_H 2 | # define _LIBC_ADNS_H 3 | 4 | void adns_init(void); 5 | void adns_fini(void); 6 | int adns_lookup(const char *); 7 | int adns_gather(void (* /* function will get name and address */)(const char *, const char *)); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /attic/gnu_adns: -------------------------------------------------------------------------------- 1 | http://www.chiark.greenend.org.uk/~ian/adns/ 2 | -------------------------------------------------------------------------------- /attic/gnu_adns.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include 4 | 5 | #define SLOT_CNT 8U 6 | 7 | struct { 8 | adns_state s; 9 | struct adns_slots { 10 | adns_query q; 11 | adns_answer *a; 12 | } slots[SLOT_CNT]; 13 | struct adns_slots *free_slots[SLOT_CNT]; 14 | unsigned int free; 15 | unsigned int resolved; 16 | unsigned int asked; 17 | } dnsq; 18 | 19 | void myadns_init(void) { 20 | int flags=0, ret=0; 21 | unsigned int j=0; 22 | 23 | if (s->verbose > 4) { 24 | flags |= adns_if_debug|adns_if_checkc_entex; 25 | } 26 | 27 | memset(&dnsq, 0, sizeof(dnsq)); 28 | 29 | ret=adns_init(&dnsq.s, flags, 0); 30 | if (ret) { 31 | fprintf(stderr, "adns_init fails: %s", strerror(ret)); 32 | return; 33 | } 34 | 35 | for (j=0; j < SLOT_CNT; j++) { 36 | dnsq.free_slots[j]=&dnsq.slots[j]; 37 | } 38 | 39 | return; 40 | } 41 | 42 | void myadns_fini(void) { 43 | 44 | adns_finish(dnsq.s); 45 | 46 | return; 47 | } 48 | 49 | int myadns_fwdlookup(const char *host) { 50 | unsigned int idx=0; 51 | 52 | if (dnsq.free < 1) { 53 | DBG("returning 0 cause no free slots"); 54 | return 0; 55 | } 56 | 57 | assert(dnsq.free <= SLOT_CNT); 58 | idx=SLOT_CNT - dnsq.free; 59 | dnsq.free_slots[idx]-> 60 | 61 | return -1; 62 | } 63 | 64 | int myadns_revlookup(struct sockaddr *sock) { 65 | return -1; 66 | } 67 | 68 | int myadns_gather(void (*fp)(const char *, const char *)) { 69 | return -1; 70 | } 71 | -------------------------------------------------------------------------------- /attic/gnu_adns.h: -------------------------------------------------------------------------------- 1 | #ifndef _MYADNS_H 2 | # define _MYADNS_H 3 | 4 | void myadns_init(void); 5 | void myadns_fini(void); 6 | int myadns_fwdlookup(const char *); 7 | int myadns_revlookup(struct sockaddr *); 8 | int myadns_gather(void (*)(const char *, const char *)); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | #ifndef _CONFIG_H 2 | # define _CONFIG_H 3 | 4 | #define DEF_BRUTECHARS "abcdefghijklmnopqrstuvwxyz0123456789-" 5 | #define LEGAL_LEN 37 6 | #define MAX_BRUTELEN 16 7 | #define SQL_COMMENT "--" 8 | #define DEF_CONFFILE SYSCONFDIR "/" PROGNAME ".conf" 9 | 10 | #define PACKAGE_VERSION @PACKAGE_VERSION@ 11 | 12 | #define MAX_SHN_LEN 24 13 | #define MIN_SHN_LEN 16 14 | 15 | #define XDEBUG_SIGNAL SIGUSR2 16 | 17 | #define NBUF_LEN 4096 18 | 19 | #define MYADNS_TIMEOUT 8 /* seconds */ 20 | 21 | #define DEF_CONCURRENCY 16 22 | 23 | #define ASYNC_SLEEPTIME 10000 24 | 25 | #define MAX_TARGETS 256 26 | 27 | #define IPV6 1 28 | 29 | /* autoconf cruft follows */ 30 | 31 | #undef HAVE_ARPA_INET_H 32 | #undef HAVE_GETHOSTBYNAME 33 | #undef HAVE_GETHOSTBYNAME2 34 | #undef HAVE_INTTYPES_H 35 | #undef HAVE_LIMITS_H 36 | #undef HAVE_MALLOC 37 | #undef HAVE_MEMORY_H 38 | #undef HAVE_MEMSET 39 | #undef HAVE_NETDB_H 40 | #undef HAVE_NETINET_IN_H 41 | #undef HAVE_REALLOC 42 | #undef HAVE_SELECT 43 | #undef HAVE_STDINT_H 44 | #undef HAVE_STDLIB_H 45 | #undef HAVE_STRCASECMP 46 | #undef HAVE_STRDUP 47 | #undef HAVE_STRERROR 48 | #undef HAVE_STRINGS_H 49 | #undef HAVE_STRING_H 50 | #undef HAVE_SYS_SELECT_H 51 | #undef HAVE_SYS_SOCKET_H 52 | #undef HAVE_SYS_STAT_H 53 | #undef HAVE_SYS_TYPES_H 54 | #undef HAVE_UNISTD_H 55 | #undef STDC_HEADERS 56 | #undef TIME_WITH_SYS_TIME 57 | #undef HAVE_STRUCT_SOCKADDR_LEN 58 | #undef BIGENDIAN 59 | 60 | #include 61 | #ifdef HAVE_STDLIB_H 62 | # include 63 | #endif 64 | #if defined(HAVE_INTTYPES_H) 65 | # include 66 | #elif defined(HAVE_STDINT_H) 67 | # include 68 | #else 69 | /* this is the part where i make things up */ 70 | #define uint8_t unsigned char 71 | #define int8_t signed char 72 | #define uint16_t unsigned short int 73 | #define int16_t signed short int 74 | #define uint32_t unsigned int 75 | #define int32_t signed int 76 | #define uint64_t unsigned long long int 77 | #define int64_t signed long long int 78 | #endif /* std ints */ 79 | #ifdef HAVE_UNISTD_H 80 | # include 81 | #endif 82 | #ifdef HAVE_STRING_H 83 | # include 84 | #endif 85 | #ifdef HAVE_STRINGS_H 86 | # include 87 | #endif 88 | #include 89 | #include 90 | #include 91 | #include 92 | #include 93 | #ifdef HAVE_ARPA_INET_H 94 | # include 95 | #endif 96 | #include 97 | #include 98 | #include 99 | #ifdef HAVE_LIMITS_H 100 | # include 101 | #endif 102 | #include 103 | #ifdef TIME_WITH_SYS_TIME 104 | # include 105 | # include 106 | #else 107 | # include 108 | #endif 109 | 110 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 111 | struct f_s { 112 | uint8_t len; 113 | uint8_t family; 114 | }; 115 | #else 116 | struct f_s { 117 | uint16_t family; 118 | }; 119 | #endif 120 | 121 | #endif /* CONFIG_H */ 122 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ(2.57) 5 | 6 | AC_INIT([namedrop], [0.2.3], [osace-users@lists.sourceforge.net]) 7 | AC_CONFIG_SRCDIR([readconf.h]) 8 | AC_CONFIG_HEADERS([config.h:config.h.in]) 9 | 10 | # Checks for programs. 11 | AC_PROG_CC 12 | AC_PROG_LN_S 13 | 14 | # Checks for libraries. 15 | AC_CHECK_LIB([cares], [ares_init], 16 | [export HAVE_C_ARES=1;export EXTRA_SRCS=myadns.c;export EXTRA_LIBS=-lcares], [export HAVE_C_ARES=0;export EXTRA_SRCS=;export EXTRA_LIBS=]) 17 | 18 | # Checks for header files. 19 | AC_HEADER_STDC 20 | AC_CHECK_HEADERS([arpa/inet.h limits.h netdb.h netinet/in.h stdint.h stdlib.h string.h sys/socket.h sys/time.h unistd.h]) 21 | 22 | # Checks for typedefs, structures, and compiler characteristics. 23 | AC_C_CONST 24 | AC_C_INLINE 25 | AC_TYPE_SIZE_T 26 | AC_HEADER_TIME 27 | 28 | # Checks for library functions. 29 | AC_FUNC_MALLOC 30 | AC_FUNC_MEMCMP 31 | AC_FUNC_REALLOC 32 | AC_FUNC_SELECT_ARGTYPES 33 | AC_CHECK_FUNCS([memset select strcasecmp strdup strrchr strerror getnameinfo getaddrinfo]) 34 | 35 | AC_C_BIGENDIAN([export BIGENDIAN=1], [export BIGENDIAN=0], [AC_MSG_ERROR(unable to determine endianness of this machine, hopefully you arent using a pdp-11, if you are i spit in your general direction, otherwise sorry.)]) 36 | 37 | AC_CHECK_MEMBER([struct sockaddr.sa_len], [AC_DEFINE(HAVE_STRUCT_SOCKADDR_LEN)], [], [#include 38 | #include ]) 39 | 40 | AC_SUBST(HAVE_C_ARES) 41 | AC_SUBST(EXTRA_SRCS) 42 | AC_SUBST(EXTRA_LIBS) 43 | AC_SUBST(BIGENDIAN) 44 | 45 | AC_PATH_PROGS(USE_MAKE, gmake gnumake make) 46 | 47 | AC_CONFIG_FILES([Makefile.inc 48 | Makefile]) 49 | AC_OUTPUT 50 | 51 | if test $HAVE_C_ARES -eq 0; then 52 | echo Warning, no c-ares library detected, try downloading it and re-running configure, or see README if you belive this is an error 53 | fi 54 | -------------------------------------------------------------------------------- /default.conf.in: -------------------------------------------------------------------------------- 1 | # configuration file for @PROGNAME@, (@SYSCONFDIR@/@PROGNAME@.conf) 2 | # default values are in the commented out example setting. command line options 3 | # will override the values in this file. 4 | 5 | # 6 | # There are 3 modes of operation, dict (dictionary host guessing), brute force mode, and reverse mode. 7 | # 8 | #mode: dict 9 | 10 | # 11 | # By default, ipv4 and ipv6 look ups are attempted, if you know there are no ipv6 records, or don't care, 12 | # uncomment this following like, possible values are ipv4, ipv6 (only ipv6) and ipv46 for both 13 | # 14 | #addrfam: ipv46 15 | 16 | # during brute force mode, allowed determines what characters are used during hostname creation, and also 17 | # the wildcard host name (the sillyhostname) { if not specified } is created randomly from this character 18 | # list as well. 19 | # 20 | #allowed: abcdefghijklmnopqrstuvwxyz0123456789-._ 21 | 22 | # 23 | # async (if supported during compile time) has 2 types of settings, no for forcing sync dns look ups 24 | # or a number controlling how many dns look ups are queued at any given time, too large a value may 25 | # cause the scanner to malfunction, ymmv 26 | # 27 | #async: 16 28 | 29 | # 30 | # dictfile is the dictionary (a file containing words on separate lines) that will be asked for, 31 | # the default is @SHAREDIR@/default, generally a symlink to another file. you may 32 | # specify a fully qualified path or simply a file name, and the following search will be used 33 | # 1) look for a file called `foo' 34 | # 2) look for a compressed (gzip) file called `foo.gz' 35 | # 3) look in @SHAREDIR@ for a file called `foo' 36 | # 4) look in @SHAREDIR@ for a file called `foo.gz' 37 | # 38 | #dictfile: default 39 | 40 | # 41 | # sillyhostname (if specified) will be the hostname that we look for to determine if the dns server 42 | # will send back a reply for anything we ask for, if found the address records for this `wildcard' 43 | # will be ignored, IE; if we ask for ldfkgjfkdfjgkldfg.foo.bar and later we ask for mail.foo.bar 44 | # and they have the same address, then we will assume that the host mail.foo.bar does not exist 45 | # if not specified, the sillyhostname will be randomly created from the `allowed' characters 46 | # 47 | # NOTE: there is no default sillyhostname, it is randomly generated, if you specify it, it will no 48 | # longer be random. 49 | # 50 | #sillyhostname: foobar393849384_sdfkjdsf 51 | 52 | # 53 | # verbose is a numeric argument containing the level of verbosity that you want to see from the scan, 54 | # if it is set high, a lot of output will be available, sometimes useful for troubleshooting (if you 55 | # find a bug, try setting this high, and see if it clears up the reason) 56 | # 57 | #verbose: 0 58 | 59 | # 60 | # exact means that you want to know exactly what names matched the query, IE; if you got an answer 61 | # back for www.foo.bar, and the record indicates that it is an alias for web.foo.bar, then exact mode 62 | # will say that www.foo.bar is a CNAME and that there is an A record for web.foo.bar. otherwise 63 | # it would have just told you that www.foo.bar had address x.x.x.x 64 | # 65 | #exact: 1 66 | 67 | # 68 | # discover mode means that when a record is found, then more information will be attempted from this 69 | # information. for example if we find printer.foo.bar then in discover mode, we will ask about the HINFO 70 | # record for printer.foo.bar 71 | # 72 | #discover: 1 73 | 74 | # 75 | # filter is a numeric argument that specifies if duplicate record detection is used, IE if we get back 76 | # 2 records for www.foo.bar with the same address, then if filtered we will only display one. 77 | # 78 | #filter: 1 79 | -------------------------------------------------------------------------------- /dnspkt.h: -------------------------------------------------------------------------------- 1 | #ifndef _DNSPKT_H 2 | # define _DNSPKT_H 3 | 4 | typedef struct dnshdr_t { 5 | uint32_t notused; /* 0 - 3 */ 6 | uint16_t questions; /* 4 - 5 */ 7 | uint16_t answers; /* 6 - 7 */ 8 | uint16_t nss; /* 8 - 9 */ 9 | uint16_t others; /* 10 - 11 */ 10 | } dnshdr_t; 11 | 12 | /* 13 | * follows name 14 | */ 15 | typedef struct dnsq_t { 16 | uint16_t type; 17 | uint16_t qclass; 18 | } dnsq_t; 19 | 20 | /* 21 | * follows name 22 | */ 23 | typedef struct dnsrr_t { 24 | uint16_t type; 25 | uint16_t qclass; 26 | uint32_t ttl; 27 | uint16_t len; 28 | } dnsrr_t; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | 2 | all: man.1 3 | 4 | man.1: man.tex 5 | latex2man man.tex man.1 6 | 7 | clean: 8 | distclean: 9 | -------------------------------------------------------------------------------- /docs/man.1: -------------------------------------------------------------------------------- 1 | '\" t 2 | .\" Manual page created with latex2man on Tue Dec 20 21:43:20 PST 2005 3 | .\" NOTE: This file is generated, DO NOT EDIT. 4 | .de Vb 5 | .ft CW 6 | .nf 7 | .. 8 | .de Ve 9 | .ft R 10 | 11 | .fi 12 | .. 13 | .TH "NAMEDROP" "1" "12/20/05" "Network Tools " "Network Tools " 14 | .SH NAME 15 | 16 | .PP 17 | namedrop 18 | Version 0.2.3 is a (possibly, if compiled with c\-ares) asynchronous DNS information enumeration 19 | tool. 20 | .PP 21 | .SH SYNOPSIS 22 | 23 | .PP 24 | namedrop 25 | [\fB\-4\fP] 26 | [\fB\-6\fP] 27 | [\fB\-a\fP\fI number\fP] 28 | [\fB\-b\fP\fI number\-number\fP] 29 | [\fB\-c\fP\fI characters\fP] 30 | [\fB\-d\fP] 31 | [\fB\-D\fP] 32 | [\fB\-e\fP] 33 | [\fB\-f\fP\fI filename\fP] 34 | [\fB\-F\fP] 35 | [\fB\-h\fP] 36 | [\fB\-H\fP\fI hostname\fP] 37 | [\fB\-r\fP] 38 | [\fB\-s\fP] 39 | [\fB\-S\fP] 40 | [\fB\-v\fP] 41 | [\fB\-V\fP] 42 | \fItarget list\fP 43 | .PP 44 | .SH DESCRIPTION 45 | 46 | .PP 47 | namedrop: 48 | There are three basic modes of operation, dictionary brute force mode, general brute force mode and 49 | reverse IP sweep mode. Dictionary brute force mode may use a (possibly compressed) file specified at the 50 | command line, containing a hostnames separated by newlines. 51 | .PP 52 | .SH OPTIONS 53 | 54 | .TP 55 | \fB\-4\fP 56 | Imply that all questions are for IPV4, possibly requiring half the amount of questions 57 | to be asked if IPV6 questions were also enabled. 58 | .TP 59 | \fB\-6\fP 60 | Does exactly the same thing as \fB\-4\fP 61 | but it enables IPV6 not IPV4. This option can 62 | also possibly serve to disambiguate the meaning of a hostname, that otherwise could return an IPV4 63 | and a IPV6 record, in such a case the best guess is generally to use the IPV4 address record. 64 | .TP 65 | \fB\-a\fP\fI number\fP 66 | Concurrency for asynchronous resolver (how many questions to leave pending in parallel). This option 67 | requires c\-ares support to be enabled. Some experimentation is generally required to get this value at 68 | a optimal setting, as it depends on the DNS cache(s) that are available. 69 | .TP 70 | \fB\-b\fP\fI number\-number\fP 71 | Brute force mode, with mandatory argument in the form of \fB\-b\fP\fI 3\fP 72 | or \fB\-b\fP\fI 3\-4\fP 73 | to brute force 74 | hostnames from 1 (implied) to 3 characters, and from 3 to 4 characters, respectively. 75 | .TP 76 | \fB\-c\fP\fI characters\fP 77 | If inside of brute force mode, a list of characters that will be used to create hostnames from, such as 78 | \fB\-c\fP\fI abcdefghjiklmnopqrstuvwxyz\-\fP\&. 79 | This option will also effect the random `wildcard\&' host 80 | (if not specifically specified otherwise with \fB\-H\fP) 81 | that is asked for to detect a default forward 82 | record. 83 | .TP 84 | \fB\-d\fP 85 | Not yet implemented. 86 | .TP 87 | \fB\-D\fP 88 | Dictionary Brute force Mode (default). 89 | .TP 90 | \fB\-e\fP 91 | Display an exact output of data as returned by name server (only generally useful in a forward lookup mode). 92 | If this option is selected CNAME records will be displayed so it is obvious what actual question generated 93 | the A record output. 94 | .TP 95 | \fB\-f\fP\fI filename\fP 96 | Filename that will be used inside of a Dictionary mode brute force, the search order used to locate the file 97 | is 1) locate a file in the current directory 2) append on \&.gz to the filename and locate it within the current 98 | directory 2) prepend SHAREDIR (possibly /usr/local/share/namedrop or /usr/share/namedrop) onto the filename 99 | 3) append \&.gz to SHAREDIR/filename. Stated simply \fB\-f\fP\fI foo\fP 100 | will become, \&./foo, \&./foo.gz, 101 | /usr/share/namedrop/foo, and finally /usr/share/namedrop/foo.gz. 102 | .TP 103 | \fB\-F\fP 104 | Do not attempt to remove duplicate output, possibly display the same results over and over. 105 | .TP 106 | \fB\-h\fP 107 | Display command line program help. 108 | .TP 109 | \fB\-H\fP\fI hostname\fP 110 | Explicit hostname to be used during wildcard hostname detection. 111 | .TP 112 | \fB\-r\fP 113 | Reverse DNS sweeping mode (gather hostnames from a cidr address range), use \fB\-4\fP 114 | or \fB\-6\fP 115 | to specify 116 | exactly what you want, otherwise the programs interpretation can be seemingly random. 117 | .TP 118 | \fB\-s\fP 119 | Output will be SQL, all data output will be in the form of SQL insert statements, and all non\-data output 120 | will be preceded with an SQL comment (\-\-) so that a pipe may be used to interface to a command line SQL 121 | monitor program like \fIpsql\fP(1)\&. 122 | .TP 123 | \fB\-S\fP 124 | Force synchronous DNS behavior, only useful if c\-ares support is compiled in, as asynchronous questions 125 | are default in that case. 126 | .TP 127 | \fB\-v\fP 128 | For each \fB\-v\fP 129 | increase verbosity of program, useful when trying to locate a problem. 130 | .TP 131 | \fB\-V\fP 132 | Display program version. 133 | .PP 134 | .SH EXAMPLES 135 | 136 | \fBnamedrop \-ve4 domain.tld \fP 137 | Dictionary Brute force the domain `domain.tld\&' for hostnames within asking for IPV4 records only. 138 | If CNAMES are discovered \fI\-e\fP 139 | then display them with the actual A record returned. Also 140 | display a small amount of information about things the program is doing. 141 | .PP 142 | .SH FILES 143 | 144 | .TP 145 | namedrop.conf 146 | The file containing the default configuration options for usage. 147 | .PP 148 | .SH SEE ALSO 149 | 150 | \fIhost\fP(1) 151 | \fIdig\fP(1) 152 | .PP 153 | .SH REPORTING BUGS 154 | 155 | Report Bugs to osace\-users@lists.sourceforge.net 156 | .PP 157 | .SH COPYRIGHT 158 | 159 | (C)2005 Jack Louis \fBjack@dyadsecurity.com\fP 160 | This is free software; see the source for copying conditions. There is NO warranty; not even for 161 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 162 | .PP 163 | .\" NOTE: This file is generated, DO NOT EDIT. 164 | -------------------------------------------------------------------------------- /docs/man.tex: -------------------------------------------------------------------------------- 1 | \documentclass[english]{article} 2 | 3 | \usepackage[latin1]{inputenc} 4 | \usepackage{latex2man} 5 | \usepackage{babel} 6 | \usepackage{verbatim} 7 | 8 | \setDate{12/20/05} 9 | \setVersion{0.2.3} 10 | 11 | \begin{document} 12 | 13 | % \begin{Name}{chapter}{name}{author}{info}{title} 14 | \begin{Name}{1}{namedrop}{Jack Louis}{Network Tools}{namedrop command documentation} 15 | %%%%%%%%%% 16 | 17 | \Prog{namedrop} Version \Version\ is a (possibly, if compiled with c-ares) asynchronous DNS information enumeration 18 | tool. 19 | 20 | \end{Name} 21 | 22 | \section{Synopsis} 23 | %%%%%%%%%% 24 | 25 | \Prog{namedrop} 26 | \oOpt{-4} 27 | \oOpt{-6} 28 | \oOptArg{-a}{ number} 29 | \oOptArg{-b}{ number-number} 30 | \oOptArg{-c}{ characters} 31 | \oOpt{-d} 32 | \oOpt{-D} 33 | \oOpt{-e} 34 | \oOptArg{-f}{ filename} 35 | \oOpt{-F} 36 | \oOpt{-h} 37 | \oOptArg{-H}{ hostname} 38 | \oOpt{-r} 39 | \oOpt{-s} 40 | \oOpt{-S} 41 | \oOpt{-v} 42 | \oOpt{-V} 43 | \Arg{ target list} 44 | 45 | \section{Description} 46 | %%%%%%%%%% 47 | 48 | \Prog{namedrop}: 49 | There are three basic modes of operation, dictionary brute force mode, general brute force mode and 50 | reverse IP sweep mode. Dictionary brute force mode may use a (possibly compressed) file specified at the 51 | command line, containing a hostnames separated by newlines. 52 | 53 | \section{Options} 54 | %%%%%%%%%% 55 | \begin{Description} 56 | \item[\Opt{-4}] 57 | Imply that all questions are for IPV4, possibly requiring half the amount of questions 58 | to be asked if IPV6 questions were also enabled. 59 | \item[\Opt{-6}] 60 | Does exactly the same thing as \Opt{-4} but it enables IPV6 not IPV4. This option can 61 | also possibly serve to disambiguate the meaning of a hostname, that otherwise could return an IPV4 62 | and a IPV6 record, in such a case the best guess is generally to use the IPV4 address record. 63 | \item[\OptArg{-a}{ number}] 64 | Concurrency for asynchronous resolver (how many questions to leave pending in parallel). This option 65 | requires c-ares support to be enabled. Some experimentation is generally required to get this value at 66 | a optimal setting, as it depends on the DNS cache(s) that are available. 67 | \item[\OptArg{-b}{ number-number}] 68 | Brute force mode, with mandatory argument in the form of \OptArg{-b}{ 3} or \OptArg{-b}{ 3-4} to brute force 69 | hostnames from 1 (implied) to 3 characters, and from 3 to 4 characters, respectively. 70 | \item[\OptArg{-c}{ characters}] 71 | If inside of brute force mode, a list of characters that will be used to create hostnames from, such as 72 | \OptArg{-c}{ abcdefghjiklmnopqrstuvwxyz-}. This option will also effect the random `wildcard' host 73 | (if not specifically specified otherwise with \Opt{-H}) that is asked for to detect a default forward 74 | record. 75 | \item[\Opt{-d}] 76 | Not yet implemented. 77 | \item[\Opt{-D}] 78 | Dictionary Brute force Mode (default). 79 | \item[\Opt{-e}] 80 | Display an exact output of data as returned by name server (only generally useful in a forward lookup mode). 81 | If this option is selected CNAME records will be displayed so it is obvious what actual question generated 82 | the A record output. 83 | \item[\OptArg{-f}{ filename}] 84 | Filename that will be used inside of a Dictionary mode brute force, the search order used to locate the file 85 | is 1) locate a file in the current directory 2) append on .gz to the filename and locate it within the current 86 | directory 2) prepend SHAREDIR (possibly /usr/local/share/namedrop or /usr/share/namedrop) onto the filename 87 | 3) append .gz to SHAREDIR/filename. Stated simply \OptArg{-f}{ foo} will become, ./foo, ./foo.gz, 88 | /usr/share/namedrop/foo, and finally /usr/share/namedrop/foo.gz. 89 | \item[\Opt{-F}] 90 | Do not attempt to remove duplicate output, possibly display the same results over and over. 91 | \item[\Opt{-h}] 92 | Display command line program help. 93 | \item[\OptArg{-H}{ hostname}] 94 | Explicit hostname to be used during wildcard hostname detection. 95 | \item[\Opt{-r}] 96 | Reverse DNS sweeping mode (gather hostnames from a cidr address range), use \Opt{-4} or \Opt{-6} to specify 97 | exactly what you want, otherwise the programs interpretation can be seemingly random. 98 | \item[\Opt{-s}] 99 | Output will be SQL, all data output will be in the form of SQL insert statements, and all non-data output 100 | will be preceded with an SQL comment (--) so that a pipe may be used to interface to a command line SQL 101 | monitor program like \Cmd{psql}{1}. 102 | \item[\Opt{-S}] 103 | Force synchronous DNS behavior, only useful if c-ares support is compiled in, as asynchronous questions 104 | are default in that case. 105 | \item[\Opt{-v}] 106 | For each \Opt{-v} increase verbosity of program, useful when trying to locate a problem. 107 | \item[\Opt{-V}] 108 | Display program version. 109 | \end{Description} 110 | 111 | \section{Examples} 112 | %%%%%%%%%% 113 | \begin{Description} 114 | \textbf{namedrop -ve4 domain.tld } 115 | Dictionary Brute force the domain `domain.tld' for hostnames within asking for IPV4 records only. 116 | If CNAMES are discovered \emph{-e} then display them with the actual A record returned. Also 117 | display a small amount of information about things the program is doing. 118 | \end{Description} 119 | 120 | \section{Files} 121 | %%%%%%%%%% 122 | \begin{Description} 123 | \item[\File{namedrop.conf}] The file containing the default configuration options for usage. 124 | \end{Description} 125 | 126 | \section{See Also} 127 | %%%%%%%%%% 128 | \Cmd{host}{1} \Cmd{dig}{1} 129 | 130 | \section{Reporting Bugs} 131 | %%%%%%%%%% 132 | \begin{description} 133 | Report Bugs to osace-users@lists.sourceforge.net 134 | \end{description} 135 | 136 | \section{Copyright} 137 | %%%%%%%%%% 138 | \begin{description} 139 | \copyright\ 2005 Jack Louis \Email{jack@dyadsecurity.com} 140 | This is free software; see the source for copying conditions. There is NO warranty; not even for 141 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 142 | \end{description} 143 | 144 | \LatexManEnd 145 | 146 | \end{document} 147 | -------------------------------------------------------------------------------- /docs/rfc1123.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/docs/rfc1123.txt.gz -------------------------------------------------------------------------------- /ext/_xdebug.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #include "settings.h" 20 | 21 | #include "ext/xmalloc.h" 22 | 23 | static char *my_strdup(const char *, const char *, unsigned int); 24 | static void xdebug_display_memory(FILE *, void *, size_t); 25 | static void xdebug_verify_guard(void *, size_t ); 26 | 27 | typedef struct memchunk_t { 28 | struct memchunk_t *next; 29 | void *p; 30 | size_t sz; 31 | char *file; 32 | unsigned int lineno; 33 | int realloced; 34 | } memchunk_t; 35 | 36 | memchunk_t *head=NULL; 37 | 38 | uint32_t guard=0x410043ef; 39 | 40 | static void xdebug_atexit(void) __attribute__((destructor)); 41 | static void xdebug_start(void) __attribute__((constructor)); 42 | static void xdebug_dumpleak(int /* not used */); 43 | 44 | static size_t track(void *, size_t, const char *, unsigned int, int); 45 | 46 | #define ACTION_MALLOCED 1 47 | #define ACTION_REALLOCED 2 48 | #define ACTION_FREED 3 49 | #define ACTION_GETSIZE 4 50 | 51 | static void xdebug_start(void) { 52 | struct sigaction sa; 53 | 54 | sa.sa_handler=xdebug_dumpleak; 55 | sa.sa_flags=0; 56 | sigemptyset(&sa.sa_mask); 57 | 58 | if (sigaction(XDEBUG_SIGNAL, &sa, NULL) < 0) { 59 | ERR("sigaction failts: %s", strerror(errno)); 60 | } 61 | 62 | srand(getpid()); 63 | 64 | /* 65 | * this guard stuff was never really intended for security, but what the heck, lets at least 66 | * add a bit of spice to the mix 67 | */ 68 | guard ^= (UINT_MAX & (unsigned int)rand()); 69 | 70 | /* fprintf(stderr, "signal %d to dump memory in real time", XDEBUG_SIGNAL); */ 71 | } 72 | 73 | static size_t track(void *pointer, size_t len, const char *file, unsigned int lineno, int action) { 74 | 75 | if (action == ACTION_MALLOCED) { 76 | memchunk_t *walk=NULL, *old=NULL; 77 | 78 | if (head == NULL) { 79 | head=(memchunk_t *)malloc(sizeof(memchunk_t)); 80 | assert(head != NULL); 81 | head->next=NULL; 82 | head->p=pointer; 83 | head->sz=len; 84 | if (file != NULL) { 85 | size_t sz=0; 86 | 87 | sz=strlen(file) + 1; 88 | head->file=malloc(sz); 89 | assert(head->file != NULL); 90 | memcpy(head->file, file, sz - 1); 91 | head->file[sz - 1]='\0'; 92 | } 93 | else { 94 | head->file=NULL; 95 | } 96 | head->lineno=lineno; 97 | head->realloced=0; 98 | 99 | return head->sz; 100 | } 101 | 102 | for (walk=head ; walk->next != NULL ; old=walk, walk=walk->next) { 103 | ; 104 | } 105 | 106 | walk->next=(memchunk_t *)malloc(sizeof(memchunk_t)); 107 | walk=walk->next; 108 | walk->next=NULL; 109 | walk->p=pointer; 110 | walk->sz=len; 111 | if (file != NULL) { 112 | size_t sz=0; 113 | 114 | sz=strlen(file) + 1; 115 | walk->file=malloc(sz); 116 | assert(walk->file != NULL); 117 | memcpy(walk->file, file, sz - 1); 118 | walk->file[sz - 1]='\0'; 119 | } 120 | else { 121 | walk->file=NULL; 122 | } 123 | walk->lineno=lineno; 124 | walk->realloced=0; 125 | 126 | return walk->sz; 127 | } 128 | else if (action == ACTION_FREED) { 129 | memchunk_t *old=NULL, *walk=NULL; 130 | int found=0; 131 | size_t ret=0; 132 | 133 | if (head == NULL) { 134 | PANIC("free non-existant pointer (head null)"); 135 | } 136 | for (walk=head ; walk != NULL ; old=walk, walk=walk->next) { 137 | if (walk->p == pointer) { 138 | found=1; 139 | ret=walk->sz; 140 | break; 141 | } 142 | } 143 | if (found == 0) { 144 | PANIC("delting non-existant pointer (not on list)"); 145 | } 146 | assert(walk != NULL); 147 | if (old == NULL) { 148 | assert(walk == head); 149 | if (head->next == NULL) { 150 | head=NULL; 151 | } 152 | else { 153 | head=head->next; 154 | } 155 | if (walk->file != NULL) { 156 | free(walk->file); 157 | walk->file=NULL; 158 | } 159 | free(walk); 160 | walk=NULL; 161 | } 162 | else { 163 | assert(old->next == walk); 164 | old->next=walk->next; 165 | if (walk->file != NULL) { 166 | free(walk->file); 167 | walk->file=NULL; 168 | } 169 | free(walk); 170 | walk=NULL; 171 | } 172 | 173 | return ret; 174 | } 175 | else if (action == ACTION_GETSIZE) { 176 | memchunk_t *walk=NULL; 177 | 178 | if (head == NULL) { 179 | PANIC("getsize for non-existant pointer (head null)"); 180 | } 181 | for (walk=head ; walk != NULL ; walk=walk->next) { 182 | if (walk->p == pointer) { 183 | return walk->sz; 184 | } 185 | } 186 | PANIC("getsize for non-existant pointer"); 187 | } 188 | else { 189 | PANIC("track unknown action"); 190 | } 191 | 192 | return 0; 193 | } 194 | 195 | void *_xmalloc(size_t n, const char *file, unsigned int lineno) { 196 | union { 197 | uint32_t *g; 198 | char *w; 199 | void *p; 200 | } g_u; 201 | char *e=NULL; 202 | 203 | #ifdef STRICT 204 | if (n < 1) { 205 | PANIC("attempt to allocate 0 or less bytes of memory"); 206 | } 207 | #endif 208 | 209 | g_u.p=malloc(n + (sizeof(uint32_t) * 2)); 210 | if (g_u.p == NULL) { 211 | PANIC("malloc failed"); 212 | } 213 | 214 | memset(g_u.p, 0x41, n); 215 | *g_u.g=guard; 216 | e=(char *)g_u.p; 217 | e += (sizeof(uint32_t) + n); 218 | *(uint32_t *)e=guard; 219 | 220 | track(g_u.p, n, file, lineno, ACTION_MALLOCED); 221 | g_u.g++; 222 | return g_u.p; 223 | } 224 | 225 | void *_xcalloc(size_t n, size_t l, const char *file, unsigned int lineno) { 226 | void *p=NULL; 227 | size_t asz=0; 228 | 229 | asz=n * l; 230 | 231 | #ifdef STRICT 232 | assert(asz > n && asz > l); 233 | #endif 234 | 235 | p=_xmalloc(asz, file, lineno); 236 | 237 | memset(p, 0, asz); 238 | 239 | return p; 240 | } 241 | 242 | void *_xrealloc(void *obuf, size_t n, const char *file, unsigned int lineno) { 243 | union { 244 | uint32_t *g; 245 | void *p; 246 | } g_u, ng_u; 247 | size_t sz=0; 248 | 249 | if (obuf == NULL) { 250 | #ifndef STRICT 251 | return _xmalloc(n, file, lineno); 252 | #else 253 | PANIC("attempt to realloc a null pointer"); 254 | #endif 255 | } 256 | 257 | #ifdef STRICT 258 | if (n < 1) { 259 | PANIC("attempt to increase allocation by 0 bytes"); 260 | } 261 | #endif 262 | 263 | #ifndef STRICT 264 | if (n == 0) { 265 | __xfree(obuf, file, lineno); 266 | return NULL; 267 | } 268 | #endif 269 | 270 | g_u.p=obuf; 271 | g_u.g--; 272 | if (*g_u.g != guard) { 273 | PANIC("guard %08x != %08x, heap corruption", *g_u.g, guard); 274 | } 275 | sz=track(g_u.p, 0, file, lineno, ACTION_GETSIZE); 276 | g_u.g++; 277 | 278 | #ifdef STRICT 279 | assert(n > sz); 280 | #endif 281 | 282 | ng_u.p=_xmalloc(n, file, lineno); 283 | 284 | memcpy(ng_u.p, g_u.p, sz); 285 | 286 | __xfree(g_u.p, file, lineno); 287 | 288 | return ng_u.p; 289 | } 290 | 291 | void __xfree(void *p, const char *file, unsigned int lineno) { 292 | union { 293 | uint32_t *g; 294 | void *p; 295 | char *c; 296 | } g_u; 297 | char *e=NULL; 298 | size_t sz=0; 299 | 300 | #ifdef STRICT 301 | if (p == NULL) { 302 | PANIC("attempt to free a NULL pointer"); 303 | } 304 | #else 305 | if (p == NULL) { 306 | return; 307 | } 308 | #endif 309 | g_u.p=p; 310 | g_u.g--; 311 | if (*g_u.g != guard) { 312 | PANIC("guard %08x != %08x, heap corruption", *g_u.g, guard); 313 | } 314 | e=g_u.p; 315 | 316 | sz=track(g_u.p, 0, file, lineno, ACTION_FREED); 317 | 318 | e += (sz + sizeof(uint32_t)); 319 | if (*(uint32_t *)e != guard) { 320 | PANIC("guard %08x != %08x, heap corruption", *(uint32_t *)e, guard); 321 | } 322 | 323 | memset(g_u.p, 0x42, sz + (sizeof(uint32_t) * 2)); 324 | 325 | free(g_u.p); 326 | g_u.p=NULL; 327 | 328 | return; 329 | } 330 | 331 | char *_xstrdup(const char *p, const char *file, unsigned int lineno) { 332 | char *_p=NULL; 333 | 334 | #ifdef STRICT 335 | if (p == NULL || strlen(p) < 1) { 336 | PANIC("Attempt to dup a %s string", p == NULL ? "null" : "blank"); 337 | } 338 | #endif 339 | 340 | _p=my_strdup(p, file, lineno); 341 | if (_p == NULL) { 342 | PANIC("strdup failed"); 343 | } 344 | 345 | return _p; 346 | } 347 | 348 | static char *my_strdup(const char *in, const char *file, unsigned int lineno) { 349 | size_t asz=0; 350 | char *ret=NULL; 351 | 352 | asz=strlen(in) + 1; 353 | ret=_xmalloc(asz, file, lineno); 354 | memcpy(ret, in, asz - 1); 355 | ret[asz - 1]='\0'; 356 | 357 | return ret; 358 | } 359 | 360 | static void xdebug_dumpleak(int unused) { 361 | memchunk_t *walk=NULL, *old=NULL; 362 | char *fname=NULL; 363 | FILE *out=NULL; 364 | 365 | if ((fname=getenv("XDEBUG_OUTFILE")) != NULL) { 366 | out=fopen(fname, "w+"); 367 | if (out == NULL) { 368 | ERR("fopen `%s' fails, using stderr: %s", fname, strerror(errno)); 369 | out=stderr; 370 | } 371 | } 372 | else { 373 | out=stderr; 374 | } 375 | 376 | for (walk=head ; walk != NULL ; old=walk, walk=walk->next) { 377 | xdebug_verify_guard(walk->p, walk->sz); 378 | 379 | fprintf(out, "leak %p size %zu%s from %s:%u\n", walk->p, walk->sz, walk->realloced == 0 ? "" : " Reallocated", walk->file, walk->lineno); 380 | if (getenv("XDEBUG_LEAKDUMP") != NULL) { 381 | xdebug_display_memory(out, walk->p, walk->sz); 382 | } 383 | } 384 | 385 | return; 386 | } 387 | 388 | static void xdebug_atexit(void) { 389 | memchunk_t *walk=NULL, *old=NULL; 390 | char *fname=NULL; 391 | FILE *out=NULL; 392 | 393 | if ((fname=getenv("XDEBUG_OUTFILE")) != NULL) { 394 | out=fopen(fname, "w+"); 395 | if (out == NULL) { 396 | ERR("fopen `%s' fails, using stderr: %s", fname, strerror(errno)); 397 | out=stderr; 398 | } 399 | } 400 | else { 401 | out=stderr; 402 | } 403 | 404 | if (getenv("XDEBUG_LEAK") != NULL) { 405 | for (walk=head ; walk != NULL ; old=walk, walk=walk->next) { 406 | xdebug_verify_guard(walk->p, walk->sz); 407 | 408 | fprintf(out, "leak %p size %zu%s from %s:%u\n", walk->p, walk->sz, walk->realloced == 0 ? "" : " Reallocated", walk->file, walk->lineno); 409 | if (getenv("XDEBUG_LEAKDUMP") != NULL) { 410 | xdebug_display_memory(out, walk->p, walk->sz); 411 | } 412 | if (old != NULL) { 413 | if (old->file != NULL) { 414 | free(old->file); 415 | old->file=NULL; 416 | } 417 | free(old); 418 | old=NULL; 419 | } 420 | } 421 | if (old != NULL) { 422 | if (old->file != NULL) { 423 | free(old->file); 424 | old->file=NULL; 425 | } 426 | free(old); 427 | old=NULL; 428 | } 429 | } 430 | 431 | return; 432 | } 433 | 434 | static void display_char(FILE *out, char in) { 435 | if (isgraph(in)) { 436 | fprintf(out, "%c", in); 437 | } 438 | else { 439 | switch (in) { 440 | case '\n': 441 | fprintf(out, "\\n"); break; 442 | case '\v': 443 | fprintf(out, "\\v"); break; 444 | case '\t': 445 | fprintf(out, "\\t"); break; 446 | case '\f': 447 | fprintf(out, "\\f"); break; 448 | case '\r': 449 | fprintf(out, "\\r"); break; 450 | default: 451 | fprintf(out, "\\x%02x", (uint8_t )in); 452 | break; 453 | } 454 | } 455 | } 456 | 457 | void xdebug_display_memory(FILE *out, void *in, size_t len) { 458 | union { 459 | char *c; 460 | void *p; 461 | } m_u; 462 | size_t j=0; 463 | 464 | m_u.p=in; 465 | 466 | for (j=0 ; j < len ; j++) { 467 | if (j != 0 && (j % 16) == 0) { 468 | fprintf(out, "\n"); 469 | } 470 | display_char(out, *m_u.c); 471 | m_u.c++; 472 | } 473 | 474 | fprintf(out, "\n"); 475 | 476 | return; 477 | } 478 | 479 | static void xdebug_verify_guard(void *p, size_t sz) { 480 | union { 481 | uint32_t *g; 482 | uint8_t *c; 483 | void *p; 484 | } g_u; 485 | 486 | g_u.p=p; 487 | 488 | assert(p != NULL); 489 | 490 | if (*g_u.g != guard) { 491 | PANIC("guard %08x != %08x, heap corruption", *g_u.g, guard); 492 | } 493 | 494 | g_u.g++; 495 | g_u.c += sz; 496 | 497 | if (*g_u.g != guard) { 498 | PANIC("guard %08x != %08x, heap corruption", *g_u.g, guard); 499 | } 500 | 501 | return; 502 | } 503 | 504 | #ifdef _WRAP_ 505 | 506 | #include 507 | #include 508 | #include 509 | 510 | settings_t *s=NULL; 511 | 512 | int main(int argc, char ** argv) { 513 | char *cow=NULL; 514 | 515 | s=(settings_t *)xmalloc(sizeof(settings_t)); 516 | s->_stdout=stdout; 517 | s->_stderr=stderr; 518 | 519 | cow=xstrdup("frog frog"); 520 | fprintf(stderr, "%s\n", cow); 521 | 522 | xfree(cow); 523 | 524 | cow=xmalloc(16); 525 | //memset(cow, 0x41, 17); 526 | //memset(cow - 1, 0x41, 17); 527 | 528 | cow=xrealloc(cow, 32); 529 | 530 | memset(cow, 0x31, 32); 531 | 532 | xfree(cow); 533 | 534 | exit(0); 535 | } 536 | 537 | #endif 538 | -------------------------------------------------------------------------------- /ext/_xdebug.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #ifndef XMALLOC_H 20 | #define XMALLOC_H 21 | 22 | #define xfree(ptr) _xfree(ptr); ptr=NULL 23 | #define _xfree(ptr) __xfree((ptr), __FILE__, __LINE__) 24 | #define xmalloc(ptr) _xmalloc((ptr), __FILE__, __LINE__) 25 | #define xrealloc(ptr, size) _xrealloc((ptr), (size), __FILE__, __LINE__) 26 | #define xstrdup(ptr) _xstrdup((ptr), __FILE__, __LINE__) 27 | #define xcalloc(nmemb, len) _xcalloc((nmemb), (len)) 28 | 29 | void *_xmalloc(size_t, const char *, unsigned int); 30 | void *_xcalloc(size_t, size_t, const char *, unsigned int); 31 | void *_xrealloc(void *, size_t, const char *, unsigned int); 32 | void __xfree(void *, const char *, unsigned int); 33 | char *_xstrdup(const char *, const char *, unsigned int); 34 | 35 | void *debug_malloc(size_t); 36 | void *debug_calloc(size_t, size_t); 37 | void *debug_realloc(void *, size_t); 38 | void debug_free(void *); 39 | char *debug_strdup(const char *); 40 | 41 | #define libc_malloc malloc 42 | #define libc_strdup strdup 43 | #define libc_realloc realloc 44 | #define libc_free free 45 | #define libc_calloc calloc 46 | #endif 47 | -------------------------------------------------------------------------------- /ext/_xmalloc.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #include "settings.h" 20 | 21 | #include "ext/xmalloc.h" 22 | 23 | void *xmalloc(size_t n) { 24 | void *p=NULL; 25 | 26 | if (n < 1) { 27 | PANIC("attempt to allocate 0 or less bytes of memory"); 28 | } 29 | 30 | p=malloc(n); 31 | 32 | if (p == NULL) { 33 | PANIC("malloc failed"); 34 | } 35 | 36 | return p; 37 | } 38 | 39 | void *xrealloc(void *obuf, size_t n) { 40 | void *p=NULL; 41 | 42 | if (obuf == NULL) { 43 | return xmalloc(n); 44 | } 45 | if (n < 1) { 46 | PANIC("attempt to increase allocation by 0 bytes"); 47 | } 48 | 49 | p=realloc(obuf, n); 50 | if (p == NULL) { 51 | PANIC("realloc fails"); 52 | } 53 | 54 | return p; 55 | } 56 | 57 | void _xfree(void *p) { 58 | 59 | if (p == NULL) { 60 | PANIC("attempt to free a NULL pointer"); 61 | } 62 | 63 | free(p); 64 | 65 | return; 66 | } 67 | 68 | char *xstrdup(const char *p) { 69 | char *_p=NULL; 70 | 71 | if (p == NULL || strlen(p) < 1) { 72 | PANIC("Attempt to dup an %s string", p != NULL ? "Empty" : "NULL"); 73 | } 74 | 75 | _p=strdup(p); 76 | if (_p == NULL) { 77 | PANIC("strdup failed"); 78 | } 79 | 80 | return _p; 81 | } 82 | 83 | #ifdef _WRAP_ 84 | #include 85 | 86 | int main(int argc, char **argv) { 87 | exit(0); 88 | } 89 | #endif 90 | -------------------------------------------------------------------------------- /ext/_xmalloc.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #ifndef XMALLOC_H 20 | #define XMALLOC_H 21 | 22 | #include 23 | 24 | #define xfree(ptr) _xfree(ptr); ptr=NULL 25 | 26 | void *xmalloc(size_t); 27 | void *xrealloc(void *, size_t ); 28 | void _xfree(void *); 29 | char *xstrdup(const char *); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /ext/chtbl.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #define chead chtbl_head_t 25 | #define cnode chtbl_node_t 26 | 27 | #define CHTMAGIC (uint32_t)0xdefaced1 28 | 29 | #define MALLOC(x) xmalloc(x) 30 | #define FREE(x) xfree(x) 31 | 32 | typedef struct cnode { 33 | void *data; 34 | uint64_t key; 35 | struct cnode *next; 36 | } cnode; 37 | 38 | typedef struct chead { 39 | uint32_t magic; 40 | uint32_t tsize; 41 | uint32_t size; 42 | cnode **table; 43 | } chead; 44 | 45 | static uint32_t s_tbl[]={ 46 | 0x00000002, 0x00000003, 0x00000005, 0x00000007, 0x0000000b, 47 | 0x0000000d, 0x00000011, 0x00000013, 0x00000017, 0x0000001d, 48 | 0x00000025, 0x00000029, 0x0000002f, 0x00000035, 0x0000003b, 49 | 0x00000043, 0x0000004f, 0x00000059, 0x00000065, 0x00000071, 50 | 0x0000007f, 0x00000095, 0x000000a7, 0x000000bf, 0x000000df, 51 | 0x000000fb, 0x00000119, 0x00000139, 0x0000015b, 0x00000185, 52 | 0x000001b1, 0x000001e7, 0x0000021d, 0x00000259, 0x000002a1, 53 | 0x000002ef, 0x00000347, 0x000003a9, 0x00000419, 0x00000493, 54 | 0x00000515, 0x000005a7, 0x00000647, 0x000006fb, 0x000007c3, 55 | 0x0000089f, 0x0000099b, 0x00000ab5, 0x00000be9, 0x00000d3d, 56 | 0x00000eb7, 0x00001069, 0x00001241, 0x0000144d, 0x00001693, 57 | 0x00001915, 0x00001bef, 0x00001f0d, 0x00002285, 0x00002665, 58 | 0x00002ab9, 0x00002f7d, 0x000034c9, 0x00003aa9, 0x00004133, 59 | 0x00004879, 0x00005093, 0x00005989, 0x0000637d, 0x00006e93, 60 | 0x00007aed, 0x000088a5, 0x000097d3, 0x0000a8b5, 0x0000bb91, 61 | 0x0000d069, 0x0000e791, 0x0001014b, 0x00011de5, 0x00013db3, 62 | 0x00016103, 0x00018841, 0x0001b3d9, 0x0001e44b, 0x00021a2b, 63 | 0x00025601, 0x00029873, 0x0002e247, 0x0003345b, 0x00038f83, 64 | 0x0003f4cd, 0x00046559, 0x0004e265, 0x00056d55, 0x000607b5, 65 | 0x0006b353, 0x000771fd, 0x000845c5, 0x00093121, 0x000a36af, 66 | 0x000b5943, 0x000c9c17, 0x000e02cf, 0x000f9157, 0x00114c35, 67 | 0x00133849, 0x00155afb, 0x0017ba75, 0x001a5d6b, 0x001d4b5f, 68 | 0x00208caf, 0x00242a95, 0x00282f55, 0x002ca661, 0x00319c75, 69 | 0x00371fa1, 0x003d3f9d, 0x00440dcd, 0x004b9d91, 0x0054046f, 70 | 0x005d5a47, 0x0067b9a9, 0x00734017, 0x00800e55, 0x008e48d9, 71 | 0x009e1811, 0x00afa909, 0x00c32da1, 0x00d8dd5f, 0x00f0f5f9, 72 | 0x010bbc11, 0x01297bc1, 0x014a89a5, 0x016f43c5, 0x01981279, 73 | 0x01c569f5, 0x01f7cb3d, 0x022fc561, 0x026df7e5, 0x02b31393, 74 | 0x02ffdceb, 0x03552e5d, 0x03b3fab5, 0x041d4f73, 0x04925851, 75 | 0x0514622b, 0x05a4def1, 0x0645698b, 0x06f7caa1, 0x00000000, 76 | }; 77 | 78 | #define THASH(x, y) \ 79 | ((x) % (y)) 80 | 81 | /* exported */ 82 | void *chtinit(uint32_t exp_size) { 83 | union { 84 | void *ptr; 85 | chead *th; 86 | } h_u; 87 | uint32_t j=0; 88 | 89 | for (j=0 ; s_tbl[j] != 0 ; j++) { 90 | if (s_tbl[j] > exp_size) { 91 | exp_size=s_tbl[j]; 92 | break; 93 | } 94 | } 95 | 96 | h_u.ptr=MALLOC(sizeof(chead)); 97 | h_u.th->magic=CHTMAGIC; 98 | h_u.th->tsize=0; 99 | h_u.th->size=exp_size; 100 | h_u.th->table=(cnode **)MALLOC(sizeof(cnode *) * exp_size); 101 | for (j=0 ; j < exp_size ; j++) { 102 | h_u.th->table[j]=(cnode *)NULL; 103 | } 104 | 105 | return h_u.ptr; 106 | } 107 | 108 | uint32_t chtsize(void *lh) { 109 | union { 110 | void *ptr; 111 | chead *th; 112 | } h_u; 113 | 114 | assert(lh != NULL); 115 | h_u.ptr=lh; 116 | assert(h_u.th->magic == CHTMAGIC); 117 | 118 | return h_u.th->size; 119 | } 120 | 121 | void chtdestroy(void *lh) { 122 | union { 123 | void *ptr; 124 | chead *th; 125 | } h_u; 126 | uint32_t j=0; 127 | cnode *n=NULL, *save=NULL; 128 | 129 | assert(lh != NULL); 130 | h_u.ptr=lh; 131 | assert(h_u.th->magic == CHTMAGIC); 132 | 133 | if (h_u.th->tsize == 0) { 134 | return; 135 | } 136 | 137 | for (j=0 ; j < h_u.th->size ; j++) { 138 | n=h_u.th->table[j]; 139 | if (n == NULL) continue; /* nothing to see here, please move along */ 140 | while (n->next != NULL) { 141 | save=n; 142 | n=n->next; 143 | FREE(save); 144 | save=NULL; 145 | } 146 | FREE(n); 147 | } 148 | 149 | FREE(h_u.th->table); 150 | FREE(h_u.ptr); 151 | h_u.ptr=NULL; 152 | 153 | return; 154 | } 155 | 156 | uint32_t chtgetsize(void *th) { 157 | union { 158 | void *ptr; 159 | chead *th; 160 | } h_u; 161 | assert(th != NULL); 162 | h_u.ptr=th; 163 | assert(h_u.th->magic == CHTMAGIC); 164 | 165 | return h_u.th->tsize; 166 | } 167 | 168 | int chtinsert(void *th, uint64_t key, void *data) { 169 | union { 170 | void *ptr; 171 | chead *th; 172 | } h_u; 173 | uint32_t offset=0; 174 | cnode *bucket=NULL, *newn=NULL, *prev=NULL; 175 | 176 | assert(th != NULL); 177 | h_u.ptr=th; 178 | assert(h_u.th->magic == CHTMAGIC); 179 | 180 | offset=THASH(key, h_u.th->size); 181 | 182 | bucket=h_u.th->table[offset]; 183 | 184 | while (bucket != NULL && key != bucket->key) { 185 | prev=bucket; 186 | bucket=bucket->next; 187 | } 188 | if (bucket != NULL && bucket->key == key) { 189 | return CHEXIT_KEYCOLLIDE; 190 | } 191 | 192 | newn=(cnode *)MALLOC(sizeof(cnode)); 193 | newn->key=key; 194 | newn->data=data; 195 | 196 | if (!(prev)) { 197 | h_u.th->table[offset]=newn; 198 | } 199 | else { 200 | prev->next=newn; 201 | } 202 | newn->next=NULL; 203 | ++h_u.th->tsize; 204 | 205 | return CHEXIT_SUCCESS; 206 | } 207 | 208 | int chtdelete(void *th, uint64_t key) { 209 | union { 210 | void *ptr; 211 | chead *th; 212 | } h_u; 213 | uint32_t offset=0; 214 | cnode *bucket=NULL, *prev=NULL; 215 | 216 | assert(th != NULL); 217 | h_u.ptr=th; 218 | assert(h_u.th->magic == CHTMAGIC); 219 | 220 | offset=THASH(key, h_u.th->size); 221 | bucket=h_u.th->table[offset]; 222 | 223 | while (bucket != NULL && bucket->key != key) { 224 | prev=bucket; 225 | bucket=bucket->next; 226 | } 227 | if (bucket == NULL || bucket->key != key) { 228 | return CHEXIT_FAILURE; 229 | } 230 | if (prev != NULL) { 231 | prev->next=bucket->next; 232 | } 233 | else { 234 | h_u.th->table[offset]=bucket->next; 235 | } 236 | FREE(bucket->data); 237 | FREE(bucket); 238 | --h_u.th->tsize; 239 | 240 | return CHEXIT_SUCCESS; 241 | } 242 | 243 | void chtwalk(void *th, int (*wf)(uint64_t, void *, void * /* cbdata */), int ignore, void *cbdata) { 244 | union { 245 | void *ptr; 246 | chead *th; 247 | } h_u; 248 | uint32_t j=0; 249 | int wfbrk=0; 250 | cnode *n=NULL; 251 | 252 | assert(th != NULL); 253 | h_u.ptr=th; 254 | assert(h_u.th->magic == CHTMAGIC); 255 | 256 | if (h_u.th->tsize == 0) { 257 | return; 258 | } 259 | 260 | for (j=0 ; j < h_u.th->size ; j++) { 261 | n=h_u.th->table[j]; 262 | if (n == NULL) { 263 | continue; /* nothing to see here, please move along */ 264 | } 265 | if (wf(n->key, n->data, cbdata) == 0) { 266 | break; 267 | } 268 | for ( wfbrk=0, n=n->next ; n != NULL ; n=n->next) { 269 | if (wf(n->key, n->data, cbdata) == 0) { 270 | wfbrk=1; 271 | break; 272 | } 273 | } 274 | if (wfbrk == 1) { 275 | break; 276 | } 277 | } 278 | 279 | return; 280 | } 281 | 282 | int chtfind(void *th, uint64_t key, void **udata) { 283 | union { 284 | void *ptr; 285 | chead *th; 286 | } h_u; 287 | uint32_t offset=0; 288 | cnode *bucket=NULL, *prev=NULL; 289 | 290 | assert(th != NULL); 291 | h_u.ptr=th; 292 | assert(h_u.th->magic == CHTMAGIC); 293 | 294 | offset=THASH(key, h_u.th->size); 295 | 296 | for (bucket=h_u.th->table[offset] ; bucket != NULL && bucket->key != key ; bucket=bucket->next) { 297 | prev=bucket; 298 | } 299 | 300 | if (bucket == NULL || bucket->key != key) { 301 | *udata=NULL; 302 | return CHEXIT_FAILURE; 303 | } 304 | 305 | *udata=bucket->data; 306 | return CHEXIT_SUCCESS; 307 | } 308 | 309 | #ifdef DEBUG 310 | void chtstats(void *th) { 311 | union { 312 | void *ptr; 313 | chead *th; 314 | } h_u; 315 | uint32_t j=0; 316 | uint32_t clen=0; 317 | cnode *step=NULL; 318 | 319 | assert(th != NULL); 320 | h_u.ptr=th; 321 | assert(h_u.th->magic == CHTMAGIC); 322 | 323 | printf("Load Factor %f [%u items in %u slots]\n", (float)(h_u.th->tsize / h_u.th->size), h_u.th->tsize, h_u.th->size); 324 | 325 | for (j=0 ; j < h_u.th->size ; j++) { 326 | if (h_u.th->table[j]) { 327 | step=h_u.th->table[j]; ++clen; 328 | while (step->next != NULL) { 329 | ++clen; 330 | step=step->next; 331 | } 332 | printf("%u [%u] ", j, clen); clen=0; 333 | } 334 | } 335 | } 336 | #endif 337 | 338 | #undef chead 339 | #undef cnode 340 | -------------------------------------------------------------------------------- /ext/chtbl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #ifndef _CHTBL_H 20 | # define _CHTBL_H 21 | 22 | #define CHEXIT_KEYCOLLIDE -2 23 | #define CHEXIT_FAILURE -1 24 | #define CHEXIT_SUCCESS 1 25 | 26 | void *chtinit(uint32_t /* expected size */); 27 | 28 | int chtinsert (void * /* th */, uint64_t /* key */, void * /* data */ ); 29 | int chtdelete (void * /* th */, uint64_t /* key */ ); 30 | int chtfind (void * /* th */, uint64_t /* key */, void ** /* data_ptr */); 31 | void chtstats (void * /* th */); 32 | void chtwalk (void * /* rh */, int (* /* walk func */)(uint64_t /* key */, void * /* data ptr */, void * /* cbdata */), int /* wt 0-2*/, void * /* cbdata */); 33 | uint32_t chtgetsize(void * /* th */); 34 | void chtdestroy(void * /* rh */); 35 | uint32_t chtsize (void * /* rh */); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /ext/cidr.c: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #include "../settings.h" 20 | 21 | #include 22 | #include "xmalloc.h" 23 | #include "standard_dns.h" 24 | #include "cidr.h" 25 | 26 | #ifndef ntohll 27 | # if BIGENDIAN == 0 28 | # define ntohll(x) (((unsigned long long)ntohl((x))) << 32) + ntohl((x) >> 32) 29 | # else 30 | # define ntohll(x) (x) 31 | # endif 32 | #endif 33 | #ifndef htonll 34 | # if BIGENDIAN == 0 35 | # define htonll(x) (((unsigned long long)htonl((x))) << 32) + htonl((x) >> 32) 36 | # else 37 | # define htonll(x) (x) 38 | # endif 39 | #endif 40 | 41 | static inline int cidr_in6cmp(const void *, const void *); 42 | static inline void cidr_in6inc(void *); 43 | static void cidr_fill6mask(void *, unsigned int ); 44 | static void cidr_u128str(const void *) __attribute__((unused)); 45 | 46 | typedef struct __attribute__((packed)) u128_t { 47 | uint64_t u; 48 | uint64_t l; 49 | } u128_t; 50 | 51 | static const uint32_t cidrmasktbl[]={ 52 | 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 53 | 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 54 | 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 55 | 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 56 | 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 57 | 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 58 | 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 59 | 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff 60 | }; 61 | 62 | #if 0 63 | void mktbl6data(void) { 64 | #define TBIT (((0ULL - 1) / 2) + 1) 65 | #define EV(x) ((x) != 0 && (((x) + 1) % 2) == 0) 66 | uint64_t a=TBIT, b=0, *c=&a, f=0; 67 | for (;; f++) { 68 | printf("%s{0x%016llxULL, 0x%016llxULL},%c", EV(f) ? "" : "\t", a, b, EV(f) ? '\n' : ' '); 69 | *c=(*c >> 1) | TBIT; 70 | if (*c == (uint64_t)(0 - 1)) { 71 | if (c == &b) { 72 | printf("{0x%016llxULL, 0x%016llxULL}\n", a, b); 73 | break; 74 | } 75 | c=&b; 76 | } 77 | } 78 | } 79 | #endif 80 | 81 | static const u128_t cidrmasktbl_6[]={ 82 | {0x8000000000000000ULL, 0x0000000000000000ULL}, {0xc000000000000000ULL, 0x0000000000000000ULL}, 83 | {0xe000000000000000ULL, 0x0000000000000000ULL}, {0xf000000000000000ULL, 0x0000000000000000ULL}, 84 | {0xf800000000000000ULL, 0x0000000000000000ULL}, {0xfc00000000000000ULL, 0x0000000000000000ULL}, 85 | {0xfe00000000000000ULL, 0x0000000000000000ULL}, {0xff00000000000000ULL, 0x0000000000000000ULL}, 86 | {0xff80000000000000ULL, 0x0000000000000000ULL}, {0xffc0000000000000ULL, 0x0000000000000000ULL}, 87 | {0xffe0000000000000ULL, 0x0000000000000000ULL}, {0xfff0000000000000ULL, 0x0000000000000000ULL}, 88 | {0xfff8000000000000ULL, 0x0000000000000000ULL}, {0xfffc000000000000ULL, 0x0000000000000000ULL}, 89 | {0xfffe000000000000ULL, 0x0000000000000000ULL}, {0xffff000000000000ULL, 0x0000000000000000ULL}, 90 | {0xffff800000000000ULL, 0x0000000000000000ULL}, {0xffffc00000000000ULL, 0x0000000000000000ULL}, 91 | {0xffffe00000000000ULL, 0x0000000000000000ULL}, {0xfffff00000000000ULL, 0x0000000000000000ULL}, 92 | {0xfffff80000000000ULL, 0x0000000000000000ULL}, {0xfffffc0000000000ULL, 0x0000000000000000ULL}, 93 | {0xfffffe0000000000ULL, 0x0000000000000000ULL}, {0xffffff0000000000ULL, 0x0000000000000000ULL}, 94 | {0xffffff8000000000ULL, 0x0000000000000000ULL}, {0xffffffc000000000ULL, 0x0000000000000000ULL}, 95 | {0xffffffe000000000ULL, 0x0000000000000000ULL}, {0xfffffff000000000ULL, 0x0000000000000000ULL}, 96 | {0xfffffff800000000ULL, 0x0000000000000000ULL}, {0xfffffffc00000000ULL, 0x0000000000000000ULL}, 97 | {0xfffffffe00000000ULL, 0x0000000000000000ULL}, {0xffffffff00000000ULL, 0x0000000000000000ULL}, 98 | {0xffffffff80000000ULL, 0x0000000000000000ULL}, {0xffffffffc0000000ULL, 0x0000000000000000ULL}, 99 | {0xffffffffe0000000ULL, 0x0000000000000000ULL}, {0xfffffffff0000000ULL, 0x0000000000000000ULL}, 100 | {0xfffffffff8000000ULL, 0x0000000000000000ULL}, {0xfffffffffc000000ULL, 0x0000000000000000ULL}, 101 | {0xfffffffffe000000ULL, 0x0000000000000000ULL}, {0xffffffffff000000ULL, 0x0000000000000000ULL}, 102 | {0xffffffffff800000ULL, 0x0000000000000000ULL}, {0xffffffffffc00000ULL, 0x0000000000000000ULL}, 103 | {0xffffffffffe00000ULL, 0x0000000000000000ULL}, {0xfffffffffff00000ULL, 0x0000000000000000ULL}, 104 | {0xfffffffffff80000ULL, 0x0000000000000000ULL}, {0xfffffffffffc0000ULL, 0x0000000000000000ULL}, 105 | {0xfffffffffffe0000ULL, 0x0000000000000000ULL}, {0xffffffffffff0000ULL, 0x0000000000000000ULL}, 106 | {0xffffffffffff8000ULL, 0x0000000000000000ULL}, {0xffffffffffffc000ULL, 0x0000000000000000ULL}, 107 | {0xffffffffffffe000ULL, 0x0000000000000000ULL}, {0xfffffffffffff000ULL, 0x0000000000000000ULL}, 108 | {0xfffffffffffff800ULL, 0x0000000000000000ULL}, {0xfffffffffffffc00ULL, 0x0000000000000000ULL}, 109 | {0xfffffffffffffe00ULL, 0x0000000000000000ULL}, {0xffffffffffffff00ULL, 0x0000000000000000ULL}, 110 | {0xffffffffffffff80ULL, 0x0000000000000000ULL}, {0xffffffffffffffc0ULL, 0x0000000000000000ULL}, 111 | {0xffffffffffffffe0ULL, 0x0000000000000000ULL}, {0xfffffffffffffff0ULL, 0x0000000000000000ULL}, 112 | {0xfffffffffffffff8ULL, 0x0000000000000000ULL}, {0xfffffffffffffffcULL, 0x0000000000000000ULL}, 113 | {0xfffffffffffffffeULL, 0x0000000000000000ULL}, {0xffffffffffffffffULL, 0x0000000000000000ULL}, 114 | {0xffffffffffffffffULL, 0x8000000000000000ULL}, {0xffffffffffffffffULL, 0xc000000000000000ULL}, 115 | {0xffffffffffffffffULL, 0xe000000000000000ULL}, {0xffffffffffffffffULL, 0xf000000000000000ULL}, 116 | {0xffffffffffffffffULL, 0xf800000000000000ULL}, {0xffffffffffffffffULL, 0xfc00000000000000ULL}, 117 | {0xffffffffffffffffULL, 0xfe00000000000000ULL}, {0xffffffffffffffffULL, 0xff00000000000000ULL}, 118 | {0xffffffffffffffffULL, 0xff80000000000000ULL}, {0xffffffffffffffffULL, 0xffc0000000000000ULL}, 119 | {0xffffffffffffffffULL, 0xffe0000000000000ULL}, {0xffffffffffffffffULL, 0xfff0000000000000ULL}, 120 | {0xffffffffffffffffULL, 0xfff8000000000000ULL}, {0xffffffffffffffffULL, 0xfffc000000000000ULL}, 121 | {0xffffffffffffffffULL, 0xfffe000000000000ULL}, {0xffffffffffffffffULL, 0xffff000000000000ULL}, 122 | {0xffffffffffffffffULL, 0xffff800000000000ULL}, {0xffffffffffffffffULL, 0xffffc00000000000ULL}, 123 | {0xffffffffffffffffULL, 0xffffe00000000000ULL}, {0xffffffffffffffffULL, 0xfffff00000000000ULL}, 124 | {0xffffffffffffffffULL, 0xfffff80000000000ULL}, {0xffffffffffffffffULL, 0xfffffc0000000000ULL}, 125 | {0xffffffffffffffffULL, 0xfffffe0000000000ULL}, {0xffffffffffffffffULL, 0xffffff0000000000ULL}, 126 | {0xffffffffffffffffULL, 0xffffff8000000000ULL}, {0xffffffffffffffffULL, 0xffffffc000000000ULL}, 127 | {0xffffffffffffffffULL, 0xffffffe000000000ULL}, {0xffffffffffffffffULL, 0xfffffff000000000ULL}, 128 | {0xffffffffffffffffULL, 0xfffffff800000000ULL}, {0xffffffffffffffffULL, 0xfffffffc00000000ULL}, 129 | {0xffffffffffffffffULL, 0xfffffffe00000000ULL}, {0xffffffffffffffffULL, 0xffffffff00000000ULL}, 130 | {0xffffffffffffffffULL, 0xffffffff80000000ULL}, {0xffffffffffffffffULL, 0xffffffffc0000000ULL}, 131 | {0xffffffffffffffffULL, 0xffffffffe0000000ULL}, {0xffffffffffffffffULL, 0xfffffffff0000000ULL}, 132 | {0xffffffffffffffffULL, 0xfffffffff8000000ULL}, {0xffffffffffffffffULL, 0xfffffffffc000000ULL}, 133 | {0xffffffffffffffffULL, 0xfffffffffe000000ULL}, {0xffffffffffffffffULL, 0xffffffffff000000ULL}, 134 | {0xffffffffffffffffULL, 0xffffffffff800000ULL}, {0xffffffffffffffffULL, 0xffffffffffc00000ULL}, 135 | {0xffffffffffffffffULL, 0xffffffffffe00000ULL}, {0xffffffffffffffffULL, 0xfffffffffff00000ULL}, 136 | {0xffffffffffffffffULL, 0xfffffffffff80000ULL}, {0xffffffffffffffffULL, 0xfffffffffffc0000ULL}, 137 | {0xffffffffffffffffULL, 0xfffffffffffe0000ULL}, {0xffffffffffffffffULL, 0xffffffffffff0000ULL}, 138 | {0xffffffffffffffffULL, 0xffffffffffff8000ULL}, {0xffffffffffffffffULL, 0xffffffffffffc000ULL}, 139 | {0xffffffffffffffffULL, 0xffffffffffffe000ULL}, {0xffffffffffffffffULL, 0xfffffffffffff000ULL}, 140 | {0xffffffffffffffffULL, 0xfffffffffffff800ULL}, {0xffffffffffffffffULL, 0xfffffffffffffc00ULL}, 141 | {0xffffffffffffffffULL, 0xfffffffffffffe00ULL}, {0xffffffffffffffffULL, 0xffffffffffffff00ULL}, 142 | {0xffffffffffffffffULL, 0xffffffffffffff80ULL}, {0xffffffffffffffffULL, 0xffffffffffffffc0ULL}, 143 | {0xffffffffffffffffULL, 0xffffffffffffffe0ULL}, {0xffffffffffffffffULL, 0xfffffffffffffff0ULL}, 144 | {0xffffffffffffffffULL, 0xfffffffffffffff8ULL}, {0xffffffffffffffffULL, 0xfffffffffffffffcULL}, 145 | {0xffffffffffffffffULL, 0xfffffffffffffffeULL}, {0xffffffffffffffffULL, 0xffffffffffffffffULL} 146 | }; 147 | 148 | int cidr_get(const char *instr, struct sockaddr *net_id, struct sockaddr *netmask, unsigned int *cmask) { 149 | union { 150 | struct sockaddr *p; 151 | struct sockaddr_in *sin; 152 | struct sockaddr_in6 *sin6; 153 | } net_u, mask_u; 154 | struct in_addr ia; 155 | struct in6_addr ia6; 156 | sockaddr_list_t **sl=NULL; 157 | char *masksl=NULL, tbuf[4096]; 158 | int exp_family=AF_INET, j=0, sd_flags; 159 | unsigned int maskset=0; 160 | void *sc=NULL; 161 | 162 | net_u.p=net_id; 163 | mask_u.p=netmask; 164 | 165 | if (net_id == NULL || netmask == NULL || instr == NULL || cmask == NULL) { 166 | return -1; 167 | } 168 | 169 | *cmask=0; 170 | 171 | if (sscanf(instr, "ipv4:%4095[^/]", tbuf) == 1) { 172 | } 173 | else if (sscanf(instr, "ipv6:%4095[^/]", tbuf) == 1) { 174 | exp_family=AF_INET6; 175 | } 176 | else if (sscanf(instr, "%4095[^/]", tbuf) != 1) { 177 | ERR("cant even get host part of cidr string"); 178 | return -1; 179 | } 180 | 181 | if (s->ipv6_lookup == 1 && s->ipv4_lookup == 0) { 182 | exp_family=AF_INET6; 183 | } 184 | 185 | if ((masksl=strrchr(instr, '/')) != NULL) { 186 | masksl++; 187 | if (sscanf(masksl, "%u", cmask) != 1) { 188 | ERR("bad mask (numeric?)!"); 189 | return -1; 190 | } 191 | maskset++; 192 | } 193 | 194 | if (inet_pton(AF_INET, tbuf, &ia) > 0 && exp_family != AF_INET6) { 195 | if (maskset == 0) { 196 | *cmask=32; 197 | } 198 | else if (*cmask > 32) { 199 | ERR("mask too big for ipv4"); 200 | return -1; 201 | } 202 | 203 | net_u.sin->sin_family=AF_INET; 204 | mask_u.sin->sin_family=AF_INET; 205 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 206 | net_u.sin->sin_len=(uint8_t )sizeof(struct sockaddr_in); 207 | mask_u.sin->sin_len=(uint8_t )sizeof(struct sockaddr_in); 208 | #endif 209 | mask_u.sin->sin_addr.s_addr=*cmask == 0 ? 0 : htonl(cidrmasktbl[*cmask - 1]); 210 | net_u.sin->sin_addr.s_addr=ia.s_addr & mask_u.sin->sin_addr.s_addr; 211 | 212 | return exp_family; 213 | } 214 | else if (inet_pton(AF_INET6, tbuf, &ia6) > 0) { 215 | if (maskset == 0) { 216 | *cmask=128; 217 | } 218 | else if (*cmask > 128) { 219 | ERR("mask too large for ipv6"); 220 | return -1; 221 | } 222 | 223 | net_u.sin6->sin6_family=AF_INET6; 224 | mask_u.sin6->sin6_family=AF_INET6; 225 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 226 | net_u.sin6->sin6_len=(uint8_t )sizeof(struct sockaddr_in6); 227 | mask_u.sin6->sin6_len=(uint8_t )sizeof(struct sockaddr_in6); 228 | #endif 229 | cidr_fill6mask(mask_u.sin6->sin6_addr.s6_addr, *cmask); 230 | memcpy(net_u.sin6->sin6_addr.s6_addr, ia6.s6_addr, sizeof(struct in6_addr)); 231 | 232 | for (j=0 ; j < 16; j++) { 233 | net_u.sin6->sin6_addr.s6_addr[j]=net_u.sin6->sin6_addr.s6_addr[j] & mask_u.sin6->sin6_addr.s6_addr[j]; 234 | } 235 | 236 | return exp_family; 237 | } 238 | 239 | sd_flags=0; 240 | if (exp_family == AF_INET) { 241 | sd_flags=STDDNS_FLG_IPV4; 242 | } 243 | else { 244 | sd_flags=STDDNS_FLG_IPV6; 245 | } 246 | 247 | sc=stddns_init(NULL, sd_flags); 248 | if (sc == NULL) { 249 | return -1; 250 | } 251 | 252 | sl=stddns_getaddr(sc, tbuf); 253 | if (sl == NULL) { 254 | stddns_fini(&sc); 255 | return -1; 256 | } 257 | 258 | for (j=0; sl[j] != NULL; j++) { 259 | if (exp_family == AF_INET && sl[j]->s_u.fs.family == AF_INET) { 260 | if (maskset == 0) { 261 | *cmask=32; 262 | } 263 | else if (*cmask > 32) { 264 | ERR("mask too big for ipv4"); 265 | stddns_freeaddr(sc, &sl); 266 | stddns_fini(&sc); 267 | return -1; 268 | } 269 | 270 | net_u.sin->sin_family=AF_INET; 271 | mask_u.sin->sin_family=AF_INET; 272 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 273 | net_u.sin->sin_len=(uint8_t )sizeof(struct sockaddr_in); 274 | mask_u.sin->sin_len=(uint8_t )sizeof(struct sockaddr_in); 275 | #endif 276 | mask_u.sin->sin_addr.s_addr=*cmask == 0 ? 0 : htonl(cidrmasktbl[*cmask - 1]); 277 | net_u.sin->sin_addr.s_addr=sl[j]->s_u.sin.sin_addr.s_addr & mask_u.sin->sin_addr.s_addr; 278 | 279 | stddns_freeaddr(sc, &sl); 280 | stddns_fini(&sc); 281 | 282 | return exp_family; 283 | } 284 | else { 285 | if (maskset == 0) { 286 | *cmask=128; 287 | } 288 | else if (*cmask > 128) { 289 | ERR("mask too large for ipv6"); 290 | stddns_freeaddr(sc, &sl); 291 | stddns_fini(&sc); 292 | return -1; 293 | } 294 | 295 | net_u.sin6->sin6_family=AF_INET6; 296 | mask_u.sin6->sin6_family=AF_INET6; 297 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 298 | net_u.sin6->sin6_len=(uint8_t )sizeof(struct sockaddr_in6); 299 | mask_u.sin6->sin6_len=(uint8_t )sizeof(struct sockaddr_in6); 300 | #endif 301 | cidr_fill6mask(mask_u.sin6->sin6_addr.s6_addr, *cmask); 302 | memcpy(net_u.sin6->sin6_addr.s6_addr, sl[j]->s_u.sin6.sin6_addr.s6_addr, sizeof(struct in6_addr)); 303 | 304 | for (j=0 ; j < 16; j++) { 305 | net_u.sin6->sin6_addr.s6_addr[j]=net_u.sin6->sin6_addr.s6_addr[j] & mask_u.sin6->sin6_addr.s6_addr[j]; 306 | } 307 | 308 | stddns_freeaddr(sc, &sl); 309 | stddns_fini(&sc); 310 | 311 | return exp_family; 312 | } 313 | } 314 | 315 | /* 316 | * we didnt match anything 317 | */ 318 | stddns_freeaddr(sc, &sl); 319 | stddns_fini(&sc); 320 | 321 | return -1; 322 | } 323 | 324 | static void cidr_fill6mask(void *a, unsigned int mask) { 325 | union { 326 | void *p; 327 | uint64_t *dw; 328 | } p_u; 329 | 330 | if (mask == 0) { 331 | memset(p_u.p, 0, sizeof(struct in6_addr)); 332 | return; 333 | } 334 | p_u.p=a; 335 | *p_u.dw=htonll(cidrmasktbl_6[mask - 1].u); 336 | p_u.dw++; 337 | *p_u.dw=htonll(cidrmasktbl_6[mask - 1].l); 338 | return; 339 | } 340 | 341 | int cidr_inchost(struct sockaddr *p, struct sockaddr *n, struct sockaddr *m) { 342 | union { 343 | struct sockaddr *p; 344 | struct sockaddr_in *sin; 345 | struct sockaddr_in6 *sin6; 346 | struct f_s *fs; 347 | } s_u; 348 | uint32_t tmp=0; 349 | 350 | s_u.p=p; 351 | 352 | switch (s_u.fs->family) { 353 | case AF_INET: 354 | tmp=ntohl(s_u.sin->sin_addr.s_addr) + 1; 355 | s_u.sin->sin_addr.s_addr=htonl(tmp); 356 | return 1; 357 | break; 358 | 359 | case AF_INET6: 360 | cidr_in6inc(s_u.sin6->sin6_addr.s6_addr); 361 | return 1; 362 | break; 363 | default: 364 | return -1; 365 | } 366 | 367 | return 0; 368 | } 369 | 370 | int cidr_within(const struct sockaddr *host, const struct sockaddr *net, const struct sockaddr *mask) { 371 | union { 372 | const struct sockaddr *p; 373 | const struct sockaddr_in *sin; 374 | const struct sockaddr_in6 *sin6; 375 | const struct f_s *fs; 376 | } host_u, net_u, mask_u; 377 | 378 | if (host == NULL || net == NULL || mask == NULL) { 379 | ERR("one or more arguments null"); 380 | return -1; 381 | } 382 | 383 | host_u.p=host; 384 | net_u.p=net; 385 | mask_u.p=mask; 386 | 387 | if (net_u.fs->family != mask_u.fs->family) { 388 | ERR("net family not same as mask family"); 389 | return -1; 390 | } 391 | 392 | if (host_u.fs->family != net_u.fs->family) { 393 | ERR("host family not same as network family"); 394 | return 0; 395 | } 396 | 397 | if (host_u.fs->family == AF_INET) { 398 | uint32_t host_max, host_min, host_cur; 399 | 400 | host_min=ntohl(net_u.sin->sin_addr.s_addr); 401 | host_max=host_min | ~(ntohl(mask_u.sin->sin_addr.s_addr)); 402 | host_cur=ntohl(host_u.sin->sin_addr.s_addr); 403 | 404 | if (host_cur > host_max || host_cur < host_min) { 405 | return 0; 406 | } 407 | 408 | return 1; 409 | } 410 | else if (host_u.fs->family == AF_INET6) { 411 | u128_t host_max, host_min, host_cur; 412 | union { 413 | u128_t *p; 414 | uint8_t *c; 415 | } dw_u; 416 | int j=0; 417 | 418 | memcpy(&host_min, net_u.sin6->sin6_addr.s6_addr, sizeof(host_min)); 419 | memcpy(&host_max, net_u.sin6->sin6_addr.s6_addr, sizeof(host_max)); 420 | 421 | dw_u.p=&host_max; 422 | for (j=0 ; j < 16; j++) { 423 | *dw_u.c=net_u.sin6->sin6_addr.s6_addr[j] | ~(mask_u.sin6->sin6_addr.s6_addr[j]); 424 | dw_u.c++; 425 | } 426 | 427 | memcpy(&host_cur, host_u.sin6->sin6_addr.s6_addr, sizeof(struct in6_addr)); 428 | 429 | if ( (cidr_in6cmp(&host_cur, &host_min) != -1 /* so cur is >= host_min */) && 430 | (cidr_in6cmp(&host_cur, &host_max) != 1 /* so cur is <= host_max */)) { 431 | return 1; 432 | } 433 | 434 | return 0; 435 | } 436 | else { 437 | return -1; 438 | } 439 | 440 | return 0; 441 | } 442 | 443 | char *cidr_saddrstr(const struct sockaddr *in) { 444 | union { 445 | struct f_s *fs; 446 | const struct sockaddr *s; 447 | const struct sockaddr_in *sin; 448 | const struct sockaddr_in6 *sin6; 449 | } s_u; 450 | static char nbuf[256], *ret=NULL; 451 | const void *p=NULL; 452 | 453 | if (in == NULL) { 454 | return NULL; 455 | } 456 | 457 | s_u.s=in; 458 | 459 | switch (s_u.fs->family) { 460 | case AF_INET: 461 | p=&s_u.sin->sin_addr; 462 | break; 463 | 464 | case AF_INET6: 465 | p=&s_u.sin6->sin6_addr; 466 | break; 467 | 468 | default: 469 | ERR("unknown address family `%d'?", s_u.fs->family); 470 | return NULL; 471 | } 472 | 473 | ret=inet_ntop(s_u.fs->family, p, nbuf, sizeof(nbuf) - 1); /* GAH */ 474 | if (ret == NULL) { 475 | ERR("inet_ntop fails: %s", strerror(errno)); 476 | } 477 | 478 | return ret; 479 | } 480 | 481 | /* 482 | * returns: 483 | * 1 if a > b 484 | * 0 if a == b 485 | * -1 if a < b 486 | */ 487 | static inline int cidr_in6cmp(const void *a, const void *b) { 488 | union { 489 | const uint8_t *c; 490 | const void *p; 491 | } p1_u, p2_u; 492 | int j=0; 493 | 494 | p1_u.p=a; 495 | p2_u.p=b; 496 | for (j=0; j < 16; j++) { 497 | if (p1_u.c[j] > p2_u.c[j]) { 498 | return 1; 499 | } 500 | else if (p1_u.c[j] != p2_u.c[j]) { 501 | return -1; 502 | } 503 | } 504 | 505 | return 0; 506 | } 507 | 508 | static inline void cidr_in6inc(void *a) { 509 | #if BIGENDIAN == 0 510 | union { 511 | uint8_t *c; 512 | uint64_t *dw; 513 | void *p; 514 | } p_u; 515 | uint64_t dw; 516 | #endif 517 | u128_t tmp; 518 | 519 | #if BIGENDIAN == 0 520 | p_u.p=a; 521 | tmp.l=ntohll(*p_u.dw); 522 | p_u.dw++; 523 | tmp.u=ntohll(*p_u.dw); 524 | #else 525 | memcpy(&tmp, a, sizeof(tmp)); 526 | #endif 527 | 528 | #if BIGENDIAN == 0 529 | tmp.u++; 530 | if (tmp.u == 0ULL) { 531 | tmp.l++; 532 | } 533 | #else 534 | tmp.l++; 535 | if (tmp.l == 0ULL) { 536 | tmp.u++; 537 | } 538 | #endif 539 | 540 | 541 | #if BIGENDIAN == 0 542 | dw=htonll(tmp.l); 543 | p_u.p=a; 544 | memcpy(p_u.p, &dw, sizeof(dw)); 545 | p_u.dw++; 546 | dw=htonll(tmp.u); 547 | memcpy(p_u.p, &dw, sizeof(dw)); 548 | #else 549 | memcpy(a, &tmp, sizeof(tmp)); 550 | #endif 551 | 552 | return; 553 | } 554 | 555 | static void cidr_u128str(const void *in) { 556 | const uint8_t *c=NULL; 557 | int cnt=0; 558 | 559 | printf("BUF DUMP: "); 560 | for (c=(const uint8_t *)in, cnt=0; cnt < 16; cnt++, c++) { 561 | printf(":%02x", *c); 562 | } 563 | 564 | printf("\n"); 565 | 566 | return; 567 | } 568 | -------------------------------------------------------------------------------- /ext/cidr.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (C) (2004) (Jack Louis) * 3 | * * 4 | * This program is free software; you can redistribute it and/or * 5 | * modify it under the terms of the GNU General Public License * 6 | * as published by the Free Software Foundation; either * 7 | * version 2 of the License, or (at your option) any later * 8 | * version. * 9 | * * 10 | * This program is distributed in the hope that it will be useful, * 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 | * GNU General Public License for more details. * 14 | * * 15 | * You should have received a copy of the GNU General Public License * 16 | * along with this program; if not, write to the Free Software * 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 | **********************************************************************/ 19 | #ifndef _CIDR_H 20 | # define _CIDR_H 21 | 22 | /* 23 | * returns: 24 | * > -1 address family AF_INET or AF_INET6 that sockaddr's are within 25 | * -1: error condition with error message in error string pointer 26 | * arguments: 27 | */ 28 | 29 | int cidr_get( 30 | const char * /* network string */, 31 | struct sockaddr * /* netid host order */, 32 | struct sockaddr * /* netmask (host order) */, 33 | unsigned int * /* parsed cidr mask (perhaps implied) */ 34 | ); 35 | 36 | /* 37 | * increments the socket address, returns 1 if ok, -1 otherwise 38 | */ 39 | int cidr_inchost( 40 | struct sockaddr * /* host */, 41 | struct sockaddr * /* network */, 42 | struct sockaddr * /* netmask */ 43 | ); 44 | 45 | /* 46 | * returns 1 if host is within the network/netmask, 0 if it is outside, 47 | * and -1 if there is some sort of error with the arguments 48 | */ 49 | int cidr_within( 50 | const struct sockaddr * /* host */, 51 | const struct sockaddr * /* network */, 52 | const struct sockaddr * /* netmask */ 53 | ); 54 | /* 55 | * returns a string describing the socket address structure 56 | */ 57 | char *cidr_saddrstr(const struct sockaddr * /* address */); 58 | 59 | #endif /* _CIDR_H */ 60 | -------------------------------------------------------------------------------- /ext/fread.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "ext/xmalloc.h" 4 | #include "ext/fread.h" 5 | 6 | #include 7 | 8 | #define FREAD_MAGIC 0x46b03a19 9 | 10 | typedef struct fread_t { 11 | uint32_t magic; 12 | char *fname; 13 | unsigned int lineno; 14 | unsigned int rtimes; 15 | int close; 16 | 17 | int flags; 18 | 19 | FILE *stream; 20 | gzFile *gdesc; 21 | 22 | char *buf; 23 | } fread_t; 24 | 25 | #define FREAD_BUFSZ 4096 26 | 27 | void *fread_create (const char *filename, int flags) { 28 | union { 29 | void *p; 30 | fread_t *f; 31 | } f_u; 32 | char fname[PATH_MAX]; 33 | 34 | f_u.p=NULL; 35 | 36 | if (filename == NULL || strlen(filename) < 1) { 37 | return NULL; 38 | } 39 | 40 | f_u.p=xmalloc(sizeof(fread_t)); 41 | memset(f_u.p, 0, sizeof(fread_t)); 42 | f_u.f->magic=FREAD_MAGIC; 43 | 44 | f_u.f->stream=fopen(filename, "r"); 45 | if (f_u.f->stream == NULL) { 46 | snprintf(fname, sizeof(fname) -1, "%s.gz", filename); 47 | 48 | f_u.f->gdesc=gzopen(fname, "r"); 49 | if (f_u.f->gdesc == NULL) { 50 | xfree(f_u.p); 51 | return NULL; 52 | } 53 | //gzclearerr(f_u.f->gdesc); 54 | f_u.f->fname=xstrdup(fname); 55 | } 56 | else { 57 | (void )clearerr(f_u.f->stream); 58 | f_u.f->fname=xstrdup(filename); 59 | } 60 | 61 | f_u.f->flags=flags; 62 | f_u.f->lineno=0; 63 | f_u.f->rtimes=0; 64 | f_u.f->close=1; 65 | 66 | return f_u.p; 67 | } 68 | 69 | void *fread_assoc (FILE *fhand, const char *filename, int flags, int iclose) { 70 | union { 71 | void *p; 72 | fread_t *f; 73 | } f_u; 74 | 75 | if (fhand == NULL) { 76 | return NULL; 77 | } 78 | 79 | f_u.p=NULL; 80 | 81 | f_u.p=xmalloc(sizeof(fread_t)); 82 | memset(f_u.p, 0, sizeof(fread_t)); 83 | f_u.f->magic=FREAD_MAGIC; 84 | 85 | if (filename == NULL || strlen(filename) < 1) { 86 | f_u.f->fname=xstrdup("None"); 87 | } 88 | else { 89 | f_u.f->fname=xstrdup(filename); 90 | } 91 | 92 | f_u.f->stream=fhand; 93 | 94 | (void )clearerr(f_u.f->stream); 95 | 96 | f_u.f->flags=flags; 97 | f_u.f->lineno=0; 98 | f_u.f->rtimes=0; 99 | f_u.f->close=iclose; 100 | 101 | return f_u.p; 102 | } 103 | 104 | int fread_getline(void *p, char **buf) { 105 | union { 106 | void *p; 107 | fread_t *f; 108 | } f_u; 109 | 110 | if (p == NULL) { 111 | ERR("getline with null fread handle"); 112 | return -1; 113 | } 114 | 115 | if (buf == NULL) { 116 | ERR("getline with null output pointer"); 117 | return -1; 118 | } 119 | *buf=NULL; 120 | 121 | f_u.p=p; 122 | assert(f_u.f->magic == FREAD_MAGIC); 123 | 124 | if (f_u.f->stream == NULL && f_u.f->gdesc == NULL) { 125 | ERR("fread handle does not contain an open file, perhaps you need to fread_create first?"); 126 | return -1; 127 | } 128 | 129 | if ((f_u.f->stream != NULL && feof(f_u.f->stream)) || (f_u.f->gdesc != NULL && gzeof(f_u.f->gdesc))) { 130 | return 0; 131 | } 132 | 133 | if (f_u.f->buf == NULL) { 134 | f_u.f->buf=xmalloc(FREAD_BUFSZ); 135 | } 136 | 137 | memset(f_u.f->buf, 0, FREAD_BUFSZ); 138 | 139 | if (f_u.f->stream != NULL) { 140 | if (fgets(f_u.f->buf, FREAD_BUFSZ - 1, f_u.f->stream) == NULL) { 141 | return 0; 142 | } 143 | } 144 | else if (f_u.f->gdesc != NULL) { 145 | if (gzgets(f_u.f->gdesc, f_u.f->buf, FREAD_BUFSZ - 1) == NULL) { 146 | return 0; 147 | } 148 | } 149 | else { 150 | PANIC("whoa"); 151 | } 152 | f_u.f->lineno++; 153 | 154 | *buf=f_u.f->buf; 155 | 156 | if (strlen(f_u.f->buf) < 1) { 157 | return 1; 158 | } 159 | 160 | switch (f_u.f->flags) { 161 | case FREAD_NULL: 162 | break; 163 | 164 | case FREAD_NONL: 165 | if (f_u.f->buf[strlen(f_u.f->buf) - 1] == '\n') { 166 | f_u.f->buf[strlen(f_u.f->buf) - 1]='\0'; 167 | } 168 | break; 169 | 170 | case FREAD_NOCRNL: 171 | if (strlen(f_u.f->buf) < 2) { 172 | return 1; 173 | } 174 | if (f_u.f->buf[strlen(f_u.f->buf) - 1] == '\n' && f_u.f->buf[strlen(f_u.f->buf) - 2] == '\r') { 175 | f_u.f->buf[strlen(f_u.f->buf) - 2]='\0'; 176 | } 177 | break; 178 | 179 | case FREAD_NOCR: 180 | if (f_u.f->buf[strlen(f_u.f->buf) - 1] == '\r') { 181 | f_u.f->buf[strlen(f_u.f->buf) - 1]='\0'; 182 | } 183 | break; 184 | 185 | default: 186 | ERR("unknown flags `%08x' for fread handle, resetting flags to NULL", f_u.f->flags); 187 | f_u.f->flags=FREAD_NULL; 188 | break; 189 | } 190 | 191 | return 2; 192 | } 193 | 194 | void fread_destroy(void *p) { 195 | union { 196 | void *p; 197 | fread_t *f; 198 | } f_u; 199 | 200 | if (p == NULL) { 201 | return; 202 | } 203 | 204 | f_u.p=p; 205 | 206 | assert(f_u.f->magic == FREAD_MAGIC); 207 | 208 | if (f_u.f->stream != NULL && f_u.f->close > 0) { 209 | fclose(f_u.f->stream); 210 | } 211 | if (f_u.f->gdesc != NULL && f_u.f->close > 0) { 212 | gzclose(f_u.f->gdesc); 213 | } 214 | 215 | if (f_u.f->buf != NULL) { 216 | xfree(f_u.f->buf); 217 | } 218 | 219 | if (f_u.f->fname) { 220 | xfree(f_u.f->fname); 221 | } 222 | 223 | xfree(f_u.p); 224 | 225 | return; 226 | } 227 | 228 | const char *fread_filename(void *p) { 229 | union { 230 | void *p; 231 | fread_t *f; 232 | } f_u; 233 | 234 | if (p == NULL) { 235 | return "NotOpen"; 236 | } 237 | 238 | f_u.p=p; 239 | 240 | assert(f_u.f->magic == FREAD_MAGIC); 241 | 242 | return f_u.f->fname; 243 | } 244 | 245 | unsigned int fread_lineno(void *p) { 246 | union { 247 | void *p; 248 | fread_t *f; 249 | } f_u; 250 | 251 | if (p == NULL) { 252 | return 0U; 253 | } 254 | 255 | f_u.p=p; 256 | 257 | assert(f_u.f->magic == FREAD_MAGIC); 258 | 259 | return f_u.f->lineno; 260 | } 261 | 262 | #ifdef _WRAP_ 263 | 264 | #include 265 | #include 266 | 267 | settings_t *s=NULL; 268 | 269 | int main(int argc, char ** argv) { 270 | int j=0; 271 | void *handle=NULL; 272 | char *buf=NULL; 273 | 274 | s=xmalloc(sizeof(settings_t)); 275 | memset(s, 0, sizeof(settings_t)); 276 | 277 | s->_stdout=stdout; 278 | s->_stderr=stderr; 279 | 280 | for (j=1 ; j < argc ; j++) { 281 | handle=fread_create(argv[j], FREAD_NONL); 282 | if (handle == NULL) { 283 | continue; 284 | } 285 | 286 | while (fread_getline(handle, &buf) > 0) { 287 | printf("Got line `%s' from %s:%u\n", buf, fread_filename(handle), fread_lineno(handle)); 288 | } 289 | fread_destroy(handle); 290 | } 291 | 292 | xfree(s); 293 | exit(0); 294 | } 295 | 296 | #endif 297 | -------------------------------------------------------------------------------- /ext/fread.h: -------------------------------------------------------------------------------- 1 | #ifndef _FREAD_H 2 | # define _FREAD_H 3 | 4 | void *fread_create (const char * /* filename */, int /* flags */); 5 | void *fread_assoc (FILE *, const char * /* filename */, int /* flags */, int /* close FILE on destroy */); 6 | 7 | #define FREAD_NULL 0 8 | #define FREAD_NONL 1 9 | #define FREAD_NOCRNL 2 10 | #define FREAD_NOCR 3 11 | 12 | int fread_getline (void * /* handle */, char ** /* buf */); 13 | void fread_destroy (void * /* handle */); 14 | const char *fread_filename(void * /* handle */); 15 | unsigned int fread_lineno (void * /* handle */); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /ext/hash.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "ext/hash.h" 4 | 5 | inline uint32_t sdbmhash(const void *in, size_t len) { 6 | uint32_t hash=0; 7 | const uint8_t *str=NULL, *end=NULL; 8 | 9 | str=(const uint8_t *)in; 10 | end=str + len; 11 | 12 | for (; str < end; ++str) { 13 | hash=*str + (hash << 6) + (hash << 16) - hash; 14 | } 15 | 16 | return hash; 17 | } 18 | 19 | #if 0 20 | #define SEED8 0x95U 21 | #define SEED_ST 0x55555565U 22 | 23 | uint32_t bkdrjhash(const void *in, size_t len) { 24 | uint32_t hash=SEED_ST; 25 | union { 26 | const uint32_t *w; 27 | const uint8_t *c; 28 | const void *p; 29 | } p_u; 30 | 31 | p_u.p=in; 32 | /* 33 | * try and cheat for the 32 bit speed advantage 34 | * unfortunately it isnt compatible with the original 35 | * hash function 36 | */ 37 | for (; len > sizeof(*p_u.w); ) { 38 | hash *= SEED8; 39 | hash += (*p_u.w & 0xff000000) >> 24; 40 | 41 | hash *= SEED8; 42 | hash += (*p_u.w & 0x00ff0000) >> 16; 43 | 44 | hash *= SEED8; 45 | hash += (*p_u.w & 0x0000ff00) >> 8; 46 | 47 | hash *= SEED8; 48 | hash += (*p_u.w & 0x000000ff); 49 | 50 | p_u.w++; 51 | len -= sizeof(*p_u.w); 52 | } 53 | 54 | for (; len != 0; --len, ++p_u.c) { 55 | hash = (hash * SEED8) + *p_u.c; 56 | } 57 | 58 | return hash; 59 | } 60 | 61 | #endif 62 | 63 | #ifdef _WRAP_ 64 | #include 65 | 66 | inline uint64_t get_tsc(void) { 67 | uint64_t j; 68 | asm volatile ( "rdtsc;" 69 | : "=A" (j) 70 | ); 71 | return j; 72 | } 73 | 74 | 75 | int main(int argc, char ** argv) { 76 | uint64_t a,b,c,d; 77 | uint32_t y,z; 78 | size_t slen=0; 79 | 80 | if (argc != 2) { 81 | printf("bad usage\n"); 82 | exit(1); 83 | } 84 | 85 | slen=strlen(argv[1]); 86 | /* we really need to use this string first, to get it in cache */ 87 | printf("hashing `%s'\n", argv[1]); 88 | 89 | a=get_tsc(); 90 | y=bkdrhash(argv[1], slen); 91 | b=get_tsc(); 92 | 93 | d=get_tsc(); 94 | z=bkdrjhash(argv[1], slen); 95 | c=get_tsc(); 96 | 97 | printf("hashes %08x and %08x (old %llu new %llu)\n", y, z, (b - a), (c - d)); 98 | 99 | exit(0); 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /ext/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef _HASH_H 2 | # define _HASH_H 3 | 4 | uint32_t sdbmhash(const void * /* data */, size_t /* length of data */); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /ext/standard_dns.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "ext/xmalloc.h" 4 | #include "ext/cidr.h" 5 | #include "standard_dns.h" 6 | #include "misc.h" 7 | #include "main.h" 8 | 9 | #define STDDNS_MAGIC 0xed01dda6 10 | 11 | typedef struct stddns_context_t { 12 | uint32_t magic; 13 | void (*fp)(int, const void *, const void *); 14 | int flags; 15 | } stddns_context_t; 16 | 17 | void *stddns_init(void (*callback)(int /* type */, const void *, const void *), int flags) { 18 | stddns_context_t *sc=NULL; 19 | 20 | sc=xmalloc(sizeof(stddns_context_t)); 21 | sc->magic=STDDNS_MAGIC; 22 | sc->fp=callback; 23 | sc->flags=flags; 24 | 25 | return (void *)sc; 26 | } 27 | 28 | /* 29 | * returns the hostname or NULL if not found 30 | */ 31 | char *stddns_getname(void *c, const struct sockaddr *is) { 32 | socklen_t sl=0; 33 | int ret=0; 34 | static char hname[2048]; 35 | union { 36 | const struct sockaddr *p; 37 | struct f_s *fs; 38 | } is_u; 39 | union { 40 | stddns_context_t *c; 41 | void *p; 42 | } c_u; 43 | 44 | 45 | if (is == NULL || c == NULL) { 46 | return NULL; 47 | } 48 | 49 | c_u.p=c; 50 | assert(c_u.c->magic == STDDNS_MAGIC); 51 | 52 | is_u.p=is; 53 | 54 | memset(hname, 0, sizeof(hname)); 55 | 56 | switch (is_u.fs->family) { 57 | case AF_INET: 58 | sl=(socklen_t )sizeof(struct sockaddr_in); 59 | break; 60 | 61 | case AF_INET6: 62 | sl=(socklen_t )sizeof(struct sockaddr_in6); 63 | break; 64 | 65 | default: 66 | break; 67 | } 68 | 69 | ret=getnameinfo(is, sl, hname, sizeof(hname), NULL /* service */, 0, NI_NAMEREQD); 70 | 71 | if (ret == 0) { 72 | if (strlen(hname) > 0) { 73 | return hname; 74 | } 75 | ERR("whoa, no name?"); 76 | return NULL; 77 | } 78 | 79 | #ifdef EAI_NODATA 80 | if (ret != EAI_NONAME && ret != EAI_NODATA) { 81 | #else 82 | if (ret != EAI_NONAME) { 83 | #endif 84 | ERR("getnameinfo fails: %s [%d]", gai_strerror(ret), ret); 85 | } 86 | 87 | return NULL; 88 | } 89 | 90 | /* 91 | * returns 0 if nothing found 92 | */ 93 | int stddns_getname_cb(void *c, const struct sockaddr *is) { 94 | socklen_t sl=0; 95 | static char hname[2048]; 96 | union { 97 | const struct sockaddr *p; 98 | struct f_s *fs; 99 | } s_u; 100 | union { 101 | void *p; 102 | stddns_context_t *c; 103 | } c_u; 104 | int ret=0; 105 | 106 | if (is == NULL || c == NULL) { 107 | return -1; 108 | } 109 | c_u.p=c; 110 | 111 | assert(c_u.c->magic == STDDNS_MAGIC); 112 | assert(c_u.c->fp != NULL); 113 | 114 | s_u.p=is; 115 | 116 | memset(hname, 0, sizeof(hname)); 117 | 118 | switch (s_u.fs->family) { 119 | case AF_INET: 120 | sl=(socklen_t )sizeof(struct sockaddr_in); 121 | break; 122 | 123 | case AF_INET6: 124 | sl=(socklen_t )sizeof(struct sockaddr_in6); 125 | break; 126 | 127 | default: 128 | ERR("Unknown address family %d", s_u.fs->family); 129 | return 0; 130 | } 131 | 132 | ret=getnameinfo(is, sl, hname, sizeof(hname), NULL /* service */, 0, NI_NAMEREQD); 133 | 134 | if (ret == 0) { 135 | if (strlen(hname) > 0) { 136 | c_u.c->fp(OUTPUT_REVERSE, (const void *)is, (const void *)hname); 137 | return 1; 138 | } 139 | ERR("whoa, no name?"); 140 | return 0; 141 | } 142 | 143 | #ifdef EAI_NODATA 144 | if (ret != EAI_NONAME && ret != EAI_NODATA) { 145 | #else 146 | if (ret != EAI_NONAME) { 147 | #endif 148 | ERR("getnameinfo fails: %s [%d]", gai_strerror(ret), ret); 149 | } 150 | 151 | return 0; 152 | } 153 | 154 | /* 155 | */ 156 | sockaddr_list_t **stddns_getaddr(void *c, const char *name) { 157 | struct addrinfo *ret=NULL, *walk=NULL; 158 | struct addrinfo hint; 159 | int iret=0; 160 | unsigned int cnt=0, idx=0; 161 | union { 162 | struct sockaddr *p; 163 | struct sockaddr_in *sin; 164 | struct sockaddr_in6 *s6in; 165 | } s_u, s2_u; 166 | union { 167 | void *p; 168 | stddns_context_t *c; 169 | } c_u; 170 | sockaddr_list_t **sl=NULL; 171 | char *sstring=NULL, *ename=NULL; 172 | 173 | if (name == NULL || c == NULL) { 174 | return NULL; 175 | } 176 | 177 | c_u.p=c; 178 | 179 | assert(c_u.c->magic == STDDNS_MAGIC); 180 | 181 | memset(&hint, 0, sizeof(hint)); 182 | 183 | hint.ai_family=PF_UNSPEC; 184 | if (s->ipv4_lookup != s->ipv6_lookup) { 185 | if (s->ipv4_lookup == 1 && s->ipv6_lookup == 0) { 186 | hint.ai_family=AF_INET; 187 | } 188 | else { 189 | hint.ai_family=AF_INET6; 190 | } 191 | } 192 | 193 | if (s->exact) { 194 | hint.ai_flags=AI_CANONNAME; 195 | } 196 | 197 | if (name == NULL || strlen(name) < 1) { 198 | return NULL; 199 | } 200 | 201 | if ((iret=getaddrinfo(name, NULL, &hint, &ret)) != 0) { 202 | #ifdef EAI_NODATA 203 | if (iret != EAI_NONAME && iret != EAI_NODATA) { 204 | #else 205 | if (iret != EAI_NONAME) { 206 | #endif 207 | ERR("getaddrinfo errors for name `%s': %s", name, gai_strerror(iret)); 208 | } 209 | DBG("getaddrinfo fails for %s", name); 210 | return NULL; 211 | } 212 | 213 | for (walk=ret; walk != NULL; walk=walk->ai_next) { 214 | cnt++; 215 | assert(cnt < 9999); 216 | } 217 | DBG("got %u awnsers for %s", cnt, name); 218 | 219 | cnt++; 220 | 221 | sl=(sockaddr_list_t **)xmalloc(sizeof(sockaddr_list_t *) * cnt); 222 | 223 | for (idx=0, walk=ret; walk != NULL; walk=walk->ai_next, idx++) { 224 | 225 | sl[idx]=(sockaddr_list_t *)xmalloc(sizeof(sockaddr_list_t)); 226 | 227 | memset(&sl[idx]->s_u.s, 0, sizeof(struct sockaddr)); 228 | 229 | s_u.p=&sl[idx]->s_u.s; 230 | s2_u.p=walk->ai_addr; 231 | 232 | if (s->verbose > 4) { 233 | hexdump((const uint8_t *)walk->ai_addr, 16); 234 | } 235 | 236 | /* XXX we dont get all the cnames this way */ 237 | sstring=cidr_saddrstr(walk->ai_addr); 238 | DBG("index %u for name `%s' ai_flags %d ai_family %d ai_socktype %d ai_protocol %d ai_addrlen %zu ai_addr %p (%s) ai_canonname %s ai_next %p\n", idx, name, walk->ai_flags, walk->ai_family, walk->ai_socktype, walk->ai_protocol, walk->ai_addrlen, walk->ai_addr, sstring != NULL ? sstring : "Nothing", walk->ai_canonname != NULL ? walk->ai_canonname : "Null", walk->ai_next); 239 | 240 | if (ename == NULL && s->exact && walk->ai_canonname != NULL) { 241 | ename=walk->ai_canonname; 242 | DBG("setting ename to `%s' from `%s'", ename, name); 243 | } 244 | 245 | switch (walk->ai_family) { 246 | case AF_INET: 247 | s_u.sin->sin_addr.s_addr=s2_u.sin->sin_addr.s_addr; 248 | s_u.sin->sin_family=walk->ai_family; 249 | break; 250 | 251 | case AF_INET6: 252 | memcpy(&s_u.s6in->sin6_addr.s6_addr[0], &s2_u.s6in->sin6_addr.s6_addr[0], (128 / 8)); 253 | s_u.s6in->sin6_family=walk->ai_family; 254 | break; 255 | 256 | default: 257 | ERR("unknown address family %d", walk->ai_family); 258 | break; 259 | } 260 | if (ename != NULL) { 261 | sl[idx]->ename=xstrdup(ename); 262 | } 263 | } 264 | 265 | sl[idx]=NULL; 266 | 267 | if (ret != NULL) { 268 | freeaddrinfo(ret); 269 | } 270 | 271 | return sl; 272 | } 273 | 274 | /* 275 | */ 276 | int stddns_getaddr_cb(void *c, const char *name) { 277 | struct addrinfo *ret=NULL, *walk=NULL; 278 | struct addrinfo hint; 279 | int iret=0; 280 | unsigned int idx=0; 281 | char *sstring=NULL, *ename=NULL; 282 | union { 283 | void *p; 284 | stddns_context_t *c; 285 | } c_u; 286 | 287 | if (name == NULL || c == NULL) { 288 | return -1; 289 | } 290 | 291 | c_u.p=c; 292 | 293 | assert(c_u.c->magic == STDDNS_MAGIC); 294 | assert(c_u.c->fp != NULL); 295 | 296 | memset(&hint, 0, sizeof(hint)); 297 | 298 | if (s->ipv4_lookup != s->ipv6_lookup) { 299 | if (s->ipv4_lookup == 1 && s->ipv6_lookup == 0) { 300 | hint.ai_family=AF_INET; 301 | } 302 | else { 303 | hint.ai_family=AF_INET6; 304 | } 305 | } 306 | 307 | if (s->exact) { 308 | hint.ai_flags=AI_CANONNAME; 309 | } 310 | 311 | if (name == NULL || strlen(name) < 1) { 312 | return 0; 313 | } 314 | 315 | if ((iret=getaddrinfo(name, NULL, &hint, &ret)) != 0) { 316 | #ifdef EAI_NODATA 317 | if (iret != EAI_NONAME && iret != EAI_NODATA) { 318 | #else 319 | if (iret != EAI_NONAME) { 320 | #endif 321 | ERR("getaddrinfo errors for name `%s': %s", name, gai_strerror(iret)); 322 | } 323 | DBG("getaddrinfo fails for %s", name); 324 | return 0; 325 | } 326 | 327 | for (idx=0, walk=ret; walk != NULL; walk=walk->ai_next, idx++) { 328 | 329 | /* XXX we dont get all the cnames this way */ 330 | sstring=cidr_saddrstr(walk->ai_addr); 331 | DBG("index %u for name `%s' ai_flags %d ai_family %d ai_socktype %d ai_protocol %d ai_addrlen %zu ai_addr %p (%s) ai_canonname %s ai_next %p\n", idx, name, walk->ai_flags, walk->ai_family, walk->ai_socktype, walk->ai_protocol, walk->ai_addrlen, walk->ai_addr, sstring != NULL ? sstring : "Nothing", walk->ai_canonname != NULL ? walk->ai_canonname : "Null", walk->ai_next); 332 | 333 | if (ename == NULL && s->exact == 1 && walk->ai_canonname != NULL) { 334 | 335 | ename=xstrdup(walk->ai_canonname); 336 | DBG("setting ename to `%s' from `%s'", ename, name); 337 | 338 | /* 339 | * this is a little weird, we need to check that we arent 340 | * blabbering on about cnames for wildcard hosts, so we will 341 | * manually check this fact 342 | */ 343 | if (check_wildcard(walk->ai_addr) == 1) { 344 | continue; 345 | } 346 | c_u.c->fp(OUTPUT_ALIAS, name, ename); 347 | } 348 | 349 | c_u.c->fp(OUTPUT_FORWARD, ename != NULL ? ename : name, walk->ai_addr); 350 | } 351 | 352 | if (ret != NULL) { 353 | freeaddrinfo(ret); 354 | } 355 | 356 | return 1; 357 | } 358 | 359 | void stddns_freeaddr(void *c, struct sockaddr_list_t ***in) { 360 | unsigned int j=0; 361 | union { 362 | void *p; 363 | stddns_context_t *c; 364 | } c_u; 365 | 366 | assert(in != NULL && c != NULL); 367 | 368 | c_u.p=c; 369 | 370 | assert(c_u.c->magic == STDDNS_MAGIC); 371 | 372 | for (j=0; (*in)[j] != NULL; j++) { 373 | if ((*in)[j]->ename != NULL) { 374 | DBG("free %p\n", (*in)[j]->ename); 375 | xfree((*in)[j]->ename); 376 | (*in)[j]->ename=NULL; 377 | } 378 | xfree((*in)[j]); 379 | } 380 | 381 | xfree(*in); 382 | *in=NULL; 383 | 384 | return; 385 | } 386 | 387 | void stddns_fini(void **p) { 388 | union { 389 | void *p; 390 | stddns_context_t *c; 391 | } c_u; 392 | 393 | c_u.p=*p; 394 | 395 | if (p == NULL || *p == NULL) { 396 | return; 397 | } 398 | 399 | assert(c_u.c->magic == STDDNS_MAGIC); 400 | xfree(*p); 401 | *p=NULL; 402 | 403 | return; 404 | } 405 | -------------------------------------------------------------------------------- /ext/standard_dns.h: -------------------------------------------------------------------------------- 1 | #ifndef _STANDARD_DNS_H 2 | # define _STANDARD_DNS_H 3 | 4 | typedef struct sockaddr_list_t { 5 | union { 6 | struct f_s fs; 7 | struct sockaddr s; 8 | struct sockaddr_in sin; 9 | struct sockaddr_in6 sin6; 10 | } s_u; 11 | char *ename; 12 | } sockaddr_list_t; 13 | 14 | /* 15 | * returns context or NULL on failure 16 | * callback may be NULL, but take care not to call any of the *_cb functions 17 | * callback is a function that: 18 | * first argument is type "type" of data being sent to the callback, 19 | * and the 2 following arguments are the subject and result respectively 20 | */ 21 | extern void *stddns_init(void (* /* callback */)(int, const void *, const void *), int /* flags */); 22 | 23 | #define STDDNS_FLG_IPV4 1 24 | #define STDDNS_FLG_IPV6 2 25 | #define STDDNS_FLG_EXACT 4 26 | 27 | /* 28 | * returns the hostname or NULL if not found 29 | */ 30 | extern char *stddns_getname(void * /* context */, const struct sockaddr *); 31 | 32 | /* 33 | * returns 0 if nothing matched 34 | */ 35 | int stddns_getname_cb(void * /* context */, const struct sockaddr *); 36 | 37 | /* 38 | * writes the address family and struct sockaddr * for name, 39 | * returns 1 for sucess or something else on failure 40 | */ 41 | sockaddr_list_t **stddns_getaddr(void * /* context */, const char *); 42 | 43 | /* 44 | * returns 0 if nothing matched 45 | */ 46 | int stddns_getaddr_cb(void * /* context */, const char *); 47 | 48 | /* 49 | */ 50 | void stddns_freeaddr(void * /* context */, struct sockaddr_list_t ***); 51 | 52 | extern void stddns_fini(void ** /* pointer to context */); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /ext/xmalloc.c: -------------------------------------------------------------------------------- 1 | _xdebug.c -------------------------------------------------------------------------------- /ext/xmalloc.h: -------------------------------------------------------------------------------- 1 | _xdebug.h -------------------------------------------------------------------------------- /getopts.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "ext/xmalloc.h" 4 | 5 | #include "getopts.h" 6 | 7 | #define GETOPT "4" "6" "a:" "b:" "c:" "d" "e" "D" "f:" "F" "h" "H:" "r" "s" "S" "v" "V" 8 | 9 | static void display_version(void) __attribute__((noreturn)); 10 | 11 | int get_opts_argv(int argc, char **argv) { 12 | extern char *optarg; 13 | extern int optind; 14 | char bob[128]; 15 | int ch=0, j=0; 16 | unsigned int idx=0; 17 | 18 | while ((ch=getopt(argc, argv, GETOPT)) != -1) { 19 | switch (ch) { 20 | case '4': /* XXX */ 21 | if (set_addrfam("ipv4") != 1) { 22 | usage(); 23 | } 24 | break; 25 | 26 | case '6': /* XXX */ 27 | if (set_addrfam("ipv6") != 1) { 28 | usage(); 29 | } 30 | break; 31 | 32 | case 'a': 33 | #if HAVE_C_ARES == 1 34 | if (set_async(optarg) != 1) { 35 | usage(); 36 | } 37 | #else 38 | ERR("No async dns support compiled in"); 39 | usage(); 40 | #endif 41 | break; 42 | 43 | case 'b': 44 | memset(bob, 0, sizeof(bob)); 45 | strcat(bob, "brute-"); 46 | strncat(bob, optarg, sizeof(bob) - 7 /* brute- + STR + \0 */); 47 | if (set_mode(bob) != 1) { 48 | usage(); 49 | } 50 | break; 51 | 52 | case 'c': 53 | if (set_allowed(optarg) != 1) { 54 | usage(); 55 | } 56 | break; 57 | 58 | case 'd': 59 | if (set_discover(1) != 1) { 60 | usage(); 61 | } 62 | break; 63 | 64 | case 'D': 65 | if (set_mode("dict") != 1) { 66 | usage(); 67 | } 68 | break; 69 | 70 | case 'e': 71 | if (set_exact(1) != 1) { 72 | usage(); 73 | } 74 | break; 75 | 76 | case 'f': 77 | if (set_dictfile(optarg) != 1) { 78 | usage(); 79 | } 80 | break; 81 | 82 | case 'F': 83 | if (set_filter(0) != 1) { 84 | usage(); 85 | } 86 | break; 87 | 88 | case 'H': 89 | if (set_sillyhostname(optarg) != 1) { 90 | usage(); 91 | } 92 | break; 93 | 94 | case 'r': 95 | if (set_mode("rev") != 1) { 96 | usage(); 97 | } 98 | break; 99 | 100 | case 's': 101 | if (set_outsql(1) != 1) { 102 | usage(); 103 | } 104 | break; 105 | 106 | case 'S': 107 | if (set_async("no") != 1) { 108 | usage(); 109 | } 110 | break; 111 | 112 | case 'v': 113 | if (set_verbose(s->verbose + 1) != 1) { 114 | usage(); 115 | } 116 | break; 117 | 118 | case 'V': 119 | display_version(); 120 | break; 121 | 122 | case 'h': 123 | /* fall though */ 124 | default: 125 | usage(); 126 | } /* switch */ 127 | } 128 | 129 | assert(argc >= optind); 130 | 131 | if (argc - optind == 0) { 132 | ERR("nothing to lookup! (-h for help)"); 133 | exit(1); 134 | } 135 | 136 | memset(s->targets, 0, sizeof(char *) * MAX_TARGETS); 137 | 138 | assert(MAX_TARGETS > (argc - optind)); 139 | 140 | for ( j=optind; j < argc; j++) { 141 | s->targets[idx++]=xstrdup(argv[j]); 142 | } 143 | 144 | s->targets[idx]=NULL; 145 | 146 | return 1; 147 | } 148 | 149 | static void display_version(void) { 150 | OUT("%s %s", PROGNAME, PACKAGE_VERSION); 151 | exit(0); 152 | } 153 | 154 | void usage(void) { 155 | 156 | OUT("Usage: %s (%s %s)\n" 157 | "\t-4\t only scan ipv4 forward lookups\n" 158 | "\t-6\t only scan ipv6 lookups\n" 159 | "\t-a\t* async mode (if compiled in) with a numeric argument of concurrency (%u default)\n" 160 | "\t-b\t* brute force hostnames from X to Y chars (x-y)\n" 161 | "\t-c\t* characters allowed in brute force mode\n" 162 | "\t-d\t discover more information based upon found information\n" 163 | "\t-D\t dictionary mode (default)\n" 164 | "\t-e\t exact information returned is displayed, not asked for information\n" 165 | "\t-f\t* wordlist to lookup hosts from\n" 166 | "\t-F\t do not filter output for unique results\n" 167 | "\t-h\t help (you are here)\n" 168 | "\t-H\t* silly hostname to use to detect wildcards (otherwise itll be random)\n" 169 | "\t-r\t reverse dns scan mode\n" 170 | "\t-s\t SQL output mode\n" 171 | "\t-S\t force SYNC scanning mode (if async mode is available, it is default)\n" 172 | "\t-v\t verbose (more for more)\n" 173 | "\t-V\t display program version\n" 174 | , GETOPT, PROGNAME, PACKAGE_VERSION, DEF_CONCURRENCY); 175 | 176 | exit(0); 177 | } 178 | 179 | int set_allowed(const char *str) { 180 | 181 | if (str == NULL || strlen(str) < 1) { 182 | return -1; 183 | } 184 | 185 | if (s->allowed != NULL) { 186 | xfree(s->allowed); 187 | } 188 | s->allowed=xstrdup(str); 189 | 190 | return 1; 191 | } 192 | 193 | int set_sillyhostname(const char *name) { 194 | 195 | if (name == NULL || strlen(name) < 1) { 196 | return -1; 197 | } 198 | 199 | if (s->sillyhostname != NULL) { 200 | xfree(s->sillyhostname); 201 | } 202 | s->sillyhostname=xstrdup(name); 203 | 204 | return 1; 205 | } 206 | 207 | int set_addrfam(const char *addrfams) { 208 | 209 | s->ipv4_lookup=0; 210 | s->ipv6_lookup=0; 211 | 212 | if (addrfams == NULL || strlen(addrfams) < 1) { 213 | ERR("no address family to set, use ipv4|ipv6|ipv46"); 214 | return -1; 215 | } 216 | 217 | if (strcasecmp(addrfams, "ipv4") == 0) { 218 | s->ipv4_lookup=1; 219 | } 220 | else if (strcasecmp(addrfams, "ipv6") == 0) { 221 | s->ipv6_lookup=1; 222 | } 223 | else if (strcasecmp(addrfams, "ipv46") == 0 || strcasecmp(addrfams, "all") == 0) { 224 | s->ipv4_lookup=s->ipv6_lookup=1; 225 | } 226 | else { 227 | ERR("unknown address family `%s', try ipv4|ipv6|ipv46", addrfams); 228 | return -1; 229 | } 230 | 231 | return 1; 232 | } 233 | 234 | int set_mode(const char *bstr) { 235 | 236 | assert(bstr != NULL); 237 | 238 | if (sscanf(bstr, "brute-%d-%d", &s->brute_lenmin, &s->brute_lenmax) == 2) { 239 | if (s->brute_lenmin > s->brute_lenmax) { 240 | int tmp=0; 241 | 242 | tmp=s->brute_lenmax; 243 | s->brute_lenmax=s->brute_lenmin; 244 | s->brute_lenmin=tmp; 245 | } 246 | 247 | if (s->brute_lenmax < 1 || s->brute_lenmin < 1) { 248 | ERR("bad brute length parameters"); 249 | return -1; 250 | } 251 | if (s->brute_lenmax > MAX_BRUTELEN) { 252 | ERR("who has that much time?"); 253 | return -1; 254 | } 255 | s->mode=MODE_BRUTE; 256 | } 257 | else if (sscanf(bstr, "brute-%d", &s->brute_lenmax) == 1) { 258 | s->brute_lenmin=1; 259 | if (s->brute_lenmax < 1) { 260 | ERR("brute length is less than one"); 261 | return -1; 262 | } 263 | 264 | /* else could be assumed ;] */ 265 | if (s->brute_lenmax > MAX_BRUTELEN) { 266 | ERR("who has that much time?"); 267 | return -1; 268 | } 269 | s->mode=MODE_BRUTE; 270 | } 271 | else if (strcmp(bstr, "dict") == 0 || strcmp(bstr, "dictionary") == 0) { 272 | s->mode=MODE_DICT; 273 | } 274 | else if (strcmp(bstr, "rev") == 0 || strcmp(bstr, "reverse") == 0) { 275 | s->mode=MODE_REVERSE; 276 | } 277 | else { 278 | ERR("unknown mode `%s'", bstr); 279 | return -1; 280 | } 281 | 282 | return 1; 283 | } 284 | 285 | int set_dictfile(const char *in) { 286 | 287 | if (in == NULL || strlen(in) < 1) { 288 | return -1; 289 | } 290 | 291 | if (s->dictfile != NULL) { 292 | xfree(s->dictfile); 293 | } 294 | 295 | s->dictfile=xstrdup(in); 296 | 297 | return 1; 298 | } 299 | 300 | int set_async(const char *str) { 301 | 302 | if (str == NULL || strlen(str) < 1) { 303 | ERR("bad sync|async input, try no|number"); 304 | return -1; 305 | } 306 | 307 | if (strcasecmp(str, "no") == 0) { 308 | s->async=0; 309 | } 310 | else { 311 | if (sscanf(str, "%u", &s->concurrency) != 1) { 312 | ERR("bad number for async concurrency"); 313 | return -1; 314 | } 315 | if (s->concurrency < 2) { 316 | ERR("concurrency should be > 1, otherwise dont use it"); 317 | return -1; 318 | } 319 | if (s->concurrency > 256) { 320 | ERR("concurrency too large!"); 321 | s->concurrency=DEF_CONCURRENCY; 322 | return -1; 323 | } 324 | s->async=1; 325 | } 326 | 327 | return 1; 328 | } 329 | 330 | int set_exact(int yesno) { 331 | 332 | s->exact=yesno; 333 | 334 | return 1; 335 | } 336 | 337 | int set_filter(int yesno) { 338 | 339 | s->filter_unique=yesno; 340 | 341 | return 1; 342 | } 343 | 344 | int set_discover(int yesno) { 345 | 346 | s->discover=1; 347 | 348 | return 1; 349 | } 350 | 351 | int set_outsql(int yesno) { 352 | 353 | s->output_sql=yesno; 354 | 355 | return 1; 356 | } 357 | 358 | int set_verbose(int level) { 359 | 360 | s->verbose=level; 361 | 362 | return 1; 363 | } 364 | -------------------------------------------------------------------------------- /getopts.h: -------------------------------------------------------------------------------- 1 | #ifndef _GET_OPTS_H 2 | # define _GET_OPTS_H 3 | 4 | void usage(void) __attribute__((noreturn)); 5 | int get_opts_argv(int , char **); 6 | 7 | int set_sillyhostname(const char *); 8 | int set_mode(const char *); 9 | int set_allowed(const char *); 10 | int set_async(const char *); 11 | int set_addrfam(const char *); 12 | int set_dictfile(const char *); 13 | 14 | int set_exact(int ); 15 | int set_filter(int ); 16 | int set_discover(int ); 17 | int set_outsql(int ); 18 | int set_verbose(int ); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /libs/c-ares: -------------------------------------------------------------------------------- 1 | http://daniel.haxx.se/projects/c-ares/ 2 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "main.h" 4 | #include "getopts.h" 5 | #include "ext/xmalloc.h" 6 | #include "ext/fread.h" 7 | #include "ext/cidr.h" 8 | #include "ext/chtbl.h" 9 | #include "ext/hash.h" 10 | #include "ext/standard_dns.h" 11 | #include "readconf.h" 12 | #include "myadns.h" 13 | #include "misc.h" 14 | 15 | static void display_output(int /* family */, const char * /* hostname */, const char * /* addr string */); 16 | static void display_routput(int /* family */, const char * /* address */, const char * /* hostname */); 17 | static void display_alias(const char * /* cname */, const char * /* real hname */); 18 | static void display_output_cb(int /* type */, const void *, const void *); 19 | 20 | /* 21 | * for forward lookups, use this function to find a default host thats returned 22 | */ 23 | static void get_wildcard(void); 24 | static char *get_sillyhostname(void); 25 | 26 | static void do_brute(void); 27 | static void do_dict(void); 28 | static void do_reverse(void); 29 | static void do_lookup(const char *); 30 | static void do_revlookup(const struct sockaddr *); 31 | static void do_gather(int /* wait for all = 1 otherwise 0 for free slot */); 32 | 33 | /* 34 | * use during brute force 35 | */ 36 | static void init_charlist(void); 37 | static int inc_char(char *); 38 | 39 | settings_t *s=NULL; 40 | static void *sc=NULL; 41 | 42 | int main(int argc, char **argv) { 43 | unsigned int j=0; 44 | int sd_flags=0; 45 | 46 | s=(struct settings_t *)xmalloc(sizeof(settings_t)); 47 | memset(s, 0, sizeof(*s)); 48 | 49 | set_addrfam("ipv46"); 50 | set_mode("dict"); 51 | set_allowed(DEF_BRUTECHARS); 52 | #if HAVE_C_ARES == 1 53 | s->async=1; 54 | #endif 55 | s->concurrency=DEF_CONCURRENCY; 56 | s->dictfile=xstrdup(SHAREDIR "/default"); 57 | s->filter_unique=1; 58 | s->exact=0; 59 | 60 | readconf(DEF_CONFFILE); 61 | 62 | get_opts_argv(argc, argv); 63 | 64 | if (s->filter_unique) { 65 | s->uniq=chtinit(0xffff); 66 | } 67 | 68 | if (s->sillyhostname == NULL) { 69 | s->sillyhostname=xstrdup(get_sillyhostname()); 70 | } 71 | 72 | if (s->mode == MODE_BRUTE) { 73 | DBG("brute length from %d to %d with allowed `%s'", s->brute_lenmin, s->brute_lenmax, s->allowed); 74 | } 75 | 76 | sd_flags=0; 77 | if (s->ipv6_lookup) { 78 | DBG("looking up ipv6 records"); 79 | sd_flags |= STDDNS_FLG_IPV6; 80 | } 81 | if (s->ipv4_lookup) { 82 | DBG("Looking up ipv4 records"); 83 | sd_flags |= STDDNS_FLG_IPV4; 84 | } 85 | if (s->exact) { 86 | DBG("exact mode enabled"); 87 | sd_flags |= STDDNS_FLG_EXACT; 88 | } 89 | 90 | /* 91 | * you never know ;] 92 | */ 93 | if (s->ipv4_lookup == s->ipv6_lookup && s->ipv4_lookup == 0) { 94 | ERR("well that was fast wasnt it? (no address families to look up)"); 95 | exit(1); 96 | } 97 | 98 | #if HAVE_C_ARES == 1 99 | if (s->async) { 100 | myadns_init(display_output_cb, s->concurrency); 101 | } 102 | #endif 103 | 104 | sc=stddns_init(display_output_cb, sd_flags); 105 | 106 | s->start=time(NULL); 107 | 108 | for (j=0; s->targets[j] != NULL; j++) { 109 | 110 | s->cur_target=s->targets[j]; 111 | 112 | if (s->mode == MODE_REVERSE) { 113 | int af=0; 114 | 115 | af=cidr_get(s->cur_target, (struct sockaddr *)&s->netid, (struct sockaddr *)&s->netmask, &s->cmask); 116 | if (af < 0) { 117 | ERR("sorry, i dont understand `%s' for reverse dns sweep", s->cur_target); 118 | continue; 119 | } 120 | else if (af == AF_INET) { 121 | s->ipv4_lookup=1; s->ipv6_lookup=0; 122 | } 123 | else if (af == AF_INET6) { 124 | s->ipv4_lookup=0; s->ipv6_lookup=1; 125 | } 126 | else { 127 | ERR("cidr is broken, this is a bug, skipping this sweep"); 128 | continue; 129 | } 130 | } 131 | 132 | switch (s->mode) { 133 | case MODE_BRUTE: 134 | if (s->verbose) { 135 | OUT("brute force mode length %d to %d with characters `%s'", s->brute_lenmin, s->brute_lenmax, s->allowed); 136 | } 137 | do_lookup(s->cur_target); 138 | get_wildcard(); 139 | do_brute(); 140 | break; 141 | 142 | case MODE_REVERSE: 143 | if (s->verbose) { 144 | char *net=NULL; 145 | 146 | net=cidr_saddrstr((const struct sockaddr *)&s->netid); 147 | if (net == NULL) { 148 | ERR("cant convert network sockaddr to string"); 149 | exit(1); 150 | } 151 | OUT("Reverse dns sweep mode on net %s/%u", net, s->cmask); 152 | } 153 | if (s->discover) { 154 | get_wildcard(); 155 | } 156 | do_reverse(); 157 | break; 158 | 159 | case MODE_DICT: 160 | if (s->verbose) { 161 | OUT("Dictionary mode using file `%s'", s->dictfile); 162 | } 163 | do_lookup(s->cur_target); 164 | get_wildcard(); 165 | do_dict(); 166 | break; 167 | 168 | default: 169 | ERR("unknown mode %d", s->mode); 170 | break; 171 | } /* mode switch */ 172 | 173 | #if HAVE_C_ARES == 1 174 | if (s->async) { 175 | do_gather(1); 176 | } 177 | 178 | xfree(s->targets[j]); 179 | s->targets[j]=NULL; 180 | #endif 181 | } /* targets in list */ 182 | 183 | #if HAVE_C_ARES == 1 184 | if (s->async) { 185 | myadns_fini(); 186 | } 187 | #endif 188 | 189 | stddns_fini(&sc); 190 | 191 | if (s->uniq != NULL) { 192 | chtdestroy(s->uniq); 193 | } 194 | 195 | if (s->verbose) { 196 | int secs=0; 197 | float qps=0; 198 | 199 | secs=time(NULL) - s->start; 200 | 201 | qps=(float )s->lookups / (float )(secs != 0 ? secs : 1); 202 | 203 | OUT("%u lookups total in %d seconds (%.02f QPS) with %u replies", s->lookups, secs, qps, s->replies); 204 | 205 | } 206 | 207 | if (s->allowed != NULL) { 208 | xfree(s->allowed); 209 | } 210 | 211 | if (s->sillyhostname != NULL) { 212 | xfree(s->sillyhostname); 213 | } 214 | 215 | if (s->dictfile != NULL) { 216 | xfree(s->dictfile); 217 | } 218 | 219 | if (s->wc_list) { 220 | stddns_freeaddr(s->wc_sc, &s->wc_list); 221 | } 222 | 223 | xfree(s); 224 | 225 | exit(0); 226 | } 227 | 228 | static void do_brute(void) { 229 | char fqhn[NBUF_LEN]; 230 | char str[MAX_BRUTELEN + 1]; 231 | int j=0; 232 | 233 | init_charlist(); 234 | 235 | assert(s->brute_lenmax < MAX_BRUTELEN && s->brute_lenmax > 0); 236 | assert(s->brute_lenmin < MAX_BRUTELEN && s->brute_lenmin > 0); 237 | 238 | memset(str, 0, sizeof(str)); 239 | 240 | str[0]=s->allowed[0]; 241 | if (s->brute_lenmin > 1) { 242 | memset(str, s->allowed[strlen(s->allowed) - 1], s->brute_lenmin - 1); 243 | } 244 | 245 | for (;;) { 246 | snprintf(fqhn, sizeof(fqhn) -1, "%s.%s.", str, s->cur_target); 247 | 248 | do_lookup(fqhn); 249 | 250 | for (j=0 ; j < s->brute_lenmax ; j++) { 251 | if (inc_char(&str[j]) == 0) { 252 | break; 253 | } 254 | DBG("ok, inc'ing to next char in string"); 255 | } 256 | if (j == s->brute_lenmax) { 257 | break; 258 | } 259 | } 260 | 261 | return; 262 | } 263 | 264 | static void do_reverse(void) { 265 | struct sockaddr_storage mysin; 266 | 267 | memcpy(&mysin, &s->netid, sizeof(mysin)); 268 | 269 | #ifdef HAVE_STRUCT_SOCKADDR_LEN 270 | mysin.ss_len=s->netid.ss_len; 271 | #endif 272 | 273 | for (;;) { 274 | do_revlookup((const struct sockaddr *)&mysin); 275 | if (cidr_inchost((struct sockaddr *)&mysin, (struct sockaddr *)&s->netid, (struct sockaddr *)&s->netmask) != 1) { 276 | break; 277 | } 278 | if (cidr_within((struct sockaddr *)&mysin, (struct sockaddr *)&s->netid, (struct sockaddr *)&s->netmask) != 1) { 279 | break; 280 | } 281 | } 282 | 283 | return; 284 | } 285 | 286 | static void do_revlookup(const struct sockaddr *si) { 287 | char *addr_str=NULL; 288 | #if HAVE_C_ARES == 1 289 | int ret=0; 290 | #endif 291 | 292 | s->lookups++; 293 | 294 | addr_str=cidr_saddrstr(si); 295 | 296 | DBG("Looking up `%s'", addr_str != NULL ? addr_str : "Error"); 297 | 298 | #if HAVE_C_ARES == 1 299 | if (s->async) { 300 | for (;;) { 301 | ret=myadns_revlookup(si); 302 | if (ret == 1 || ret < 0) { 303 | if (ret < 0) { 304 | ERR("adns forward lookup fails with code %d", ret); 305 | } 306 | break; 307 | } 308 | do_gather(0); 309 | } 310 | 311 | return; 312 | } 313 | #endif 314 | 315 | (void )stddns_getname_cb(sc, si); 316 | 317 | return; 318 | } 319 | 320 | static void do_gather(int wait) { 321 | #if HAVE_C_ARES == 1 322 | int ret=0; 323 | 324 | DBG("in do gather"); 325 | for (;;) { 326 | if (s->verbose > 4) { 327 | myadns_track_dump(); 328 | } 329 | 330 | ret=myadns_gather(); 331 | if (wait == 0 && ret == 1) { 332 | break; 333 | } 334 | if (ret == 2 || ret < 0) { 335 | if (ret < 0) { 336 | ERR("adns_gather fails! error %d", ret); 337 | } 338 | break; 339 | } 340 | } 341 | DBG("out do gather"); 342 | 343 | return; 344 | #else 345 | ERR("gather called with no adns support"); 346 | #endif 347 | } 348 | 349 | static void do_dict(void) { 350 | void *d=NULL; 351 | char fqhn[NBUF_LEN]; 352 | char *hostname=NULL; 353 | 354 | /* 355 | * ok bob, throw the dictionary at 'em 356 | */ 357 | 358 | d=fread_create(s->dictfile, FREAD_NONL); 359 | 360 | if (d == NULL) { 361 | char nfname[PATH_MAX]; 362 | 363 | snprintf(nfname, sizeof(nfname) - 1, "%s/%s", SHAREDIR, s->dictfile); 364 | 365 | d=fread_create(nfname, FREAD_NONL); 366 | if (d == NULL) { 367 | ERR("cant open `%s'", nfname); 368 | exit(1); 369 | } 370 | } 371 | 372 | for (; fread_getline(d, &hostname) > 0; ) { 373 | if (hostname == NULL || strlen(hostname) < 1) { 374 | continue; 375 | } 376 | 377 | if (hostname[0] == '#') { 378 | continue; 379 | } 380 | 381 | snprintf(fqhn, sizeof(fqhn) -1, "%s.%s.", hostname, s->cur_target); 382 | 383 | do_lookup(fqhn); 384 | } 385 | 386 | fread_destroy(d); 387 | 388 | return; 389 | } 390 | 391 | void get_wildcard(void) { 392 | char hostname[NBUF_LEN]; 393 | 394 | memset(hostname, 0, sizeof(hostname)); 395 | 396 | snprintf(hostname, sizeof(hostname) -1, "%s.%s.", s->sillyhostname, s->cur_target); 397 | 398 | s->wc_sc=stddns_init(NULL, 0); 399 | 400 | s->wc_list=stddns_getaddr(sc, hostname); 401 | 402 | if (s->wc_list == NULL) { 403 | if (s->verbose) { 404 | OUT("No Wildcard found inside domain `%s'", s->cur_target); 405 | } 406 | return; 407 | } 408 | 409 | if (s->verbose) { 410 | OUT("Wildcard Host Found [used `%s']", s->sillyhostname); 411 | } 412 | 413 | return; 414 | } 415 | 416 | int check_wildcard(const struct sockaddr *si) { 417 | unsigned int idx=0; 418 | union { 419 | const struct sockaddr *s; 420 | struct f_s *fs; 421 | const struct sockaddr_in *sin; 422 | const struct sockaddr_in6 *sin6; 423 | } s_u; 424 | 425 | assert(si != NULL); 426 | 427 | if (s->wc_list == NULL) { 428 | return 0; 429 | } 430 | 431 | s_u.s=si; 432 | 433 | for (idx=0; s->wc_list[idx] != NULL; idx++) { 434 | 435 | switch (s->wc_list[idx]->s_u.fs.family) { 436 | case AF_INET: 437 | if (s_u.fs->family != AF_INET) { 438 | break; 439 | } 440 | DBG("%08x Vs %08x", s_u.sin->sin_addr.s_addr, s->wc_list[idx]->s_u.sin.sin_addr.s_addr); 441 | 442 | if (s_u.sin->sin_addr.s_addr == s->wc_list[idx]->s_u.sin.sin_addr.s_addr) { 443 | return 1; 444 | } 445 | 446 | break; 447 | 448 | case AF_INET6: 449 | if (s_u.fs->family != AF_INET6) { 450 | break; 451 | } 452 | if (memcmp(&s->wc_list[idx]->s_u.sin6.sin6_addr.s6_addr[0], &s_u.sin6->sin6_addr.s6_addr[0], sizeof(s->wc_list[idx]->s_u.sin6.sin6_addr.s6_addr[0]) * sizeof(s->wc_list[idx]->s_u.sin6.sin6_addr.s6_addr)) == 0) { 453 | return 1; 454 | } 455 | break; 456 | 457 | default: 458 | break; 459 | } 460 | } 461 | 462 | return 0; 463 | } 464 | 465 | void do_lookup(const char *hn) { 466 | #if HAVE_C_ARES == 1 467 | int ret=0; 468 | #endif 469 | 470 | assert(hn != NULL && strlen(hn) > 0); 471 | DBG("looking up `%s'", hn); 472 | 473 | s->lookups++; 474 | 475 | #if HAVE_C_ARES == 1 476 | 477 | if (s->async) { 478 | for (;;) { 479 | ret=myadns_fwdlookup(hn); 480 | if (ret == 1 || ret < 0) { 481 | if (ret < 0) { 482 | ERR("adns forward lookup fails with code %d", ret); 483 | } 484 | break; 485 | } 486 | do_gather(0); 487 | } 488 | 489 | return; 490 | } 491 | 492 | #endif /* ! ASYNC DNS */ 493 | 494 | (void )stddns_getaddr_cb(sc, hn); 495 | 496 | if (s->discover) { 497 | ERR("discover mode not yet implemented for sync dns lookups"); 498 | s->discover=0; 499 | } 500 | 501 | } 502 | 503 | static void display_output_cb(int type, const void *a, const void *b) { 504 | union { 505 | const void *p; 506 | struct f_s *fs; 507 | const struct sockaddr_in *sin; 508 | const struct sockaddr_in6 *sin6; 509 | const struct sockaddr *s; 510 | } s_u; 511 | char *ret=NULL; 512 | 513 | assert(a != NULL && b != NULL); 514 | 515 | s->replies++; 516 | 517 | if (type == OUTPUT_FORWARD) { 518 | s_u.p=b; 519 | 520 | if (check_wildcard(s_u.s) == 1) { 521 | DBG("ignoring `%s' (due to wildcard address match)", (const char *)a); 522 | return; 523 | } 524 | 525 | ret=cidr_saddrstr(s_u.p); 526 | if (ret == NULL) { 527 | ERR("cant convert sockaddr into address string!"); 528 | return; 529 | } 530 | 531 | display_output(s_u.fs->family, (const char *)a, (const char *)ret); 532 | } 533 | else if (type == OUTPUT_ALIAS) { 534 | display_alias((const char *)a, (const char *)b); 535 | } 536 | else if (type == OUTPUT_REVERSE) { 537 | char *o=NULL; 538 | 539 | s_u.p=a; 540 | o=cidr_saddrstr(s_u.s); 541 | 542 | if (o == NULL) { 543 | PANIC("conversion fails"); 544 | } 545 | 546 | display_routput(s_u.fs->family, (const char *)o, (const char *)b); 547 | } 548 | else { 549 | ERR("unknown output type `%d'", type); 550 | } 551 | 552 | return; 553 | } 554 | 555 | #define escape(str) (str) 556 | 557 | int check_output_unique(const char *a, const char *b) { 558 | uint64_t okey=0; 559 | 560 | assert(a != NULL && b != NULL); 561 | 562 | if (s->filter_unique == 0) { 563 | return 1; 564 | } 565 | 566 | okey=sdbmhash(a, strlen(a)); 567 | okey=okey << 32; 568 | okey |= sdbmhash(b, strlen(b)); 569 | 570 | if (chtinsert(s->uniq, okey, NULL) != 1) { 571 | return 0; 572 | } 573 | 574 | return 1; 575 | } 576 | 577 | void display_output(int family, const char *hostname, const char *addr_str) { 578 | 579 | 580 | if (check_output_unique(hostname, addr_str) != 1) { 581 | return; 582 | } 583 | 584 | if (s->output_sql) { 585 | OUTSQL("insert into hostname (host, addrfam, type, data) values('%s', %d, %u, '%s');", 586 | addr_str, family, 0, escape(hostname)); 587 | } 588 | else { 589 | char fam[64]; 590 | 591 | switch (family) { 592 | case AF_INET: 593 | fam[0]='A'; fam[1]='\0'; 594 | break; 595 | 596 | case AF_INET6: 597 | memset(fam, 0x41, 4); 598 | fam[4]='\0'; 599 | break; 600 | 601 | default: 602 | ERR("Unknown address family %d", family); 603 | fam[0]='?'; 604 | fam[1]='\0'; 605 | break; 606 | } 607 | 608 | OUT("%s\t%s %s", hostname, fam, addr_str); 609 | } 610 | 611 | return; 612 | } 613 | 614 | void display_alias(const char *cname, const char *hostname) { 615 | 616 | if (cname == NULL || hostname == NULL || strlen(cname) < 1 || strlen(hostname) < 1) { 617 | return; 618 | } 619 | if (strcasecmp(cname, hostname) == 0) { 620 | return; 621 | } 622 | 623 | if (check_output_unique(cname, hostname) != 1) { 624 | return; 625 | } 626 | 627 | if (s->output_sql) { 628 | OUTSQL("insert into hostname_alias (hostname, alias) values('%s', '%s');", 629 | escape(hostname), escape(cname) 630 | ); 631 | } 632 | else { 633 | OUT("%s\tCNAME %s", cname, hostname); 634 | } 635 | } 636 | 637 | void display_routput(int family, const char *addr_str, const char *hostname) { 638 | 639 | if (check_output_unique(addr_str, hostname) != 1) { 640 | return; 641 | } 642 | 643 | if (s->output_sql) { 644 | OUTSQL("insert into hostname (host, addrfam, type, data) values('%s', %d, %u, '%s');", 645 | addr_str, family, 1, escape(hostname)); 646 | } 647 | else { 648 | OUT("%s\tPTR %s", addr_str, hostname); 649 | } 650 | return; 651 | } 652 | 653 | static struct cl_s { 654 | char c; 655 | int p; 656 | } *cl; 657 | 658 | static void init_charlist(void) { 659 | int j=0; 660 | 661 | cl=(struct cl_s *)xmalloc(sizeof(struct cl_s) * (strlen(s->allowed) + 1)); 662 | 663 | for (j=0; s->allowed[j] != '\0' ; j++) { 664 | cl[j].c=s->allowed[j]; 665 | cl[j].p=j; 666 | } 667 | cl[j].c=0; 668 | cl[j].p=j; 669 | } 670 | 671 | /* 672 | * returns 1 for carry, incs its char arg 673 | */ 674 | static int inc_char(char *in) { 675 | int j=0; 676 | 677 | assert(in != NULL); 678 | 679 | if (*in == '\0') { 680 | *in=cl[0].c; 681 | return 0; 682 | } 683 | 684 | for (j=0 ; s->allowed[j] != '\0' ; j++) { 685 | if (cl[j].c == *in) { 686 | if (cl[j + 1].c == '\0') { 687 | *in=cl[0].c; 688 | 689 | return 1; 690 | } 691 | else { 692 | *in=cl[j + 1].c; 693 | 694 | return 0; 695 | } 696 | } 697 | } 698 | 699 | PANIC("cow %s", in); 700 | } 701 | 702 | static char *get_sillyhostname(void) { 703 | static char rhost[MAX_SHN_LEN + 1]; 704 | unsigned int len=0, j=0; 705 | 706 | srand((unsigned int )getpid()); 707 | 708 | do { 709 | len=(rand() % MAX_SHN_LEN); 710 | } while (len < MIN_SHN_LEN); 711 | 712 | rhost[len]='\0'; 713 | 714 | for (j=0; j < len; j++) { 715 | rhost[j]=s->allowed[rand() % strlen(s->allowed)]; 716 | } 717 | 718 | return rhost; 719 | } 720 | -------------------------------------------------------------------------------- /main.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_H 2 | # define _MAIN_H 3 | 4 | extern int check_wildcard(const struct sockaddr *); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /misc.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include 4 | 5 | void hexdump(const void *in, size_t len) { 6 | const uint8_t *ptr=NULL; 7 | size_t psize=0, hsize=0; 8 | char hbuf[512]; 9 | 10 | OUT("############################## buffer dump size is %zu ##############################", len); 11 | 12 | for (ptr=(const uint8_t *)in, psize=0; psize < len; psize++, ptr++) { 13 | if (psize != 0 && ((psize % 16) == 0)) { 14 | OUT("# %-40s #", hbuf); 15 | hbuf[0]='\0'; 16 | hsize=0; 17 | } 18 | if (isalnum(*ptr)) { 19 | sprintf(hbuf + hsize, " %c ", *(const char *)ptr); 20 | } 21 | else { 22 | sprintf(hbuf + hsize, "0x%02x ", *ptr); 23 | } 24 | hsize += 5; 25 | } 26 | if (strlen(hbuf) > 0) { 27 | OUT("# %-40s #", hbuf); 28 | } 29 | 30 | OUT("####################################################################################"); 31 | 32 | OUT_FLUSH; 33 | 34 | return; 35 | } 36 | -------------------------------------------------------------------------------- /misc.h: -------------------------------------------------------------------------------- 1 | #ifndef _MISC_H 2 | # define _MISC_H 3 | 4 | void hexdump(const void *, size_t); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /myadns.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include 4 | 5 | #include "ext/xmalloc.h" 6 | #include "ext/cidr.h" 7 | #include "misc.h" 8 | #include "myadns.h" 9 | #include "dnspkt.h" 10 | 11 | #if defined TRACK_REQUESTS == 1 12 | 13 | static void myadns_track_request(int /* type */, int /* proto family */, const void * /* data */, void * /* cb data */); 14 | static void myadns_track_rmrequest(unsigned int /* slot */, unsigned int /* seq */); 15 | 16 | #endif /* TRACK_REQUESTS */ 17 | 18 | #define DO_IPV4_LOOKUPS (s->ipv4_lookup == 1) 19 | #define DO_IPV6_LOOKUPS (s->ipv6_lookup == 1) 20 | #define DO_EXACT (s->exact == 1) 21 | 22 | static struct dnsq_s { 23 | ares_channel c; 24 | void (*display)(int /* type */, const void *, const void *); 25 | int empty; 26 | unsigned int slots_werefull; 27 | unsigned int dnsseq; 28 | unsigned int *slots; 29 | #if defined TRACK_REQUESTS == 1 30 | struct track_s { 31 | unsigned int seq; 32 | int type; 33 | union { 34 | struct { 35 | int addrfam; 36 | uint8_t *addr; 37 | } a_s; 38 | char *hn; 39 | } t_u; 40 | } *track; 41 | #endif 42 | unsigned int concurrency; 43 | } dnsq; 44 | 45 | static void myadns_fwd_cb(void *, int, int, struct hostent *); 46 | static void myadns_rev_cb(void *, int, int, struct hostent *); 47 | static void myadns_any_cb(void *, int, int, uint8_t *, int ); 48 | 49 | int myadns_init(void (*cb)(int , const void *, const void *), unsigned int concurrency) { 50 | int ret=0; 51 | 52 | if (cb == NULL) { 53 | return -1; 54 | } 55 | 56 | dnsq.display=cb; 57 | 58 | dnsq.slots=(unsigned int *)xmalloc(sizeof(unsigned int *) * concurrency); 59 | memset(dnsq.slots, 0, sizeof(unsigned int *) * concurrency); 60 | 61 | dnsq.dnsseq=1; /* not 0 ;], seeing as how thats special */ 62 | dnsq.empty=1; 63 | 64 | dnsq.concurrency=concurrency; 65 | 66 | #if defined TRACK_REQUESTS == 1 67 | dnsq.track=xmalloc(sizeof(struct track_s) * concurrency); 68 | memset(dnsq.track, 0, sizeof(struct track_s) * concurrency); 69 | #endif 70 | 71 | ret=ares_init(&dnsq.c); 72 | if (ret != ARES_SUCCESS) { 73 | ERR("ares_init fails: %s", ares_strerror(ret)); 74 | return -1; 75 | } 76 | 77 | return 1; 78 | } 79 | 80 | void myadns_fini(void) { 81 | 82 | ares_destroy(dnsq.c); 83 | 84 | xfree(dnsq.slots); 85 | 86 | #if defined TRACK_REQUESTS == 1 87 | xfree(dnsq.track); 88 | #endif 89 | 90 | 91 | return; 92 | } 93 | 94 | int myadns_fwdlookup(const char *hostname) { 95 | unsigned int j=0, fidx[2]={0, 0}, *cbp=NULL, slots_req=0, slots_found=0; 96 | 97 | if (DO_IPV4_LOOKUPS) { 98 | slots_req++; 99 | } 100 | if (DO_IPV6_LOOKUPS) { 101 | slots_req++; 102 | } 103 | 104 | /* whats the point if we arent going to do anything? should have been caught already */ 105 | assert(slots_req != 0); 106 | 107 | for (j=0; j < dnsq.concurrency && slots_found != slots_req; j++) { 108 | if (dnsq.slots[j] == 0) { 109 | fidx[slots_found++]=j; 110 | } 111 | } 112 | 113 | if (slots_found != slots_req) { 114 | dnsq.slots_werefull++; 115 | return 0; 116 | } 117 | 118 | if (DO_IPV4_LOOKUPS) { 119 | 120 | cbp=(unsigned int *)xmalloc(sizeof(unsigned int) * 2); 121 | 122 | cbp[0]=dnsq.dnsseq++; 123 | cbp[1]=fidx[0]; 124 | 125 | dnsq.slots[cbp[1]]=cbp[0]; 126 | 127 | DBG("ipv4 lookup `%s' into slot %u seq %u", hostname, cbp[1], cbp[0]); 128 | 129 | #if defined TRACK_REQUESTS == 1 130 | myadns_track_request(TRACK_FWD, AF_INET, hostname, cbp); 131 | #endif 132 | 133 | ares_gethostbyname(dnsq.c, hostname, AF_INET, myadns_fwd_cb, cbp); 134 | } 135 | 136 | if (DO_IPV6_LOOKUPS) { 137 | 138 | cbp=(unsigned int *)xmalloc(sizeof(unsigned int) * 2); 139 | 140 | cbp[0]=dnsq.dnsseq++; 141 | cbp[1]=fidx[DO_IPV4_LOOKUPS ? 1 : 0]; 142 | 143 | dnsq.slots[cbp[1]]=cbp[0]; 144 | 145 | DBG("ipv6 lookup `%s' into slot %u seq %u", hostname, cbp[1], cbp[0]); 146 | 147 | #if defined TRACK_REQUESTS == 1 148 | myadns_track_request(TRACK_FWD, AF_INET6, hostname, cbp); 149 | #endif 150 | 151 | ares_gethostbyname(dnsq.c, hostname, AF_INET6, myadns_fwd_cb, cbp); 152 | } 153 | 154 | dnsq.empty=0; 155 | 156 | return 1; 157 | } 158 | 159 | int myadns_alllookup(const char *hostname) { 160 | int qtype=0xff; /* should be ns_t_any */ 161 | int qclass=0xff; /* should be ns_c_any */ 162 | unsigned int j=0, good=0; 163 | unsigned int *cbp=NULL; 164 | 165 | for (j=0; j < dnsq.concurrency; j++) { 166 | if (dnsq.slots[j] == 0) { 167 | good=1; 168 | break; 169 | } 170 | } 171 | 172 | if (good == 0) { 173 | dnsq.slots_werefull++; 174 | return 0; 175 | } 176 | 177 | cbp=(unsigned int *)xmalloc(sizeof(unsigned int) * 2); 178 | cbp[0]=dnsq.dnsseq++; 179 | cbp[1]=j; 180 | 181 | dnsq.slots[cbp[1]]=cbp[0]; 182 | dnsq.empty=0; 183 | 184 | DBG("all lookup on %s slot %u seq %u", hostname, cbp[1], cbp[0]); 185 | 186 | ares_query(dnsq.c, hostname, qclass, qtype, myadns_any_cb, cbp); 187 | 188 | return 1; 189 | } 190 | 191 | int myadns_revlookup(const struct sockaddr *sock) { 192 | union { 193 | const struct f_s *fs; 194 | const struct sockaddr *s; 195 | const struct sockaddr_in *sin; 196 | const struct sockaddr_in6 *sin6; 197 | } s_u; 198 | const void *p=NULL; /* points to the beginning of the address structure in sockaddr */ 199 | socklen_t sl=0; 200 | unsigned int j=0, good=0; 201 | unsigned int *cbp=NULL; 202 | 203 | s_u.s=sock; 204 | 205 | for (j=0; j < dnsq.concurrency; j++) { 206 | if (dnsq.slots[j] == 0) { 207 | good=1; 208 | break; 209 | } 210 | } 211 | 212 | if (good == 0) { 213 | dnsq.slots_werefull++; 214 | return 0; 215 | } 216 | 217 | switch (s_u.fs->family) { 218 | case AF_INET: 219 | sl=(socklen_t )sizeof(struct in_addr); 220 | p=&s_u.sin->sin_addr; 221 | break; 222 | 223 | case AF_INET6: 224 | sl=(socklen_t )sizeof(struct in6_addr); 225 | p=&s_u.sin6->sin6_addr; 226 | break; 227 | 228 | default: 229 | ERR("unknown address family %d", s_u.fs->family); 230 | return -1; 231 | } 232 | 233 | cbp=(unsigned int *)xmalloc(sizeof(unsigned int) * 2); 234 | cbp[0]=dnsq.dnsseq++; 235 | cbp[1]=j; 236 | 237 | dnsq.slots[cbp[1]]=cbp[0]; 238 | dnsq.empty=0; 239 | 240 | DBG("reverse lookup at address XXX slot %u seq %u", cbp[1], cbp[0]); 241 | 242 | #if defined TRACK_REQUESTS == 1 243 | myadns_track_request(TRACK_REV, s_u.fs->family, p, cbp); 244 | #endif 245 | 246 | ares_gethostbyaddr(dnsq.c, p, sl, s_u.fs->family, myadns_rev_cb, cbp); 247 | 248 | return 1; 249 | } 250 | 251 | int myadns_gather(void) { 252 | int n_fds=0, cnt=0; 253 | fd_set fd_read, fd_write; 254 | struct timeval mtv, tv, *tv_p=NULL; 255 | unsigned int j=0; 256 | 257 | if (dnsq.empty == 1) { 258 | DBG("empty!"); 259 | return 2; 260 | } 261 | 262 | for (;;) { 263 | FD_ZERO(&fd_read); 264 | FD_ZERO(&fd_write); 265 | 266 | n_fds=ares_fds(dnsq.c, &fd_read, &fd_write); 267 | 268 | DBG("got %d dns fd's back", n_fds); 269 | myadns_track_dump(); 270 | 271 | if (n_fds == 0) { 272 | break; 273 | } 274 | 275 | memset(&mtv, 0, sizeof(mtv)); 276 | mtv.tv_sec=MYADNS_TIMEOUT; 277 | 278 | tv_p=ares_timeout(dnsq.c, &mtv, &tv); 279 | 280 | cnt=select(n_fds, &fd_read, &fd_write, NULL, tv_p); 281 | 282 | ares_process(dnsq.c, &fd_read, &fd_write); 283 | 284 | break; 285 | } 286 | 287 | for (j=0; j < dnsq.concurrency; j++) { 288 | if (dnsq.slots[j] != 0) { 289 | return 1; 290 | } 291 | } 292 | 293 | dnsq.empty=1; 294 | 295 | return 2; 296 | } 297 | 298 | #if defined TRACK_REQUESTS == 1 299 | 300 | void myadns_track_dump(void) { 301 | unsigned int j=0; 302 | struct track_s *ts=NULL; 303 | char *astr=NULL; 304 | union { 305 | struct sockaddr_in sin; 306 | struct sockaddr_in6 sin6; 307 | struct sockaddr s; 308 | } s_u; 309 | 310 | for (j=0; j < dnsq.concurrency; j++) { 311 | ts=&dnsq.track[j]; 312 | if (ts->seq == 0) { 313 | continue; 314 | } 315 | DBG("question %u is outstanding", ts->seq); 316 | 317 | switch (ts->type) { 318 | case TRACK_FWD: 319 | DBG("question %u for host `%s' is outstanding", ts->seq, ts->t_u.hn); 320 | break; 321 | 322 | case TRACK_REV: 323 | if (ts->t_u.a_s.addrfam == AF_INET6) { 324 | s_u.sin6.sin6_family=AF_INET6; 325 | memcpy(&s_u.sin6.sin6_addr.s6_addr[0], ts->t_u.a_s.addr, sizeof(s_u.sin6.sin6_addr.s6_addr[0]) * sizeof(s_u.sin6.sin6_addr.s6_addr)); 326 | } 327 | else { 328 | s_u.sin.sin_family=AF_INET; 329 | memcpy(&s_u.sin.sin_addr.s_addr, ts->t_u.a_s.addr, sizeof(s_u.sin.sin_addr.s_addr)); 330 | } 331 | astr=cidr_saddrstr(&s_u.s); 332 | DBG("question %u for address `%s' is outstanding", ts->seq, astr); 333 | break; 334 | 335 | default: 336 | PANIC("whoa, what sort of track request type is %d", ts->type); 337 | break; /* not reached */ 338 | } 339 | } 340 | 341 | return; 342 | } 343 | 344 | int myadns_track_pending(int type, const void *data) { 345 | unsigned int j=0; 346 | struct track_s *ts=NULL; 347 | union { 348 | const struct sockaddr_in *sin; 349 | const struct sockaddr_in6 *sin6; 350 | struct f_s *fs; 351 | const void *p; 352 | } s_u; 353 | 354 | s_u.p=data; 355 | 356 | for (j=0; j < dnsq.concurrency; j++) { 357 | ts=&dnsq.track[j]; 358 | if (ts->seq == 0) { 359 | continue; 360 | } 361 | 362 | switch (ts->type) { 363 | case TRACK_FWD: 364 | if (strcmp(ts->t_u.hn, (const char *)data) == 0) { 365 | return 1; 366 | } 367 | break; 368 | 369 | case TRACK_REV: 370 | if (ts->t_u.a_s.addrfam == AF_INET6 && s_u.fs->family == AF_INET6) { 371 | if (memcmp(ts->t_u.a_s.addr, &s_u.sin6->sin6_addr, sizeof(struct in6_addr)) == 0) { 372 | return 1; 373 | } 374 | 375 | } 376 | else if (ts->t_u.a_s.addrfam == AF_INET && s_u.fs->family == AF_INET) { 377 | 378 | if (memcmp(ts->t_u.a_s.addr, &s_u.sin->sin_addr.s_addr, sizeof(s_u.sin->sin_addr.s_addr)) == 0) { 379 | return 1; 380 | } 381 | } 382 | else { 383 | PANIC("something is bad"); 384 | } 385 | break; 386 | 387 | default: 388 | PANIC("whoa, what sort of track request type is %d", ts->type); 389 | break; /* not reached */ 390 | } 391 | } 392 | 393 | return 0; 394 | } 395 | 396 | #else /* no tracking */ 397 | 398 | void myadns_track_dump(void) { 399 | ERR("no track support compiled in"); 400 | } 401 | 402 | void myadns_track_pending(int type, const void *p) { 403 | ERR("no track support compiled in"); 404 | } 405 | 406 | #endif 407 | /* 408 | * private functions 409 | */ 410 | 411 | static void myadns_rev_cb(void *p, int status, int timeouts, struct hostent *he) { 412 | union { 413 | void *p; 414 | unsigned int *cbp; 415 | } cb_u; 416 | union { 417 | struct sockaddr s; 418 | struct sockaddr_in sin; 419 | struct sockaddr_in6 sin6; 420 | struct f_s fs; 421 | } s_u; 422 | int good=0; 423 | 424 | assert(p != NULL); 425 | 426 | cb_u.p=p; 427 | 428 | DBG("resp for seq %u at slot %u", cb_u.cbp[0], cb_u.cbp[1]); 429 | 430 | assert(cb_u.cbp[1] < dnsq.concurrency); 431 | 432 | if (dnsq.slots[cb_u.cbp[1]] != cb_u.cbp[0]) { 433 | PANIC("gah! dnsseq for slot %u doesnt match my seq %u (it has %u)", cb_u.cbp[1], cb_u.cbp[0], dnsq.slots[cb_u.cbp[1]]); 434 | } 435 | 436 | dnsq.slots[cb_u.cbp[1]]=0; /* free the slot */ 437 | 438 | #if defined TRACK_REQUESTS == 1 439 | myadns_track_rmrequest(cb_u.cbp[1], cb_u.cbp[0]); 440 | #endif 441 | 442 | xfree(cb_u.p); 443 | 444 | switch (status) { 445 | case ARES_SUCCESS: 446 | good=1; 447 | break; 448 | case ARES_ENOTFOUND: 449 | break; 450 | 451 | case ARES_ENOTIMP: 452 | DBG("reverse lookup not implemented"); 453 | break; 454 | case ARES_EBADNAME: 455 | DBG("reverse lookup bad hostname"); 456 | break; 457 | case ARES_ENOMEM: 458 | DBG("reverse lookup no memory"); 459 | break; 460 | case ARES_EDESTRUCTION: 461 | DBG("reverse lookup shutdown in progress, not completed"); 462 | break; 463 | default: 464 | DBG("reverse lookup unknown status `%d'", status); 465 | break; 466 | } 467 | 468 | if (good == 0) { 469 | return; 470 | } 471 | 472 | if (he == NULL) { 473 | ERR("whoa!, got back NULL hostent"); 474 | return; 475 | } 476 | 477 | s_u.fs.family=he->h_addrtype; 478 | 479 | switch (he->h_addrtype) { 480 | case AF_INET: 481 | memcpy(&s_u.sin.sin_addr.s_addr, he->h_addr_list[0], sizeof(s_u.sin.sin_addr.s_addr)); 482 | break; 483 | 484 | case AF_INET6: 485 | memcpy(&s_u.sin6.sin6_addr.s6_addr, he->h_addr_list[0], sizeof(s_u.sin6.sin6_addr.s6_addr) * sizeof(s_u.sin6.sin6_addr.s6_addr[0])); 486 | break; 487 | 488 | default: 489 | PANIC("nyi"); 490 | break; 491 | } 492 | 493 | dnsq.display(OUTPUT_REVERSE, &s_u.s, he->h_name); 494 | 495 | return; 496 | } 497 | 498 | static void myadns_any_cb(void *p, int status, int timeouts, uint8_t *pkt, int pkt_len) { 499 | union { 500 | void *p; 501 | unsigned int *cbp; 502 | } cb_u; 503 | union { 504 | uint8_t *p; 505 | dnshdr_t *hdr; 506 | dnsq_t *q; 507 | dnsrr_t *r; 508 | } dh_u; 509 | int good=0; 510 | unsigned int q_cnt=0, a_cnt=0, ns_cnt=0, o_cnt=0, j=0, d_len=0; 511 | size_t d_left=0; 512 | char *ename=NULL; 513 | long ename_len=0; 514 | 515 | cb_u.p=p; 516 | dh_u.p=pkt; 517 | 518 | switch (status) { 519 | case ARES_SUCCESS: 520 | good=1; 521 | break; 522 | case ARES_ENOTFOUND: 523 | break; 524 | 525 | case ARES_ENOTIMP: 526 | DBG("reverse lookup not implemented"); 527 | break; 528 | case ARES_EBADNAME: 529 | DBG("reverse lookup bad hostname"); 530 | break; 531 | case ARES_ENOMEM: 532 | DBG("reverse lookup no memory"); 533 | break; 534 | case ARES_EDESTRUCTION: 535 | DBG("reverse lookup shutdown in progress, not completed"); 536 | break; 537 | default: 538 | DBG("reverse lookup unknown status `%d'", status); 539 | break; 540 | } 541 | 542 | if (good == 0) { 543 | return; 544 | } 545 | 546 | if (pkt_len < 1 || (size_t )pkt_len < sizeof(dnshdr_t)) { 547 | ERR("got back short resp at %p", pkt); 548 | return; 549 | } 550 | 551 | d_left=(size_t )pkt_len; 552 | 553 | q_cnt=ntohs(dh_u.hdr->questions); 554 | a_cnt=ntohs(dh_u.hdr->answers); 555 | ns_cnt=ntohs(dh_u.hdr->nss); 556 | o_cnt=ntohs(dh_u.hdr->others); 557 | 558 | dh_u.hdr++; 559 | d_left -= sizeof(dnshdr_t); 560 | 561 | DBG("questions %u answers %u nameservers %u other records %u data left %zu", q_cnt, a_cnt, ns_cnt, o_cnt, d_left); 562 | 563 | //hexdump(dh_u.p, d_left); 564 | 565 | for (j=0; j < q_cnt && d_left > 0; j++) { 566 | ename=NULL; ename_len=0; 567 | if (ares_expand_name(dh_u.p, pkt, pkt_len, &ename, &ename_len) != ARES_SUCCESS) { 568 | return; 569 | } 570 | if (ename_len < 0 || (size_t )ename_len >= d_left) { 571 | return; 572 | } 573 | d_left -= (size_t )ename_len; 574 | dh_u.p += (size_t )ename_len; 575 | 576 | if (d_left < sizeof(dnsq_t)) { 577 | return; 578 | } 579 | DBG("Question name %s [len %ld] type %hx class %hx", ename, ename_len, ntohs(dh_u.q->type), ntohs(dh_u.q->qclass)); 580 | dh_u.q++; 581 | d_left -= sizeof(dnsq_t); 582 | } 583 | 584 | hexdump(dh_u.p, d_left); 585 | 586 | for (j=0; j < a_cnt && d_left > 0; j++) { 587 | DBG("answer number %u", j); 588 | 589 | ename=NULL; ename_len=0; 590 | 591 | if (ares_expand_name(dh_u.p, pkt, pkt_len, &ename, &ename_len) != ARES_SUCCESS) { 592 | return; 593 | } 594 | 595 | if (ename_len < 0 || (size_t )ename_len >= d_left) { 596 | return; 597 | } 598 | 599 | if (ename == NULL) { 600 | return; 601 | } 602 | d_left -= (size_t )ename_len; 603 | dh_u.p += (size_t )ename_len; 604 | 605 | DBG("Answer name %s [len %ld] ", ename, ename_len); 606 | DBG("Answer type %hx class %hx ttl %u len %hu", ntohs(dh_u.r->type), ntohs(dh_u.r->qclass), ntohl(dh_u.r->ttl), ntohs(dh_u.r->len)); 607 | 608 | dh_u.r++; 609 | d_len=0; 610 | 611 | d_len=ntohs(dh_u.r->len); 612 | 613 | if (d_len >= d_left) { 614 | return; 615 | } 616 | 617 | if (d_len > 0) { 618 | hexdump(dh_u.p, d_len); 619 | dh_u.p += d_len; 620 | d_left -= d_len; 621 | } 622 | } 623 | 624 | pause(); 625 | } 626 | 627 | static void myadns_fwd_cb(void *p, int status, int timeouts, struct hostent *he) { 628 | union { 629 | void *p; 630 | unsigned int *cbp; 631 | } cb_u; 632 | union { 633 | struct sockaddr_in sin; 634 | struct sockaddr_in6 sin6; 635 | struct sockaddr s; 636 | } s_u; 637 | int good=0; 638 | unsigned int j=0, j1=0; 639 | 640 | assert(p != NULL); 641 | 642 | cb_u.p=p; 643 | 644 | DBG("resp for seq %u at slot %u", cb_u.cbp[0], cb_u.cbp[1]); 645 | 646 | assert(cb_u.cbp[1] < dnsq.concurrency); 647 | 648 | if (dnsq.slots[cb_u.cbp[1]] != cb_u.cbp[0]) { 649 | PANIC("gah! dnsseq for slot %u doesnt match my seq %u (it has %u)", cb_u.cbp[1], cb_u.cbp[0], dnsq.slots[cb_u.cbp[1]]); 650 | } 651 | 652 | dnsq.slots[cb_u.cbp[1]]=0; /* free the slot */ 653 | 654 | #if defined TRACK_REQUESTS == 1 655 | myadns_track_rmrequest(cb_u.cbp[1], cb_u.cbp[0]); 656 | #endif 657 | 658 | xfree(cb_u.p); 659 | 660 | switch (status) { 661 | case ARES_SUCCESS: 662 | good=1; 663 | break; 664 | case ARES_ENOTFOUND: 665 | break; 666 | 667 | case ARES_ENOTIMP: 668 | DBG("forward lookup not implemented"); 669 | break; 670 | case ARES_EBADNAME: 671 | DBG("forward lookup bad hostname"); 672 | break; 673 | case ARES_ENOMEM: 674 | DBG("forward lookup no memory"); 675 | break; 676 | case ARES_EDESTRUCTION: 677 | DBG("forward lookup shutdown in progress, not completed"); 678 | break; 679 | default: 680 | DBG("forward lookup unknown status `%d'", status); 681 | break; 682 | } 683 | 684 | if (good == 0) { 685 | return; 686 | } 687 | 688 | if (he == NULL) { 689 | ERR("whoa, got back NULL hostent!"); 690 | return; 691 | } 692 | 693 | for (j=0; he->h_addr_list[j] != NULL; j++) { 694 | 695 | memset(&s_u.s, 0, sizeof(s_u.s)); 696 | 697 | switch (he->h_addrtype) { 698 | case AF_INET: 699 | s_u.sin.sin_family=AF_INET; 700 | memcpy(&s_u.sin.sin_addr.s_addr, he->h_addr_list[j], sizeof(s_u.sin.sin_addr.s_addr)); 701 | break; 702 | case AF_INET6: 703 | s_u.sin6.sin6_family=AF_INET6; 704 | memcpy(&s_u.sin6.sin6_addr.s6_addr[0], he->h_addr_list[j], sizeof(s_u.sin6.sin6_addr.s6_addr[0]) * sizeof(s_u.sin6.sin6_addr.s6_addr)); 705 | break; 706 | default: 707 | break; 708 | } 709 | if (he->h_aliases != NULL && DO_EXACT) { 710 | for (j1=0; he->h_aliases[j1] != NULL && strlen(he->h_aliases[j1]) > 0; j1++) { 711 | dnsq.display(OUTPUT_ALIAS, he->h_aliases[j1], he->h_name); 712 | } 713 | dnsq.display(OUTPUT_FORWARD, he->h_name, &s_u.s); 714 | } 715 | else { 716 | dnsq.display(OUTPUT_FORWARD, he->h_name, &s_u.s); 717 | } 718 | } 719 | 720 | return; 721 | } 722 | 723 | #if defined TRACK_REQUESTS == 1 724 | 725 | static void myadns_track_request(int type, int addrfam, const void *data, void *cbp) { 726 | union { 727 | void *p; 728 | unsigned int *cbp; 729 | } cbp_u; 730 | union { 731 | const void *p; 732 | const char *hn; 733 | } d_u; 734 | struct track_s *ts=NULL; 735 | unsigned int len=0; 736 | 737 | cbp_u.p=cbp; 738 | d_u.p=data; 739 | 740 | DBG("Track for request %u addrfam %d", cbp_u.cbp[0], addrfam); 741 | 742 | ts=&dnsq.track[cbp_u.cbp[1]]; 743 | 744 | if (ts->seq != 0) { 745 | PANIC("whoa"); 746 | } 747 | 748 | ts->seq=cbp_u.cbp[0]; 749 | ts->type=type; 750 | 751 | switch (type) { 752 | case TRACK_FWD: 753 | ts->t_u.hn=xstrdup(d_u.hn); 754 | break; 755 | 756 | case TRACK_REV: 757 | ts->t_u.a_s.addrfam=addrfam; 758 | if (addrfam == AF_INET) { 759 | len=sizeof(struct in_addr); 760 | } 761 | else if (addrfam == AF_INET6) { 762 | len=sizeof(struct in6_addr); 763 | } 764 | else { 765 | PANIC("unknown address family to track"); 766 | } 767 | ts->t_u.a_s.addr=xmalloc(len); 768 | memcpy(ts->t_u.a_s.addr, d_u.p, len); 769 | break; 770 | 771 | default: 772 | PANIC("unknown type to track %d", type); 773 | break; /* not reached */ 774 | } 775 | 776 | return; 777 | } 778 | 779 | static void myadns_track_rmrequest(unsigned int slot, unsigned int seq) { 780 | struct track_s *ts=NULL; 781 | 782 | assert(slot < dnsq.concurrency); 783 | 784 | ts=&dnsq.track[slot]; 785 | 786 | ts->seq=0; 787 | 788 | switch (ts->type) { 789 | case TRACK_FWD: 790 | xfree(ts->t_u.hn); 791 | break; 792 | 793 | case TRACK_REV: 794 | xfree(ts->t_u.a_s.addr); 795 | break; 796 | 797 | default: 798 | PANIC("unknown type to rm track %d", ts->type); 799 | break; /* not reached */ 800 | } 801 | 802 | ts->type=0; 803 | 804 | return; 805 | } 806 | 807 | #endif 808 | 809 | #ifdef _WRAP_ 810 | 811 | settings_t *s=NULL; 812 | 813 | static void display_forward(const char *, const struct sockaddr *); 814 | 815 | static void display_cb(int type, const void *a, const void *b) { 816 | switch (type) { 817 | case OUTPUT_FORWARD: 818 | display_forward((const char *)a, (const struct sockaddr *)b); 819 | break; 820 | default: 821 | break; 822 | } 823 | } 824 | 825 | static void display_forward(const char *name, const struct sockaddr *si) { 826 | union { 827 | const struct sockaddr *s; 828 | const struct f_s *fs; 829 | const struct sockaddr_in *sin; 830 | const struct sockaddr_in6 *sin6; 831 | } s_u; 832 | char nbuf[256]; 833 | 834 | s_u.s=si; 835 | 836 | 837 | nbuf[0]='\0'; 838 | switch (s_u.fs->family) { 839 | case AF_INET: 840 | inet_ntop(AF_INET, &s_u.sin->sin_addr, nbuf, sizeof(nbuf) -1); 841 | break; 842 | case AF_INET6: 843 | inet_ntop(AF_INET6, &s_u.sin6->sin6_addr, nbuf, sizeof(nbuf) -1); 844 | break; 845 | } 846 | 847 | OUT("%s has address %s", name, nbuf); 848 | 849 | return; 850 | } 851 | 852 | int main(int argc, char ** argv) { 853 | int j=0; 854 | 855 | s=xmalloc(sizeof(settings_t)); 856 | memset(s, 0, sizeof(*s)); 857 | s->ipv6_lookup=1; 858 | s->ipv4_lookup=1; 859 | 860 | if (myadns_init(display_cb, 4) < 0) { 861 | exit(1); 862 | } 863 | 864 | for (j=1; j < argc; j++) { 865 | DBG("looking up `%s'", argv[j]); 866 | myadns_fwdlookup(argv[j]); 867 | } 868 | 869 | myadns_gather(); 870 | 871 | myadns_fini(); 872 | 873 | xfree(s); 874 | 875 | exit(0); 876 | } 877 | 878 | #endif 879 | -------------------------------------------------------------------------------- /myadns.h: -------------------------------------------------------------------------------- 1 | #ifndef _MYADNS_H 2 | # define _MYADNS_H 3 | 4 | #define TRACK_REQUESTS 1 5 | #define TRACK_FWD 1 6 | #define TRACK_REV 2 7 | 8 | int myadns_init(void (* /* callback */)(int /* type */, const void *, const void *), unsigned int /* concurrency */); 9 | void myadns_fini(void); 10 | int myadns_fwdlookup(const char *); 11 | int myadns_alllookup(const char *); 12 | int myadns_revlookup(const struct sockaddr *); 13 | int myadns_gather(void); 14 | void myadns_track_dump(void); 15 | int myadns_track_pending(int /* type */, const void * /* data */); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /readconf.c: -------------------------------------------------------------------------------- 1 | #include "settings.h" 2 | 3 | #include "ext/fread.h" 4 | #include "getopts.h" 5 | 6 | static struct cfg_opts_s { 7 | const char *name; 8 | const char *alias; 9 | int fptype; 10 | #define FPTYPE_NONE 0 11 | #define FPTYPE_STR 1 12 | #define FPTYPE_INT 2 13 | union { 14 | void *p; 15 | int (*sfp)(const char *); 16 | int (*ifp)(int ); 17 | } f_u; 18 | } cfg_opts[]={ 19 | {"mode", NULL, FPTYPE_STR, { set_mode }}, 20 | {"addrfam", NULL, FPTYPE_STR, { set_addrfam }}, 21 | {"allowed", NULL, FPTYPE_STR, { set_allowed }}, 22 | {"async", NULL, FPTYPE_STR, { set_async }}, 23 | {"dictfile", NULL, FPTYPE_STR, { set_dictfile }}, 24 | {"sillyhostname", NULL, FPTYPE_STR, { set_sillyhostname }}, 25 | {"verbose", NULL, FPTYPE_INT, { set_verbose }}, 26 | {"exact", NULL, FPTYPE_INT, { set_exact }}, 27 | {"outsql", NULL, FPTYPE_INT, { set_outsql }}, 28 | {"discover", NULL, FPTYPE_INT, { set_discover }}, 29 | {"filter", NULL, FPTYPE_INT, { set_filter }}, 30 | {NULL, NULL, FPTYPE_NONE, { NULL }} 31 | }; 32 | 33 | void readconf(const char *file) { 34 | void *hand=NULL; 35 | char *buf=NULL, param[128], value[128]; 36 | unsigned int j=0, found=0; 37 | 38 | /* 39 | * not possible: (no settings yet) DBG("reading `%s'", file); 40 | */ 41 | 42 | hand=fread_create(file, FREAD_NONL); 43 | if (hand == NULL) { 44 | return; 45 | } 46 | 47 | for (;;) { 48 | if (fread_getline(hand, &buf) < 1) { 49 | break; 50 | } 51 | if (buf == NULL || strlen(buf) < 1) { 52 | continue; 53 | } 54 | if (buf[0] == '#') { 55 | continue; 56 | } 57 | if (sscanf(buf, "%127[^:]: %127s", param, value) != 2) { 58 | continue; 59 | } 60 | 61 | for (j=0, found=0; cfg_opts[j].name != NULL; j++) { 62 | 63 | if (strcasecmp(param, cfg_opts[j].name) == 0 || 64 | (cfg_opts[j].alias != NULL && strcasecmp(param, cfg_opts[j].alias) == 0) 65 | ) { 66 | int ret=0; 67 | 68 | found=1; 69 | if (cfg_opts[j].fptype == FPTYPE_STR) { 70 | ret=cfg_opts[j].f_u.sfp(value); 71 | } 72 | else if (cfg_opts[j].fptype == FPTYPE_INT) { 73 | ret=cfg_opts[j].f_u.ifp(atoi(value)); 74 | } 75 | else { 76 | PANIC("bad function type"); 77 | } 78 | 79 | if (ret != 1) { 80 | ERR("line `%s' is not valid at %s:%u", buf, fread_filename(hand), fread_lineno(hand)); 81 | exit(1); 82 | } 83 | 84 | } 85 | } 86 | 87 | if (found == 0) { 88 | ERR("unknown setting `%s' at %s:%u", param, fread_filename(hand), fread_lineno(hand)); 89 | } 90 | } /* for each line of file */ 91 | 92 | fread_destroy(hand); 93 | } 94 | -------------------------------------------------------------------------------- /readconf.h: -------------------------------------------------------------------------------- 1 | #ifndef _READCONF_H 2 | # define _READCONF_H 3 | 4 | void readconf(const char * /* file name */); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /scripts/_auto.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -f configure aclocal.m4 4 | #for g in `ls m4/*.m4`; do cat $g >> aclocal.m4; done 5 | autoconf -v 6 | rm -rf Makefile Makefile.inc autom4te.cache confdefs.h config.log config.status 7 | -------------------------------------------------------------------------------- /scripts/mkdist.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | ./scripts/_auto.sh 4 | 5 | THIS_DIR=`basename $(pwd)` 6 | 7 | if [ -f ../${THIS_DIR}.tar.gz ] 8 | then 9 | mv ../${THIS_DIR}.tar.gz ../${THIS_DIR}.tar.gz.old 10 | fi 11 | 12 | ( 13 | cd .. \ 14 | && \ 15 | tar -cvf - ${THIS_DIR} | gzip -c9 > ${THIS_DIR}.tar.gz 16 | ) 17 | -------------------------------------------------------------------------------- /scripts/mkslackpkg: -------------------------------------------------------------------------------- 1 | #!/bin/sh -x 2 | 3 | if [ ! -f readconf.c ] 4 | then 5 | echo error, run this script from the source root 6 | exit 7 | fi 8 | 9 | umask 0022 10 | chown -R root:root . 11 | 12 | ARCH=i486 13 | CPUTUNE=i686 14 | 15 | if [ -f /etc/slackware-version ] 16 | then 17 | DISTVERS=`cat /etc/slackware-version | awk '{print $2}'` 18 | else 19 | DISTVERS="slackware-unknown" 20 | fi 21 | 22 | strip="strip --remove-comment -d" 23 | 24 | dist=slackware 25 | 26 | # a safe location 27 | PKGBDIR=`pwd`/stage 28 | 29 | export dist strip PKGBDIR ARCH CPUTUNE DISTVERS 30 | 31 | mkdir -p packages/${dist}/${DISTVERS} 32 | 33 | rm -rf $PKGBDIR && mkdir -m 755 $PKGBDIR 2>/dev/null 34 | 35 | ./scripts/_auto.sh 36 | 37 | CFLAGS="-march=${ARCH} -mcpu=${CPUTUNE} -O2" ./configure --prefix=/usr --mandir=/usr/man --sysconfdir=/etc --localstatedir=/var ${ARCH}-${dist}-linux 38 | make clean && make 39 | 40 | VERSION=`grep "VERSION" config.h | awk '{print $3}' | sed 's/"//g'` 41 | 42 | DESTDIR=$PKGBDIR make install 43 | 44 | find $PKGBDIR/usr/man -name "*.[1-9]" -exec gzip -9 {} \; 45 | 46 | (cd $PKGBDIR 47 | chgrp bin usr/bin 48 | cd usr/bin && $strip * && rm -f gmon.out && chown root:bin * 49 | ) 50 | 51 | (cd $PKGBDIR 52 | mkdir install && cat < install/slack-desc 53 | namedrop: namedrop 54 | namedrop: 55 | namedrop: namedrop is an enhanced dns info enumerator 56 | namedrop: 57 | namedrop: 58 | EOF 59 | makepkg -l y -c n ../packages/${dist}/${DISTVERS}/namedrop-${VERSION}-${ARCH}-1.tgz 60 | ) 61 | -------------------------------------------------------------------------------- /scripts/runtests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -xe 2 | 3 | host=kame220 4 | domain=kame.net 5 | 6 | ./namedrop -ve6r ${host}.${domain}/117 7 | ./namedrop -ve6r 2001:200:0:8002:203:47ff:fea5:3085/117 8 | ./namedrop -ve6rS 2001:200:0:8002:203:47ff:fea5:3085/117 9 | ./namedrop -ve6rs ${host}.${domain}/117 10 | ./namedrop -ve6Sr ${host}.${domain}/117 11 | ./namedrop -ver4 ${host}.${domain}/25 12 | ./namedrop -ver4 203.178.141.194/25 13 | ./namedrop -ver4S 203.178.141.194/25 14 | ./namedrop -ver4s ${host}.${domain}/25 15 | ./namedrop -verS4 ${host}.${domain}/25 16 | ./namedrop -ve4 ${domain} 17 | ./namedrop -ve6 ${domain} 18 | ./namedrop -ve ${domain} 19 | ./namedrop -ves ${domain} 20 | ./namedrop -veS ${domain} 21 | ./namedrop -vef oz ${domain} 22 | ./namedrop -veb 1-2 ${domain} 23 | ./namedrop -veb 3-3 -c cvswftpo ${domain} 24 | -------------------------------------------------------------------------------- /settings.h: -------------------------------------------------------------------------------- 1 | #ifndef _SETTINGS_H 2 | # define _SETTINGS_H 3 | 4 | #include "config.h" 5 | 6 | #define DBG(msg, args...)\ 7 | if (s->verbose > 4) {\ 8 | fprintf(stderr, "%sDEBUG %s:%u: " msg "\n", s != NULL && s->output_sql ? SQL_COMMENT : "", __FILE__, __LINE__, ## args);\ 9 | } 10 | 11 | #define ERR(msg, args...)\ 12 | fprintf(stderr, "%sERROR %s:%u: " msg "\n", s != NULL && s->output_sql ? SQL_COMMENT : "", __FILE__, __LINE__, ## args); 13 | 14 | #define assert(f) \ 15 | if (! ( f ) ) { \ 16 | PANIC("Assertion `%s' fails", # f); \ 17 | } 18 | 19 | #define PANIC(fmt, args...) \ 20 | do { \ 21 | \ 22 | fprintf(stderr, "PANIC at %s:%u " fmt "\n", __FILE__, __LINE__, ## args); \ 23 | if (s->verbose > 4) { \ 24 | fprintf(stderr, "Attach to pid %d , called from %s() %s:%d\n", getpid(), __FUNCTION__, __FILE__, __LINE__); \ 25 | pause(); \ 26 | } \ 27 | abort(); \ 28 | } while (0) 29 | 30 | #define OUT(fmt, args...) \ 31 | do { \ 32 | if (s->output_sql) { \ 33 | fprintf(stdout, "--" fmt "\n", ## args); \ 34 | } \ 35 | else { \ 36 | fprintf(stdout, fmt "\n", ## args); \ 37 | } \ 38 | } while (0) 39 | 40 | #define OUTSQL(fmt, args...) \ 41 | do { \ 42 | fprintf(stdout, fmt "\n", ## args); \ 43 | } while(0) 44 | 45 | #define OUT_FLUSH fflush(stdout) 46 | 47 | #define OUTPUT_FORWARD 1 48 | #define OUTPUT_REVERSE 2 49 | #define OUTPUT_ALIAS 3 50 | 51 | typedef struct settings_t { 52 | char *dictfile; 53 | 54 | char *targets[MAX_TARGETS]; 55 | char *cur_target; 56 | 57 | int verbose; 58 | 59 | char *allowed; /* for brute force mode */ 60 | char *sillyhostname; 61 | 62 | int mode; 63 | #define MODE_BRUTE 1 64 | #define MODE_REVERSE 2 65 | #define MODE_DICT 3 66 | 67 | int output_sql; 68 | int ipv6_lookup; 69 | int ipv4_lookup; 70 | int discover; 71 | int exact; 72 | int filter_unique; 73 | 74 | void *uniq; 75 | 76 | unsigned int concurrency; 77 | int async; 78 | 79 | struct sockaddr_list_t **wc_list; 80 | void *wc_sc; 81 | 82 | int brute_lenmin; 83 | int brute_lenmax; 84 | 85 | struct sockaddr_storage netid; 86 | struct sockaddr_storage netmask; 87 | unsigned int cmask; 88 | 89 | time_t start; 90 | unsigned int replies; 91 | unsigned int lookups; 92 | } settings_t; 93 | 94 | extern settings_t *s; 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /sql/pgsql_schema.sql: -------------------------------------------------------------------------------- 1 | drop table "hostname"; 2 | drop table "hostname_alias"; 3 | 4 | create table "hostname"( 5 | "host" inet not null, 6 | "addrfam" int2 not null default 0, 7 | "type" int2 not null default 0, 8 | "data" varchar(220) not null 9 | ); 10 | 11 | create table "hostname_alias"( 12 | "alias" varchar(220) not null, 13 | "hostname" varchar(220) not null 14 | ); 15 | -------------------------------------------------------------------------------- /wordlists/WARNING: -------------------------------------------------------------------------------- 1 | some of these wordlists contain offensive language (mit.edu for example) 2 | -------------------------------------------------------------------------------- /wordlists/dict_words.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/dict_words.gz -------------------------------------------------------------------------------- /wordlists/dos.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/dos.gz -------------------------------------------------------------------------------- /wordlists/etc-hosts.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/etc-hosts.gz -------------------------------------------------------------------------------- /wordlists/fast.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/fast.gz -------------------------------------------------------------------------------- /wordlists/jargon.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/jargon.gz -------------------------------------------------------------------------------- /wordlists/mit.edu.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/mit.edu.gz -------------------------------------------------------------------------------- /wordlists/movie-characters.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/movie-characters.gz -------------------------------------------------------------------------------- /wordlists/names.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/names.gz -------------------------------------------------------------------------------- /wordlists/oz.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Neg9/namedrop/0a1fe3fd5eef83db63126870ee73b66a0c75e68d/wordlists/oz.gz -------------------------------------------------------------------------------- /wordlists/prune: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -f $1 ] 4 | then 5 | echo no file called $1 6 | exit 1 7 | fi 8 | 9 | if (echo $1 | grep '\.gz$' >/dev/null) 10 | then 11 | zcat ${1} | dd conv=lcase 2>/dev/null | sort | uniq > ${1%%.gz} 12 | rm ${1} && gzip -9 ${1%%.gz} 13 | else 14 | echo need file name that ends with .gz 15 | exit 1 16 | fi 17 | --------------------------------------------------------------------------------