├── .clang-format ├── .github └── workflows │ └── build.yml ├── .gitignore ├── AUTHORS ├── CONTRIBUTING.md ├── COPYING ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── README.md ├── autogen.sh ├── code-format.sh ├── configure.ac ├── doc └── UPDATE-CHECK ├── man ├── create-man.sh ├── nbtscan.1 └── nbtscan.txt └── src ├── Makefile.am ├── errors.h ├── list.c ├── list.h ├── nbtscan.c ├── range.c ├── range.h ├── statusq.c ├── statusq.h └── time.h /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: LLVM 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Left 9 | AlignOperands: true 10 | AlignTrailingComments: true 11 | AllowAllParametersOfDeclarationOnNextLine: false 12 | AllowShortBlocksOnASingleLine: false 13 | AllowShortCaseLabelsOnASingleLine: false 14 | AllowShortFunctionsOnASingleLine: Empty 15 | AllowShortIfStatementsOnASingleLine: false 16 | AllowShortLoopsOnASingleLine: false 17 | AlwaysBreakAfterDefinitionReturnType: None 18 | AlwaysBreakAfterReturnType: All 19 | AlwaysBreakBeforeMultilineStrings: true 20 | AlwaysBreakTemplateDeclarations: false 21 | BinPackArguments: false 22 | BinPackParameters: false 23 | BraceWrapping: 24 | AfterClass: false 25 | AfterControlStatement: false 26 | AfterEnum: false 27 | AfterFunction: false 28 | AfterNamespace: false 29 | AfterObjCDeclaration: false 30 | AfterStruct: false 31 | AfterUnion: false 32 | AfterExternBlock: false 33 | BeforeCatch: false 34 | BeforeElse: false 35 | IndentBraces: false 36 | SplitEmptyFunction: true 37 | SplitEmptyRecord: true 38 | SplitEmptyNamespace: true 39 | BreakBeforeBinaryOperators: None 40 | BreakBeforeBraces: GNU 41 | BreakBeforeInheritanceComma: false 42 | BreakBeforeTernaryOperators: true 43 | BreakConstructorInitializersBeforeComma: false 44 | BreakConstructorInitializers: BeforeColon 45 | BreakAfterJavaFieldAnnotations: false 46 | BreakStringLiterals: true 47 | ColumnLimit: 80 48 | CommentPragmas: '^ IWYU pragma:' 49 | CompactNamespaces: false 50 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 51 | ConstructorInitializerIndentWidth: 4 52 | ContinuationIndentWidth: 8 53 | Cpp11BracedListStyle: true 54 | DerivePointerAlignment: false 55 | DisableFormat: false 56 | ExperimentalAutoDetectBinPacking: false 57 | FixNamespaceComments: true 58 | ForEachMacros: 59 | - foreach 60 | - Q_FOREACH 61 | - BOOST_FOREACH 62 | IncludeBlocks: Preserve 63 | IncludeCategories: 64 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 65 | Priority: 2 66 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 67 | Priority: 3 68 | - Regex: '.*' 69 | Priority: 1 70 | IncludeIsMainRegex: '(Test)?$' 71 | IndentCaseLabels: true 72 | IndentPPDirectives: None 73 | IndentWidth: 2 74 | IndentWrappedFunctionNames: false 75 | JavaScriptQuotes: Leave 76 | JavaScriptWrapImports: true 77 | KeepEmptyLinesAtTheStartOfBlocks: false 78 | MacroBlockBegin: '' 79 | MacroBlockEnd: '' 80 | MaxEmptyLinesToKeep: 1 81 | NamespaceIndentation: None 82 | ObjCBlockIndentWidth: 2 83 | ObjCSpaceAfterProperty: false 84 | ObjCSpaceBeforeProtocolList: true 85 | PenaltyBreakAssignment: 2 86 | PenaltyBreakBeforeFirstCallParameter: 19 87 | PenaltyBreakComment: 300 88 | PenaltyBreakFirstLessLess: 120 89 | PenaltyBreakString: 1000 90 | PenaltyExcessCharacter: 1000000 91 | PenaltyReturnTypeOnItsOwnLine: 60 92 | PointerAlignment: Right 93 | #RawStringFormats: 94 | # Delimiter: pb 95 | # Language: TextProto 96 | # BasedOnStyle: google 97 | ReflowComments: true 98 | SortIncludes: false 99 | SortUsingDeclarations: true 100 | SpaceAfterCStyleCast: true 101 | SpaceAfterTemplateKeyword: true 102 | SpaceBeforeAssignmentOperators: true 103 | SpaceBeforeParens: Always 104 | SpaceInEmptyParentheses: false 105 | SpacesBeforeTrailingComments: 2 106 | SpacesInAngles: false 107 | SpacesInContainerLiterals: true 108 | SpacesInCStyleCastParentheses: true 109 | SpacesInParentheses: true 110 | SpacesInSquareBrackets: false 111 | Standard: Cpp11 112 | TabWidth: 8 113 | UseTab: Never 114 | ... 115 | 116 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: full-check 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: first_build 13 | run: | 14 | ./autogen.sh 15 | ./configure 16 | make 17 | sudo make install 18 | sudo make uninstall 19 | make distclean 20 | - name: make_dist 21 | run: | 22 | ./autogen.sh 23 | ./configure 24 | make dist 25 | mkdir test_dist 26 | mv nbtscan-*.tar.gz test_dist 27 | cd test_dist 28 | tar -xvf nbtscan-*.tar.gz 29 | rm -f nbtscan-*.tar.gz 30 | cd nbtscan-* 31 | ./autogen.sh 32 | ./configure 33 | make 34 | sudo make install 35 | sudo make uninstall 36 | make distclean 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.o 3 | src/.deps 4 | INSTALL 5 | Makefile 6 | Makefile.in 7 | aclocal.m4 8 | autom4te.cache/output.0 9 | autom4te.cache/output.1 10 | autom4te.cache/requests 11 | autom4te.cache/traces.0 12 | autom4te.cache/traces.1 13 | compile 14 | config.guess 15 | config.log 16 | config.status 17 | config.sub 18 | configure 19 | depcomp 20 | install-sh 21 | missing 22 | src/.deps/list.Po 23 | src/.deps/nbtscan.Po 24 | src/.deps/range.Po 25 | src/.deps/statusq.Po 26 | src/Makefile 27 | src/Makefile.in 28 | src/nbtscan 29 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Alla Bezroutchko , the original author. 2 | Joao Eriberto Mota Filho , the current project 3 | manager in GitHub (since 2019). 4 | Several contributors (see the ChangeLog file). 5 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## HOW TO CONTRIBUTE TO NBTSCAN DEVELOPMENT 2 | 3 | NBTscan is available at 4 | https://github.com/resurrecting-open-source-projects/nbtscan 5 | 6 | If you are interested in contribute to NBTscan development, please, follow 7 | these steps: 8 | 9 | 1. Send a patch that fix an issue or that implement a new feature. 10 | Alternatively, you can do a 'pull request'[1] in GitHub. 11 | 12 | [1] https://help.github.com/articles/about-pull-requests 13 | 14 | 2. Ask for join to the NBTscan project in GitHub, if you want to work 15 | officially. Note that this second step is not compulsory. However, 16 | to accept you in project, is needed a minimum previous collaboration. 17 | 18 | 19 | To find issues and bugs to fix, you can check these addresses: 20 | 21 | - https://github.com/resurrecting-open-source-projects/nbtscan 22 | - https://bugs.debian.org/cgi-bin/pkgreport.cgi?dist=unstable;package=nbtscan 23 | - https://bugs.launchpad.net/ubuntu/+source/nbtscan/+bugs 24 | 25 | If you want to join, please make a contact. 26 | 27 | -- Eriberto, Thu, 14 Nov 2019 00:44:53 -0300. 28 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | Version 1.7.2 - 13 Jan 2022 2 | 3 | [ Joao Eriberto Mota Filho ] 4 | 5 | * Fixed 'make dist'. 6 | * Improved GitHub CI test. 7 | 8 | [ Mayco Souza Berghetti ] 9 | 10 | * Added code style (clang-format). 11 | * Added file .gitignore. 12 | * Fixed building warnings. 13 | * Fixed memory leaks. 14 | * Minor changes from source code. 15 | 16 | Version 1.7.1 - 17 Aug 2021 17 | 18 | [ Joao Eriberto Mota Filho ] 19 | 20 | * Revert the test to include sys/time.h. This test is no longer needed in 21 | modern systems. 22 | 23 | Version 1.7 - 16 Aug 2021 24 | 25 | [ Joao Eriberto Mota Filho ] 26 | 27 | * Added a test in nbtscan.c and statusq.c before to include sys/time.h. 28 | * Fixed distclean in Makefile.am. 29 | * Ran astyle command to reorganize the source code. 30 | * Simplified src/Makefile.am. 31 | * Updated configure.ac to make it compliant with autotools >= 2.70. Bumped 32 | required version to 2.69. 33 | * Updated man/create-man.sh to most recent version from txt2man Debian 34 | package. 35 | * Updated manpage. 36 | 37 | Version 1.6 - 14 Nov 2019 38 | 39 | [ Joao Eriberto Mota Filho ] 40 | 41 | * Autotools files: 42 | - Added a distclean-local target in Makefile.am. 43 | - Added the autogen.sh file. 44 | - Added CFLAGS, CPPFLAGS and LDFLAGS to allow GCC hardening. 45 | - Changed .in files to .ac/.am. 46 | - Improved the configure.ac and Makefile.am files. 47 | - Moved some build lines from Makefile.am to src/Makefile.am. 48 | - Removed all autogenerated files. 49 | * Created AUTHORS and CONTRIBUTING.md. 50 | * Rewritten README file. 51 | * Moved the source code to src/. 52 | * Added headers and rights. 53 | * Using an updated COPYING file. 54 | * Using txt2man to produce a manpage. 55 | 56 | [ Jochen Friedrich ] 57 | 58 | * Several fix in source code to avoid warnings. 59 | * Using ":" in MAC addresses instead of "-". 60 | 61 | [ Johan Eidenvall ] 62 | 63 | * Fixed missing format specifiers that do debug output looks odd. 64 | 65 | [ Walter "Wallie" Jakob Doekes ] 66 | 67 | * Fixed invalid pointer when scanning some ranges with -v. 68 | 69 | Version 1.5.1 - June 2003 70 | 71 | - Fixed segmentation fault when using -f option (noticed by Brian Lovrin) 72 | - Fixed printing ugliness (noticed by Darren Critchley) 73 | - Changed version number :) (1.5 said that it is 1.0.3 - now it proudly says 1.5.1) 74 | 75 | Version 1.5 - May 2002 76 | 77 | - Fixed a bug in displaying of 15-character NetBIOS names (15th character wasn't displayed). Bug reported by Tom Kustner (Tom.Kustner@mortgage.wellsFargo.COM), Kenny Breck (KCBreck@NetZero.net) and Richard IJzermans (richard.ijzermans@lgphilips-displays.com) 78 | - Fixed a bug in interpreting netmask /32 and /0. Patch provided by Thomas Poindessous (thomas@poindessous.com) for Debian Linux 79 | - List of hosts to scan can now be read from stdin as well as from file. Suggested by Kevin Kadow (kadokev@msg.net) 80 | - Fixed a bug in timing. (nbtscan waited for two seconds after scanning not doing anything). Reported by Ceri Hopkins (ceri@sandc.demon.co.uk) 81 | - Nbtscan now works on Darwin. Patches provided by Mohammad A. Haque (mhaque@haque.net) 82 | - timeout option -t is now in milliseconds, not seconds 83 | - Fixed some Solaris portability problems. Patches provided by Petter Reinholdtsen (pere@hungry.com) 84 | 85 | Version 1.0.3 - February 2002 86 | 87 | - NBTscan now returns meaningful exit code (patch by James Troup for Debian Linux) 88 | - Added /etc/hosts and lmhosts format output (suggested by Anahuac de Paula Gil and Sigmund Baginov) 89 | - configure script now honors --prefix argument (patch by Petter Reinholdtsen) 90 | - Error messages now include IP address that caused error 91 | - NBTscan accepts a file with a list of IP addresses to scan (suggested by Omas Jakobsson) 92 | - Service number is printed for unknown NetBIOS services in -h mode (suggested by Dan Wright) 93 | - Fixed some compile-time warnings on Linux 94 | - Corrected some typos 95 | 96 | Version 1.0.2 - March 30, 2000 97 | 98 | - Added retransmits (-m option) (Several people asked) 99 | - Added output bandwidth throttling (-b option) (Suggested 100 | by Jason Garman ) 101 | - Rewrote sending queries and receiving answers part for more 102 | reliable scanning of large blocks of addresses. (Suggested 103 | by Jason Garman ) 104 | - Added script-friendly output option (-s) (Suggested by 105 | Patrick Heim ) 106 | - Added printing of human-readable NetBIOS service names (-h) 107 | (Suggested by Patrick Heim ) 108 | - Added -q command line option that suppresses printing 109 | banners and error messages. (Suggested by Sam Bayne 110 | ) 111 | - Rewrote parse_response completely. This allows for better 112 | parsing of Samba servers' responses. (Bug reported by 113 | Sam Bayne ) 114 | - Added -d command line option which makes whole packets 115 | get printed 116 | - Various cosmetic improvements including fixing some 117 | spelling errors 118 | 119 | Version 1.0.1 - May 5, 1999 120 | 121 | - Fixed incorrect parsing of MAC address in parse_response() 122 | which made last byte of MAC addresses appear as 00. Bug 123 | pointed by Joseph Moon. 124 | - Changed message saying "Warning: -r option not supported 125 | under NT." to more accurate saying: "Warning: -r option not 126 | supported under Windows." 127 | - Corrected a typo in README. 128 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright 2019-2022 Joao Eriberto Mota Filho 2 | # 3 | # This program is free software; you can redistribute it and/or 4 | # modify it under the terms of the GNU General Public License 5 | # as published by the Free Software Foundation; either version 2 6 | # of the License, or (at your option) any later version. 7 | # 8 | # This program is distributed in the hope that it will be useful, 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | # GNU General Public License for more details. 12 | # 13 | # You should have received a copy of the GNU General Public License 14 | # along with this program; if not, write to the Free Software 15 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 | 17 | SUBDIRS = src 18 | 19 | man_MANS= man/nbtscan.1 20 | EXTRA_DIST= autogen.sh CONTRIBUTING.md man/nbtscan.1 README.md 21 | 22 | distclean-local: 23 | -rm -rf autom4te.cache 24 | -rm aclocal.m4 compile config.* configure depcomp INSTALL install-sh \ 25 | Makefile Makefile.in missing src/Makefile.in 26 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/resurrecting-open-source-projects/nbtscan/e09e22a2a322ba74bb0b3cd596933fe2e31f4b2b/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NBTscan 2 | 3 | **NBTscan - scan networks for NetBIOS name information** 4 | 5 | ## Help this project 6 | 7 | NBTscan needs your help. **If you are a programmer** and if you want to help a 8 | nice project, this is your opportunity. 9 | 10 | NBTscan was imported from some tarballs, the [original homepage][1] and 11 | developers are inactive. After this, all patches found in the Debian project and 12 | other places for this program were applied. All initial work was registered in the 13 | [ChangeLog file](ChangeLog) (version 1.6 and later releases). NBTscan is being packaged 14 | in the [Debian project][2]. 15 | 16 | If you are interested to help NBTscan, read the [CONTRIBUTING.md](CONTRIBUTING.md) file. 17 | 18 | ## What is NBTscan? 19 | 20 | NBTscan is a program for scanning IP networks for NetBIOS name information. 21 | It sends NetBIOS status queries to each address in the supplied range and lists 22 | received information in human-readable form. For each responding host it lists 23 | IP address, NetBIOS computer name, logged-in user name and MAC address (such 24 | as Ethernet). 25 | 26 | ## Build and Install 27 | 28 | To build and install, run the following commands: 29 | 30 | $ ./autogen.sh 31 | $ ./configure 32 | $ make 33 | # make install 34 | 35 | To return to the original source code, you can use `$ make distclean`. 36 | 37 | On Debian systems, you can use `# apt install nbtscan`. 38 | 39 | ## Author 40 | 41 | NBTscan was originally developed by Alla Bezroutchko under the GPL-2+ license. 42 | 43 | Currently, the source code and newer versions are available on [GitHub][3] 44 | 45 | 46 | [1]: https://web.archive.org/web/20210126110758/http://www.inetcat.org/software/nbtscan.html 47 | [2]: https://tracker.debian.org/pkg/nbtscan 48 | [3]: https://github.com/resurrecting-open-source-projects/nbtscan 49 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # autogen.sh with clean option, v0.1-nbtscan 4 | # Copyright 2019 Joao Eriberto Mota Filho 5 | # 6 | # This file is under BSD-3-Clause license. 7 | # 8 | # Redistribution and use in source and binary forms, with or without 9 | # modification, are permitted provided that the following conditions 10 | # are met: 11 | # 1. Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above copyright 14 | # notice, this list of conditions and the following disclaimer in the 15 | # documentation and/or other materials provided with the distribution. 16 | # 3. Neither the name of the authors nor the names of its contributors 17 | # may be used to endorse or promote products derived from this software 18 | # without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | # SUCH DAMAGE. 31 | 32 | 33 | # Use clean option 34 | if [ "$1" = "clean" -a ! -e Makefile ] 35 | then 36 | echo "Vanishing the code" 37 | rm -rf aclocal.m4 autom4te.cache/ compile config.* configure depcomp \ 38 | INSTALL install-sh Makefile.in missing src/Makefile.in 39 | exit 0 40 | fi 41 | 42 | # Do not use clean option 43 | if [ "$1" = "clean" -a -e Makefile ] 44 | then 45 | echo "I can not clean. Use '$ make distclean'." 46 | exit 0 47 | fi 48 | 49 | # Do autoreconf 50 | autoreconf -fi \ 51 | && { echo " "; \ 52 | echo "Done. You can use the 'clean' option to vanish the source code."; \ 53 | echo "Example of use: $ ./autogen.sh clean"; \ 54 | echo " "; \ 55 | echo "Now run ./configure, make, and make install."; \ 56 | } \ 57 | || { echo "We have a problem..."; exit 1; } 58 | -------------------------------------------------------------------------------- /code-format.sh: -------------------------------------------------------------------------------- 1 | clang-format -i src/*[ch] 2 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # Copyright 1999-2003 Alla Bezroutchko 2 | # Copyright 2019-2021 Joao Eriberto Mota Filho 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 version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | dnl Process this file with autoconf to produce a configure script. 19 | AC_PREREQ([2.69]) 20 | AC_INIT([nbtscan],[1.7.2],[https://github.com/resurrecting-open-source-projects/nbtscan/issues]) 21 | AC_CANONICAL_TARGET 22 | AM_INIT_AUTOMAKE 23 | AC_CONFIG_SRCDIR([src/statusq.c]) 24 | 25 | dnl Checks for programs. 26 | AC_PROG_CC 27 | AC_PROG_INSTALL 28 | 29 | dnl Checks for libraries. 30 | AC_CHECK_LIB(xnet, socket) 31 | AC_CHECK_LIB(socket, socket) 32 | AC_CHECK_LIB(resolv, inet_aton) 33 | 34 | dnl Checks for header files. 35 | AC_PROG_EGREP 36 | 37 | AC_CHECK_HEADERS(sys/time.h) 38 | AC_CHECK_HEADERS(stdint.h) 39 | 40 | dnl Checks for typedefs, structures, and compiler characteristics. 41 | AC_CHECK_TYPE(uint8_t, [AC_DEFINE(my_uint8_t, uint8_t)], [AC_CHECK_TYPE(u_int8_t, [AC_DEFINE(my_uint8_t, u_int8_t)])]) 42 | AC_CHECK_TYPE(uint16_t, [AC_DEFINE(my_uint16_t, uint16_t)], [AC_CHECK_TYPE(u_int16_t, [AC_DEFINE(my_uint16_t, u_int16_t)])]) 43 | AC_CHECK_TYPE(uint32_t, [AC_DEFINE(my_uint32_t, uint32_t)], [AC_CHECK_TYPE(u_int32_t, [AC_DEFINE(my_uint32_t, u_int32_t)])]) 44 | 45 | AC_C_CONST 46 | 47 | dnl Checks for library functions. 48 | AC_CHECK_FUNCS(snprintf inet_aton socket) 49 | 50 | if test "$target_os" = cygwin; then 51 | AC_DEFINE(WINDOWS) 52 | BINDIR=c: 53 | TARGET=nbtscan.exe 54 | else 55 | AC_DEFINE(UNIX) 56 | BINDIR=$prefix/bin 57 | TARGET=nbtscan 58 | fi 59 | 60 | AC_SUBST(TARGET) 61 | AC_SUBST(BINDIR) 62 | 63 | AC_CONFIG_FILES([Makefile src/Makefile]) 64 | AC_OUTPUT 65 | -------------------------------------------------------------------------------- /doc/UPDATE-CHECK: -------------------------------------------------------------------------------- 1 | When updating, change the following files (if needed): 2 | 3 | - Update rights 4 | - Update ChangeLog 5 | - Check for spelling errors in ChangeLog, manpage and README. 6 | - man/create-man.sh (DATE, version) 7 | - Generate a new manpage. 8 | - Check final manpage with man command. 9 | - configure.ac (VERSION) 10 | - src/nbtscan.c (version) 11 | - Update README 12 | - Test in Debian Sid 13 | -------------------------------------------------------------------------------- /man/create-man.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2015-2020 Joao Eriberto Mota Filho 4 | # Create a manpage using txt2man command. Version 2.0, 2020-06-19. 5 | # This file is part of txt2man package for Debian. 6 | # This script can be used under BSD-3-Clause license. 7 | 8 | #-------------------------------------------------------- 9 | # Don't change the following lines 10 | TEST=$(txt2man -h 2> /dev/null) 11 | [ "$TEST" ] || { echo -e "\nYou need to install txt2man, from https://github.com/mvertes/txt2man.\n"; exit 1; } 12 | 13 | function create-man { 14 | txt2man -d "$T2M_DATE" -t $T2M_NAME -r $T2M_NAME-$T2M_VERSION -s $T2M_LEVEL -v "$T2M_DESC" $T2M_NAME.txt > $T2M_NAME.$T2M_LEVEL 15 | } 16 | #-------------------------------------------------------- 17 | 18 | # Put here all data for your first manpage (in T2M lines) 19 | T2M_DATE="13 Jan 2022" 20 | T2M_NAME=nbtscan 21 | T2M_VERSION=1.7.2 22 | T2M_LEVEL=1 23 | T2M_DESC="scan networks searching for NetBIOS information" 24 | create-man 25 | -------------------------------------------------------------------------------- /man/nbtscan.1: -------------------------------------------------------------------------------- 1 | .\" Text automatically generated by txt2man 2 | .TH nbtscan 1 "13 Jan 2022" "nbtscan-1.7.2" "scan networks searching for NetBIOS information" 3 | .SH NAME 4 | \fBnbtscan \fP- scan networks for NetBIOS name information 5 | \fB 6 | .SH SYNOPSIS 7 | .nf 8 | .fam C 9 | \fBnbtscan\fP [\fB-v\fP] [\fB-d\fP] [\fB-e\fP] [\fB-l\fP] [\fB-t\fP \fItimeout\fP] [\fB-b\fP \fIbandwidth\fP] [\fB-r\fP] [\fB-q\fP] 10 | [\fB-s\fP \fIseparator\fP] [\fB-h\fP] [\fB-m\fP \fIretransmits\fP] [\fB-f\fP \fIfilename\fP | \fItarget\fP] 11 | 12 | .fam T 13 | .fi 14 | .fam T 15 | .fi 16 | .SH DESCRIPTION 17 | NBTscan is a program for scanning IP networks for NetBIOS name information. It sends 18 | NetBIOS status query to each address in supplied range and lists received information 19 | in human readable form. For each responded host it lists IP address, NetBIOS computer 20 | name, logged-in user name and MAC address (such as Ethernet). 21 | .PP 22 | NBTscan produces a report like that: 23 | .PP 24 | .nf 25 | .fam C 26 | IP address NetBIOS Name Server User MAC address 27 | ----------------------------------------------------------------------- 28 | 192.168.1.2 MYCOMPUTER JDOE 00-a0-c9-12-34-56 29 | 192.168.1.5 WIN98COMP RROE 00-a0-c9-78-90-00 30 | 192.168.1.123 DPTSERVER ADMINISTRATOR 08-00-09-12-34-56 31 | 32 | .fam T 33 | .fi 34 | First column lists IP address of responded host. Second column is computer name. Third 35 | column indicates if this computer shares or is able to share files or printers. For NT 36 | machine it means that Server Service is running on this computer. For Windows 95 it 37 | means that "I want to be able to give others access to my files" or "I want to be able 38 | to allow others to print on my \fBprinter\fP(s)" checkbox is ticked (in Control 39 | Panel/Network/File and Print Sharing). Most often it means that this computer shares 40 | files. Third column shows user name. If no one is logged on from this computer it is 41 | same as computer name. Last column shows adapter MAC address. 42 | .PP 43 | If run with \fB-v\fP switch NBTscan lists whole NetBIOS name table for each responded address. 44 | The output looks like that: 45 | .PP 46 | .nf 47 | .fam C 48 | NetBIOS Name Table for Host 192.168.1.123: 49 | 50 | Name Service Type 51 | ---------------------------------------- 52 | DPTSERVER <00> UNIQUE 53 | DPTSERVER <20> UNIQUE 54 | DEPARTMENT <00> GROUP 55 | DEPARTMENT <1c> GROUP 56 | DEPARTMENT <1b> UNIQUE 57 | DEPARTMENT <1e> GROUP 58 | DPTSERVER <03> UNIQUE 59 | DEPARTMENT <1d> UNIQUE 60 | ??__MSBROWSE__? <01> GROUP 61 | INet~Services <1c> GROUP 62 | IS~DPTSERVER <00> UNIQUE 63 | DPTSERVER <01> UNIQUE 64 | 65 | Adapter address: 00-a0-c9-12-34-56 66 | ---------------------------------------- 67 | 68 | .fam T 69 | .fi 70 | .SH OPTIONS 71 | A summary of options is included below. 72 | .TP 73 | .B 74 | \fB-v\fP 75 | Verbose output. Print all names received from each host. 76 | .TP 77 | .B 78 | \fB-d\fP 79 | Dump packets. Print whole packet contents. Cannot be used 80 | with \fB-v\fP, \fB-s\fP or \fB-h\fP options. 81 | .TP 82 | .B 83 | \fB-e\fP 84 | Format output in /etc/hosts format. 85 | .TP 86 | .B 87 | \fB-l\fP 88 | Format output in lmhosts format. 89 | .TP 90 | .B 91 | \fB-t\fP <\fItimeout\fP> 92 | Wait \fItimeout\fP seconds for response. Default 1. 93 | .TP 94 | .B 95 | \fB-b\fP <\fIbandwidth\fP> 96 | Output throttling. Slow down output so that it uses no more that 97 | \fIbandwidth\fP bps. Useful on slow links, so that outgoing queries don't 98 | get dropped. 99 | .TP 100 | .B 101 | \fB-r\fP 102 | Use local port 137 for scans. Win95 boxes respond to this only. You 103 | need to be root to use this option. 104 | .TP 105 | .B 106 | \fB-q\fP 107 | Suppress banners and error messages. 108 | .TP 109 | .B 110 | \fB-s\fP <\fIseparator\fP> 111 | Script-friendly output. Don't print column and record headers, 112 | separate fields with \fIseparator\fP. 113 | .TP 114 | .B 115 | \fB-h\fP 116 | Print human-readable names for services. Can only be used with \fB-v\fP 117 | option. 118 | .TP 119 | .B 120 | \fB-m\fP <\fIretransmits\fP> 121 | Number of \fIretransmits\fP. Default 0. 122 | .TP 123 | .B 124 | \fB-f\fP <\fIfilename\fP> 125 | Take IP addresses to scan from file "\fIfilename\fP" 126 | .TP 127 | .B 128 | \fItarget\fP 129 | NBTscan is a command-line tool. You have to supply at least one 130 | argument, the address range, in one of three forms: 131 | .RS 132 | .TP 133 | .B 134 | xxx.xxx.xxx.xxx 135 | Single IP in dotted-decimal notation. Example: 192.168.1.1 136 | .TP 137 | .B 138 | xxx.xxx.xxx.xxx/xx 139 | Net address and subnet mask. Example: 192.168.1.0/24 140 | .TP 141 | .B 142 | xxx.xxx.xxx.xxx-xxx 143 | Address range. Example: 192.168.1.1-127. This will scan all 144 | addresses from 192.168.1.1 to 192.168.1.127 145 | .SH EXAMPLES 146 | Scans the whole C-class network: 147 | .PP 148 | .nf 149 | .fam C 150 | nbtscan 192.168.1.0/24 151 | 152 | .fam T 153 | .fi 154 | Scans the whole C-class network, using port 137: 155 | .PP 156 | .nf 157 | .fam C 158 | nbtscan -r 192.168.1.0/24 159 | 160 | .fam T 161 | .fi 162 | Scans a range from 192.168.1.25 to 192.168.1.137: 163 | .PP 164 | .nf 165 | .fam C 166 | nbtscan 192.168.1.25-137 167 | 168 | .fam T 169 | .fi 170 | Scans C-class network. Prints results in script-friendly format using colon as field 171 | \fIseparator\fP: 172 | .PP 173 | .nf 174 | .fam C 175 | nbtscan -v -s : 192.168.1.0/24 176 | 177 | .fam T 178 | .fi 179 | The last command produces output like that: 180 | .PP 181 | .nf 182 | .fam C 183 | 192.168.0.1:NT_SERVER:00U 184 | 192.168.0.1:MY_DOMAIN:00G 185 | 192.168.0.1:ADMINISTRATOR:03U 186 | 192.168.0.2:OTHER_BOX:00U 187 | \.\.\. 188 | 189 | .fam T 190 | .fi 191 | Scans IP addresses specified in file iplist: 192 | .PP 193 | .nf 194 | .fam C 195 | nbtscan -f iplist 196 | 197 | .fam T 198 | .fi 199 | .SH NETBIOS SUFFIXES 200 | NetBIOS Suffix, aka NetBIOS End Character (endchar), indicates service type for the 201 | registered name. The most known codes are listed below. (U = Unique Name, G = Group Name) 202 | .PP 203 | .nf 204 | .fam C 205 | Name Number(h) Type Usage 206 | -------------------------------------------------------------------------- 207 | 208 | 00 U Workstation Service 209 | 01 U Messenger Service 210 | <\\--__MSBROWSE__> 01 G Master Browser 211 | 03 U Messenger Service 212 | 06 U RAS Server Service 213 | 1F U NetDDE Service 214 | 20 U File Server Service 215 | 21 U RAS Client Service 216 | 22 U Exchange Interchange(MSMail Connector) 217 | 23 U Exchange Store 218 | 24 U Exchange Directory 219 | 30 U Modem Sharing Server Service 220 | 31 U Modem Sharing Client Service 221 | 43 U SMS Clients Remote Control 222 | 44 U SMS Administrators Remote Control Tool 223 | 45 U SMS Clients Remote Chat 224 | 46 U SMS Clients Remote Transfer 225 | 87 U Microsoft Exchange MTA 226 | 6A U Microsoft Exchange IMC 227 | BE U Network Monitor Agent 228 | BF U Network Monitor Application 229 | 03 U Messenger Service 230 | 00 G Domain Name 231 | 1B U Domain Master Browser 232 | 1C G Domain Controllers 233 | 1D U Master Browser 234 | 1E G Browser Service Elections 235 | 1C G IIS 236 | 00 U IIS 237 | 238 | .fam T 239 | .fi 240 | .SH FAQ 241 | .IP 1. 4 242 | NBTscan lists my Windows boxes just fine but does not list my Unixes or routers. Why? 243 | .PP 244 | R: That is the way it is supposed to work. NBTscan uses NetBIOS for scanning and NetBIOS 245 | is only implemented by Windows (and some software on Unix such as Samba). 246 | .IP 2. 4 247 | Why do I get "Connection reset by peer" errors on Windows 2000? 248 | .PP 249 | R: NBTscan uses port 137 UDP for sending queries. If the port is closed on destination 250 | host destination will reply with ICMP "Port unreachable" message. Most operating system 251 | will ignore this message. Windows 2000 reports it to the application as "Connection 252 | reset by peer" error. Just ignore it. 253 | .IP 3. 4 254 | Why NBTscan doesn't scan for shares? Are you going to add share scanning to NBTscan? 255 | .PP 256 | R: No. NBTscan uses UDP for what it does. That makes it very fast. Share scanning 257 | requires TCP. For one thing, it will make \fBnbtscan\fP more slow. Also adding share scanning 258 | means adding a lot of new code to \fBnbtscan\fP. There is a lot of good share scanners around, 259 | so there is no reason to duplicate that work. 260 | .IP 4. 4 261 | Why do I get 00-00-00-00-00-00 instead of MAC address when I scan a Samba box? 262 | .PP 263 | R: Because that's what Samba send in response to the query. Nbtscan just prints out what 264 | it gets. 265 | .SH AUTHOR 266 | NBTscan was created by Alla Bezroutchko . Currently is maintained by 267 | some volunteers at https://github.com/resurrecting-open-source-projects/\fBnbtscan\fP 268 | .PP 269 | This manual page was written for the first time by Ryszard Lach and 270 | rewritten, from scratch, by Joao Eriberto Mota Filho for the 271 | Debian GNU/Linux system (but may be used by others). 272 | -------------------------------------------------------------------------------- /man/nbtscan.txt: -------------------------------------------------------------------------------- 1 | NAME 2 | nbtscan - scan networks for NetBIOS name information 3 | 4 | SYNOPSIS 5 | nbtscan [-v] [-d] [-e] [-l] [-t timeout] [-b bandwidth] [-r] [-q] 6 | [-s separator] [-h] [-m retransmits] [-f filename | target] 7 | 8 | DESCRIPTION 9 | NBTscan is a program for scanning IP networks for NetBIOS name information. It sends 10 | NetBIOS status query to each address in supplied range and lists received information 11 | in human readable form. For each responded host it lists IP address, NetBIOS computer 12 | name, logged-in user name and MAC address (such as Ethernet). 13 | 14 | NBTscan produces a report like that: 15 | 16 | IP address NetBIOS Name Server User MAC address 17 | ----------------------------------------------------------------------- 18 | 192.168.1.2 MYCOMPUTER JDOE 00-a0-c9-12-34-56 19 | 192.168.1.5 WIN98COMP RROE 00-a0-c9-78-90-00 20 | 192.168.1.123 DPTSERVER ADMINISTRATOR 08-00-09-12-34-56 21 | 22 | First column lists IP address of responded host. Second column is computer name. Third 23 | column indicates if this computer shares or is able to share files or printers. For NT 24 | machine it means that Server Service is running on this computer. For Windows 95 it 25 | means that "I want to be able to give others access to my files" or "I want to be able 26 | to allow others to print on my printer(s)" checkbox is ticked (in Control 27 | Panel/Network/File and Print Sharing). Most often it means that this computer shares 28 | files. Third column shows user name. If no one is logged on from this computer it is 29 | same as computer name. Last column shows adapter MAC address. 30 | 31 | If run with -v switch NBTscan lists whole NetBIOS name table for each responded address. 32 | The output looks like that: 33 | 34 | NetBIOS Name Table for Host 192.168.1.123: 35 | 36 | Name Service Type 37 | ---------------------------------------- 38 | DPTSERVER <00> UNIQUE 39 | DPTSERVER <20> UNIQUE 40 | DEPARTMENT <00> GROUP 41 | DEPARTMENT <1c> GROUP 42 | DEPARTMENT <1b> UNIQUE 43 | DEPARTMENT <1e> GROUP 44 | DPTSERVER <03> UNIQUE 45 | DEPARTMENT <1d> UNIQUE 46 | ??__MSBROWSE__? <01> GROUP 47 | INet~Services <1c> GROUP 48 | IS~DPTSERVER <00> UNIQUE 49 | DPTSERVER <01> UNIQUE 50 | 51 | Adapter address: 00-a0-c9-12-34-56 52 | ---------------------------------------- 53 | 54 | OPTIONS 55 | A summary of options is included below. 56 | -v Verbose output. Print all names received from each host. 57 | -d Dump packets. Print whole packet contents. Cannot be used 58 | with -v, -s or -h options. 59 | -e Format output in /etc/hosts format. 60 | -l Format output in lmhosts format. 61 | -t Wait timeout seconds for response. Default 1. 62 | -b Output throttling. Slow down output so that it uses no more that 63 | bandwidth bps. Useful on slow links, so that outgoing queries don't 64 | get dropped. 65 | -r Use local port 137 for scans. Win95 boxes respond to this only. You 66 | need to be root to use this option. 67 | -q Suppress banners and error messages. 68 | -s Script-friendly output. Don't print column and record headers, 69 | separate fields with separator. 70 | -h Print human-readable names for services. Can only be used with -v 71 | option. 72 | -m Number of retransmits. Default 0. 73 | -f Take IP addresses to scan from file "filename" 74 | target NBTscan is a command-line tool. You have to supply at least one 75 | argument, the address range, in one of three forms: 76 | 77 | xxx.xxx.xxx.xxx Single IP in dotted-decimal notation. Example: 192.168.1.1 78 | xxx.xxx.xxx.xxx/xx Net address and subnet mask. Example: 192.168.1.0/24 79 | xxx.xxx.xxx.xxx-xxx Address range. Example: 192.168.1.1-127. This will scan all 80 | addresses from 192.168.1.1 to 192.168.1.127 81 | 82 | EXAMPLES 83 | Scans the whole C-class network: 84 | 85 | nbtscan 192.168.1.0/24 86 | 87 | Scans the whole C-class network, using port 137: 88 | 89 | nbtscan -r 192.168.1.0/24 90 | 91 | Scans a range from 192.168.1.25 to 192.168.1.137: 92 | 93 | nbtscan 192.168.1.25-137 94 | 95 | Scans C-class network. Prints results in script-friendly format using colon as field 96 | separator: 97 | 98 | nbtscan -v -s : 192.168.1.0/24 99 | 100 | The last command produces output like that: 101 | 102 | 192.168.0.1:NT_SERVER:00U 103 | 192.168.0.1:MY_DOMAIN:00G 104 | 192.168.0.1:ADMINISTRATOR:03U 105 | 192.168.0.2:OTHER_BOX:00U 106 | ... 107 | 108 | Scans IP addresses specified in file iplist: 109 | 110 | nbtscan -f iplist 111 | 112 | NETBIOS SUFFIXES 113 | NetBIOS Suffix, aka NetBIOS End Character (endchar), indicates service type for the 114 | registered name. The most known codes are listed below. (U = Unique Name, G = Group Name) 115 | 116 | Name Number(h) Type Usage 117 | -------------------------------------------------------------------------- 118 | 119 | 00 U Workstation Service 120 | 01 U Messenger Service 121 | <\\--__MSBROWSE__> 01 G Master Browser 122 | 03 U Messenger Service 123 | 06 U RAS Server Service 124 | 1F U NetDDE Service 125 | 20 U File Server Service 126 | 21 U RAS Client Service 127 | 22 U Exchange Interchange(MSMail Connector) 128 | 23 U Exchange Store 129 | 24 U Exchange Directory 130 | 30 U Modem Sharing Server Service 131 | 31 U Modem Sharing Client Service 132 | 43 U SMS Clients Remote Control 133 | 44 U SMS Administrators Remote Control Tool 134 | 45 U SMS Clients Remote Chat 135 | 46 U SMS Clients Remote Transfer 136 | 87 U Microsoft Exchange MTA 137 | 6A U Microsoft Exchange IMC 138 | BE U Network Monitor Agent 139 | BF U Network Monitor Application 140 | 03 U Messenger Service 141 | 00 G Domain Name 142 | 1B U Domain Master Browser 143 | 1C G Domain Controllers 144 | 1D U Master Browser 145 | 1E G Browser Service Elections 146 | 1C G IIS 147 | 00 U IIS 148 | 149 | FAQ 150 | 1. NBTscan lists my Windows boxes just fine but does not list my Unixes or routers. Why? 151 | 152 | R: That is the way it is supposed to work. NBTscan uses NetBIOS for scanning and NetBIOS 153 | is only implemented by Windows (and some software on Unix such as Samba). 154 | 155 | 2. Why do I get "Connection reset by peer" errors on Windows 2000? 156 | 157 | R: NBTscan uses port 137 UDP for sending queries. If the port is closed on destination 158 | host destination will reply with ICMP "Port unreachable" message. Most operating system 159 | will ignore this message. Windows 2000 reports it to the application as "Connection 160 | reset by peer" error. Just ignore it. 161 | 162 | 3. Why NBTscan doesn't scan for shares? Are you going to add share scanning to NBTscan? 163 | 164 | R: No. NBTscan uses UDP for what it does. That makes it very fast. Share scanning 165 | requires TCP. For one thing, it will make nbtscan more slow. Also adding share scanning 166 | means adding a lot of new code to nbtscan. There is a lot of good share scanners around, 167 | so there is no reason to duplicate that work. 168 | 169 | 4. Why do I get 00-00-00-00-00-00 instead of MAC address when I scan a Samba box? 170 | 171 | R: Because that's what Samba send in response to the query. Nbtscan just prints out what 172 | it gets. 173 | 174 | AUTHOR 175 | NBTscan was created by Alla Bezroutchko . Currently is maintained by 176 | some volunteers at https://github.com/resurrecting-open-source-projects/nbtscan 177 | 178 | This manual page was written for the first time by Ryszard Lach and 179 | rewritten, from scratch, by Joao Eriberto Mota Filho for the 180 | Debian GNU/Linux system (but may be used by others). 181 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | # Copyright 1999-2003 Alla Bezroutchko 2 | # Copyright 2018-2022 Joao Eriberto Mota Filho 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 version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | bin_PROGRAMS = nbtscan 19 | 20 | nbtscan_SOURCES = nbtscan.c \ 21 | statusq.c statusq.h \ 22 | range.c range.h \ 23 | list.c list.h \ 24 | errors.h 25 | -------------------------------------------------------------------------------- /src/errors.h: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2021 Mayco Souza Berghetti 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #if !defined ERRORS_H 21 | #define ERRORS_H 22 | 23 | #define err_die( error, quiet ) \ 24 | if ( !quiet ) \ 25 | { \ 26 | perror ( error ); \ 27 | exit ( 1 ); \ 28 | }; 29 | 30 | #define err_print( error, quiet ) \ 31 | if ( !quiet ) \ 32 | perror ( error ); 33 | 34 | #endif /* ERRORS_H */ 35 | -------------------------------------------------------------------------------- /src/list.c: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2004 Jochen Friedrich 4 | # Copyright 2021 Mayco Souza Berghetti 5 | # 6 | # This program is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU General Public License 8 | # as published by the Free Software Foundation; either version 2 9 | # of the License, or (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | #include 22 | #include "list.h" 23 | #include 24 | #include "errors.h" 25 | 26 | extern int quiet; 27 | 28 | struct list * 29 | new_list () 30 | { 31 | struct list *lst; 32 | 33 | if ( ( lst = malloc ( sizeof ( struct list ) ) ) == NULL ) 34 | err_die ( "Malloc failed", quiet ); 35 | lst->head = NULL; 36 | return lst; 37 | } 38 | 39 | struct list_item * 40 | new_list_item ( unsigned long content ) 41 | { 42 | struct list_item *lst_item; 43 | 44 | if ( ( lst_item = malloc ( sizeof ( struct list_item ) ) ) == NULL ) 45 | err_die ( "Malloc failed", quiet ); 46 | 47 | lst_item->next = NULL; 48 | lst_item->prev = NULL; 49 | lst_item->content = content; 50 | return lst_item; 51 | } 52 | 53 | void 54 | delete_list ( struct list *list ) 55 | { 56 | struct list_item *pointer; 57 | 58 | pointer = list->head; 59 | 60 | if ( pointer ) 61 | { 62 | while ( pointer->next ) 63 | pointer = pointer->next; /* Find last list element */ 64 | 65 | /* Go back from tail to head deleteing list items on the way */ 66 | while ( pointer->prev ) 67 | { 68 | pointer = pointer->prev; 69 | free ( pointer->next ); 70 | } 71 | free ( pointer ); 72 | } 73 | free ( list ); 74 | } 75 | 76 | int 77 | compare ( struct list_item *item1, struct list_item *item2 ) 78 | { 79 | if ( item2 == NULL ) 80 | return ERROR; 81 | if ( item1 == NULL ) 82 | return 1; 83 | if ( item1->content == item2->content ) 84 | return 0; 85 | if ( item1->content > item2->content ) 86 | return 1; 87 | 88 | return -1; 89 | } 90 | 91 | int 92 | insert ( struct list *lst, unsigned long content ) 93 | { 94 | struct list_item *temp_item, *item; 95 | int cmp; 96 | 97 | item = new_list_item ( content ); 98 | 99 | cmp = compare ( lst->head, item ); 100 | if ( lst->head == NULL ) 101 | { 102 | lst->head = item; 103 | return 1; 104 | } 105 | else if ( cmp == 1 ) 106 | { 107 | item->next = lst->head; 108 | lst->head = item; 109 | item->prev = NULL; 110 | return 1; 111 | } 112 | else if ( cmp == 0 ) 113 | { 114 | free ( item ); 115 | return 0; 116 | } 117 | else if ( cmp == -1 ) 118 | { 119 | temp_item = lst->head; 120 | while ( compare ( temp_item->next, item ) == -1 ) 121 | { 122 | temp_item = temp_item->next; 123 | } 124 | /* temp_item points to last list element less then item */ 125 | /* we shall insert item after temp_item */ 126 | if ( compare ( temp_item->next, item ) == 0 ) 127 | { 128 | free ( item ); 129 | return 0; 130 | } 131 | else if ( compare ( temp_item->next, item ) == ERROR ) 132 | { 133 | free ( item ); 134 | return ERROR; 135 | } 136 | else if ( compare ( temp_item->next, item ) == 1 ) 137 | { 138 | item->next = temp_item->next; 139 | item->prev = temp_item; 140 | if ( temp_item->next ) 141 | temp_item->next->prev = item; 142 | temp_item->next = item; 143 | return 1; 144 | } 145 | } 146 | else if ( compare ( lst->head, item ) == ERROR ) 147 | { 148 | free ( item ); 149 | return ERROR; 150 | } 151 | return 0; 152 | } 153 | 154 | int 155 | in_list ( struct list *lst, unsigned long content ) 156 | { 157 | struct list_item *temp_item; 158 | struct list_item item = { .content = content }; 159 | 160 | if ( lst->head == NULL ) 161 | return 0; 162 | 163 | temp_item = lst->head; 164 | 165 | while ( compare ( temp_item, &item ) < 0 ) 166 | temp_item = temp_item->next; 167 | 168 | // return 1 is equal or 0 not equal 169 | return !compare ( temp_item, &item ); 170 | } 171 | -------------------------------------------------------------------------------- /src/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2021 Mayco Souza Berghetti 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 | */ 19 | 20 | #define ERROR 12345 21 | 22 | struct list_item 23 | { 24 | struct list_item *next; 25 | struct list_item *prev; 26 | unsigned long content; 27 | }; 28 | 29 | struct list 30 | { 31 | struct list_item *head; 32 | }; 33 | 34 | struct list * 35 | new_list (); 36 | 37 | struct list_item * 38 | new_list_item ( unsigned long content ); 39 | 40 | void 41 | delete_list ( struct list *list ); 42 | 43 | int 44 | compare ( struct list_item *item1, struct list_item *item2 ); 45 | 46 | int 47 | insert ( struct list *lst, unsigned long content ); 48 | 49 | int 50 | in_list ( struct list *lst, unsigned long content ); 51 | -------------------------------------------------------------------------------- /src/nbtscan.c: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2004 Jochen Friedrich 4 | # Copyright 2008 Walter "Wallie" Jakob Doekes 5 | # Copyright 2015 Johan Eidenvall 6 | # Copyright 2021 Mayco Souza Berghetti 7 | # 8 | # This program is free software; you can redistribute it and/or 9 | # modify it under the terms of the GNU General Public License 10 | # as published by the Free Software Foundation; either version 2 11 | # of the License, or (at your option) any later version. 12 | # 13 | # This program is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with this program; if not, write to the Free Software 20 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #if HAVE_STDINT_H 33 | #include 34 | #endif 35 | #include "statusq.h" 36 | #include "range.h" 37 | #include "list.h" 38 | #include "errors.h" 39 | #include "time.h" 40 | 41 | int quiet = 0; 42 | 43 | static void 44 | print_banner ( void ) 45 | { 46 | puts ( "\nNBTscan version 1.7.2.\n" 47 | "This is a free software and it comes with absolutely no " 48 | "warranty.\n" 49 | "You can use, distribute and modify it under terms of GNU GPL " 50 | "2+.\n\n" ); 51 | } 52 | 53 | static void 54 | usage ( void ) 55 | { 56 | puts ( "Usage:\nnbtscan [-v] [-d] [-e] [-l] [-t timeout] [-b bandwidth] " 57 | "[-r] [-q] [-s separator] [-m retransmits] (-f " 58 | "filename)|() \n" 59 | "\t-v\t\tverbose output. Print all names received\n" 60 | "\t\t\tfrom each host\n" 61 | "\t-d\t\tdump packets. Print whole packet contents.\n" 62 | "\t-e\t\tFormat output in /etc/hosts format.\n" 63 | "\t-l\t\tFormat output in lmhosts format.\n" 64 | "\t\t\tCannot be used with -v, -s or -h options.\n" 65 | "\t-t timeout\twait timeout milliseconds for response.\n" 66 | "\t\t\tDefault 1000.\n" 67 | "\t-b bandwidth\tOutput throttling. Slow down output\n" 68 | "\t\t\tso that it uses no more that bandwidth bps.\n" 69 | "\t\t\tUseful on slow links, so that ougoing queries\n" 70 | "\t\t\tdon't get dropped.\n" 71 | "\t-r\t\tuse local port 137 for scans. Win95 boxes\n" 72 | "\t\t\trespond to this only.\n" 73 | "\t\t\tYou need to be root to use this option on Unix.\n" 74 | "\t-q\t\tSuppress banners and error messages,\n" 75 | "\t-s separator\tScript-friendly output. Don't print\n" 76 | "\t\t\tcolumn and record headers, separate fields with " 77 | "separator.\n" 78 | "\t-h\t\tPrint human-readable names for services.\n" 79 | "\t\t\tCan only be used with -v option.\n" 80 | "\t-m retransmits\tNumber of retransmits. Default 0.\n" 81 | "\t-f filename\tTake IP addresses to scan from file filename.\n" 82 | "\t\t\t-f - makes nbtscan take IP addresses from stdin.\n" 83 | "\t\twhat to scan. Can either be single IP\n" 84 | "\t\t\tlike 192.168.1.1 or\n" 85 | "\t\t\trange of addresses in one of two forms: \n" 86 | "\t\t\txxx.xxx.xxx.xxx/xx or xxx.xxx.xxx.xxx-xxx.\n" 87 | "Examples:\n" 88 | "\tnbtscan -r 192.168.1.0/24\n" 89 | "\t\tScans the whole C-class network.\n" 90 | "\tnbtscan 192.168.1.25-137\n" 91 | "\t\tScans a range from 192.168.1.25 to 192.168.1.137\n" 92 | "\tnbtscan -v -s : 192.168.1.0/24\n" 93 | "\t\tScans C-class network. Prints results in script-friendly\n" 94 | "\t\tformat using colon as field separator.\n" 95 | "\t\tProduces output like that:\n" 96 | "\t\t192.168.0.1:NT_SERVER:00U\n" 97 | "\t\t192.168.0.1:MY_DOMAIN:00G\n" 98 | "\t\t192.168.0.1:ADMINISTRATOR:03U\n" 99 | "\t\t192.168.0.2:OTHER_BOX:00U\n" 100 | "\t\t...\n" 101 | "\tnbtscan -f iplist\n" 102 | "\t\tScans IP addresses specified in file iplist." ); 103 | exit ( 2 ); 104 | } 105 | 106 | static int 107 | set_range ( char *range_str, struct ip_range *range_struct ) 108 | { 109 | if ( is_ip ( range_str, range_struct ) ) 110 | return 1; 111 | if ( is_range1 ( range_str, range_struct ) ) 112 | return 1; 113 | if ( is_range2 ( range_str, range_struct ) ) 114 | return 1; 115 | return 0; 116 | } 117 | 118 | static void 119 | print_header ( void ) 120 | { 121 | printf ( "%-17s%-17s%-10s%-17s%-17s\n", 122 | "IP address", 123 | "NetBIOS Name", 124 | "Server", 125 | "User", 126 | "MAC address" ); 127 | puts ( "-------------------------------------------------------------------" 128 | "-----------" ); 129 | } 130 | 131 | #define DUP( code ) code, code 132 | 133 | static void 134 | print_nb_host_info_header ( const nbname_response_header_t *header ) 135 | { 136 | printf ( "Transaction ID: 0x%04x (%d)\n", DUP ( header->transaction_id ) ); 137 | printf ( "Flags: 0x%04x (%d)\n", DUP ( header->flags ) ); 138 | printf ( "Question count: 0x%04x (%d)\n", DUP ( header->question_count ) ); 139 | printf ( "Answer count: 0x%04x (%d)\n", DUP ( header->answer_count ) ); 140 | printf ( "Name service count: 0x%04x (%d)\n", 141 | DUP ( header->name_service_count ) ); 142 | printf ( "Additional record count: 0x%04x (%d)\n", 143 | DUP ( header->additional_record_count ) ); 144 | printf ( "Question name: %s\n", header->question_name ); 145 | printf ( "Question type: 0x%04x (%d)\n", DUP ( header->question_type ) ); 146 | printf ( "Question class: 0x%04x (%d)\n", DUP ( header->question_class ) ); 147 | printf ( "Time to live: 0x%08x (%d)\n", DUP ( header->ttl ) ); 148 | printf ( "Rdata length: 0x%04x (%d)\n", DUP ( header->rdata_length ) ); 149 | printf ( "Number of names: 0x%02x (%d)\n", DUP ( header->number_of_names ) ); 150 | } 151 | 152 | static void 153 | print_nb_host_info_footer ( const nbname_response_footer_t *footer ) 154 | { 155 | printf ( "Adapter address: %02x:%02x:%02x:%02x:%02x:%02x\n", 156 | footer->adapter_address[0], 157 | footer->adapter_address[1], 158 | footer->adapter_address[2], 159 | footer->adapter_address[3], 160 | footer->adapter_address[4], 161 | footer->adapter_address[5] ); 162 | 163 | printf ( "Version major: 0x%02x (%d)\n", DUP ( footer->version_major ) ); 164 | printf ( "Version minor: 0x%02x (%d)\n", DUP ( footer->version_minor ) ); 165 | printf ( "Duration: 0x%04x (%d)\n", DUP ( footer->duration ) ); 166 | printf ( "FRMRs Received: 0x%04x (%d)\n", DUP ( footer->frmps_received ) ); 167 | 168 | printf ( "FRMRs Transmitted: 0x%04x (%d)\n", 169 | DUP ( footer->frmps_transmitted ) ); 170 | 171 | printf ( "IFrame Receive errors: 0x%04x (%d)\n", 172 | DUP ( footer->iframe_receive_errors ) ); 173 | 174 | printf ( "Transmit aborts: 0x%04x (%d)\n", DUP ( footer->transmit_aborts ) ); 175 | printf ( "Transmitted: 0x%08x (%d)\n", DUP ( footer->transmitted ) ); 176 | printf ( "Received: 0x%08x (%d)\n", DUP ( footer->received ) ); 177 | 178 | printf ( "IFrame transmit errors: 0x%04x (%d)\n", 179 | DUP ( footer->iframe_transmit_errors ) ); 180 | 181 | printf ( "No receive buffers: 0x%04x (%d)\n", 182 | DUP ( footer->no_receive_buffer ) ); 183 | 184 | printf ( "tl timeouts: 0x%04x (%d)\n", DUP ( footer->tl_timeouts ) ); 185 | printf ( "ti timeouts: 0x%04x (%d)\n", DUP ( footer->ti_timeouts ) ); 186 | printf ( "Free NCBS: 0x%04x (%d)\n", DUP ( footer->free_ncbs ) ); 187 | printf ( "NCBS: 0x%04x (%d)\n", DUP ( footer->ncbs ) ); 188 | printf ( "Max NCBS: 0x%04x (%d)\n", DUP ( footer->max_ncbs ) ); 189 | 190 | printf ( "No transmit buffers: 0x%04x (%d)\n", 191 | DUP ( footer->no_transmit_buffers ) ); 192 | 193 | printf ( "Max datagram: 0x%04x (%d)\n", DUP ( footer->max_datagram ) ); 194 | 195 | printf ( "Pending sessions: 0x%04x (%d)\n", 196 | DUP ( footer->pending_sessions ) ); 197 | 198 | printf ( "Max sessions: 0x%04x (%d)\n", DUP ( footer->max_sessions ) ); 199 | printf ( "Packet sessions: 0x%04x (%d)\n", DUP ( footer->packet_sessions ) ); 200 | } 201 | 202 | static void 203 | d_print_hostinfo ( struct in_addr addr, const struct nb_host_info *hostinfo ) 204 | { 205 | int i; 206 | unsigned char service; /* 16th byte of NetBIOS name */ 207 | char name[16]; 208 | 209 | printf ( "\nPacket dump for Host %s:\n\n", inet_ntoa ( addr ) ); 210 | if ( hostinfo->is_broken ) 211 | printf ( "Incomplete packet, %d bytes long.\n", hostinfo->is_broken ); 212 | 213 | if ( hostinfo->header ) 214 | print_nb_host_info_header ( hostinfo->header ); 215 | 216 | if ( hostinfo->names ) 217 | { 218 | printf ( "Names received:\n" ); 219 | for ( i = 0; i < hostinfo->header->number_of_names; i++ ) 220 | { 221 | service = hostinfo->names[i].ascii_name[15]; 222 | strncpy ( name, hostinfo->names[i].ascii_name, 15 ); 223 | name[15] = 0; 224 | printf ( "%-17s Service: 0x%02x Flags: 0x%04x\n", 225 | name, 226 | service, 227 | hostinfo->names[i].rr_flags ); 228 | } 229 | } 230 | 231 | if ( hostinfo->footer ) 232 | print_nb_host_info_footer ( hostinfo->footer ); 233 | } 234 | 235 | static int 236 | v_print_hostinfo ( struct in_addr addr, 237 | const struct nb_host_info *hostinfo, 238 | char *sf, 239 | int hr ) 240 | { 241 | int i, unique; 242 | my_uint8_t service; /* 16th byte of NetBIOS name */ 243 | char name[16]; 244 | 245 | if ( !sf ) 246 | { 247 | printf ( "\nNetBIOS Name Table for Host %s:\n\n", inet_ntoa ( addr ) ); 248 | if ( hostinfo->is_broken ) 249 | printf ( "Incomplete packet, %d bytes long.\n", hostinfo->is_broken ); 250 | 251 | printf ( "%-17s%-17s%-17s\n", "Name", "Service", "Type" ); 252 | printf ( "----------------------------------------\n" ); 253 | } 254 | if ( hostinfo->header && hostinfo->names ) 255 | { 256 | for ( i = 0; i < hostinfo->header->number_of_names; i++ ) 257 | { 258 | service = hostinfo->names[i].ascii_name[15]; 259 | strncpy ( name, hostinfo->names[i].ascii_name, 15 ); 260 | name[15] = 0; 261 | unique = !( hostinfo->names[i].rr_flags & 0x0080 ); 262 | if ( sf ) 263 | { 264 | printf ( "%s%s%s%s", inet_ntoa ( addr ), sf, name, sf ); 265 | if ( hr ) 266 | printf ( "%s\n", getnbservicename ( service, unique, name ) ); 267 | else 268 | { 269 | printf ( "%02x", service ); 270 | if ( unique ) 271 | printf ( "U\n" ); 272 | else 273 | printf ( "G\n" ); 274 | } 275 | } 276 | else 277 | { 278 | printf ( "%-17s", name ); 279 | if ( hr ) 280 | printf ( "%s\n", getnbservicename ( service, unique, name ) ); 281 | else 282 | { 283 | printf ( "<%02x>", service ); 284 | if ( unique ) 285 | printf ( " UNIQUE\n" ); 286 | else 287 | printf ( " GROUP\n" ); 288 | } 289 | } 290 | } 291 | } 292 | 293 | if ( hostinfo->footer ) 294 | { 295 | if ( sf ) 296 | printf ( "%s%sMAC%s", inet_ntoa ( addr ), sf, sf ); 297 | else 298 | printf ( "\nAdapter address: " ); 299 | printf ( "%02x:%02x:%02x:%02x:%02x:%02x\n", 300 | hostinfo->footer->adapter_address[0], 301 | hostinfo->footer->adapter_address[1], 302 | hostinfo->footer->adapter_address[2], 303 | hostinfo->footer->adapter_address[3], 304 | hostinfo->footer->adapter_address[4], 305 | hostinfo->footer->adapter_address[5] ); 306 | } 307 | if ( !sf ) 308 | printf ( "----------------------------------------\n" ); 309 | return 1; 310 | } 311 | 312 | static int 313 | print_hostinfo ( struct in_addr addr, struct nb_host_info *hostinfo, char *sf ) 314 | { 315 | int i; 316 | unsigned char service; /* 16th byte of NetBIOS name */ 317 | char comp_name[16], user_name[16]; 318 | int is_server = 0; 319 | int unique; 320 | int first_name = 1; 321 | 322 | strncpy ( comp_name, "", 15 ); 323 | strncpy ( user_name, "", 15 ); 324 | if ( hostinfo->header && hostinfo->names ) 325 | { 326 | for ( i = 0; i < hostinfo->header->number_of_names; i++ ) 327 | { 328 | service = hostinfo->names[i].ascii_name[15]; 329 | unique = !( hostinfo->names[i].rr_flags & 0x0080 ); 330 | if ( service == 0 && unique && first_name ) 331 | { 332 | /* Unique name, workstation service - this is computer name */ 333 | strncpy ( comp_name, hostinfo->names[i].ascii_name, 15 ); 334 | comp_name[15] = 0; 335 | first_name = 0; 336 | } 337 | if ( service == 0x20 && unique ) 338 | { 339 | is_server = 1; 340 | } 341 | if ( service == 0x03 && unique ) 342 | { 343 | strncpy ( user_name, hostinfo->names[i].ascii_name, 15 ); 344 | user_name[15] = 0; 345 | } 346 | } 347 | } 348 | 349 | if ( sf ) 350 | { 351 | printf ( "%s%s%s%s", inet_ntoa ( addr ), sf, comp_name, sf ); 352 | if ( is_server ) 353 | printf ( "" ); 354 | printf ( "%s%s%s", sf, user_name, sf ); 355 | } 356 | else 357 | { 358 | printf ( "%-17s%-17s", inet_ntoa ( addr ), comp_name ); 359 | if ( is_server ) 360 | printf ( "%-10s", "" ); 361 | else 362 | printf ( "%-10s", "" ); 363 | printf ( "%-17s", user_name ); 364 | } 365 | if ( hostinfo->footer ) 366 | { 367 | printf ( "%02x:%02x:%02x:%02x:%02x:%02x\n", 368 | hostinfo->footer->adapter_address[0], 369 | hostinfo->footer->adapter_address[1], 370 | hostinfo->footer->adapter_address[2], 371 | hostinfo->footer->adapter_address[3], 372 | hostinfo->footer->adapter_address[4], 373 | hostinfo->footer->adapter_address[5] ); 374 | } 375 | else 376 | { 377 | printf ( "\n" ); 378 | } 379 | return 1; 380 | } 381 | 382 | /* Print hostinfo in /etc/hosts or lmhosts format */ 383 | /* If l is true adds #PRE to each line of output (for lmhosts) */ 384 | 385 | static void 386 | l_print_hostinfo ( struct in_addr addr, struct nb_host_info *hostinfo, int l ) 387 | { 388 | int i; 389 | unsigned char service; /* 16th byte of NetBIOS name */ 390 | char comp_name[16]; 391 | int unique; 392 | int first_name = 1; 393 | 394 | strncpy ( comp_name, "", 15 ); 395 | 396 | if ( hostinfo->header && hostinfo->names ) 397 | { 398 | for ( i = 0; i < hostinfo->header->number_of_names; i++ ) 399 | { 400 | service = hostinfo->names[i].ascii_name[15]; 401 | unique = !( hostinfo->names[i].rr_flags & 0x0080 ); 402 | if ( service == 0 && unique && first_name ) 403 | { 404 | /* Unique name, workstation service - this is computer name */ 405 | strncpy ( comp_name, hostinfo->names[i].ascii_name, 15 ); 406 | comp_name[15] = 0; 407 | first_name = 0; 408 | } 409 | } 410 | } 411 | printf ( "%s\t%s", inet_ntoa ( addr ), comp_name ); 412 | if ( l ) 413 | printf ( "\t#PRE" ); 414 | printf ( "\n" ); 415 | } 416 | 417 | #define BUFFSIZE 1024 418 | 419 | int 420 | main ( int argc, char *argv[] ) 421 | { 422 | int timeout = 1000, verbose = 0, use137 = 0, ch, dump = 0, bandwidth = 0, 423 | send_ok = 0, hr = 0, etc_hosts = 0, lmhosts = 0; 424 | extern char *optarg; 425 | extern int optind; 426 | char *target_string, *temp_target_string = NULL; 427 | char *sf = NULL; 428 | char *filename = NULL; 429 | struct ip_range range; 430 | void *buff; 431 | int sock; 432 | socklen_t addr_size; 433 | struct sockaddr_in src_sockaddr, dest_sockaddr; 434 | struct in_addr *prev_in_addr = NULL; 435 | struct in_addr *next_in_addr; 436 | struct timeval select_timeout, last_send_time, current_time, diff_time, 437 | send_interval; 438 | struct timeval transmit_started, now, recv_time; 439 | struct nb_host_info *hostinfo; 440 | fd_set fdsr; 441 | fd_set fdsw; 442 | int size; 443 | struct list *scanned; 444 | my_uint32_t 445 | rtt_base; /* Base time (seconds) for round trip time calculations */ 446 | float rtt; /* most recent measured RTT, seconds */ 447 | float srtt = 0; /* smoothed rtt estimator, seconds */ 448 | float rttvar = 0.75; /* smoothed mean deviation, seconds */ 449 | double delta; /* used in retransmit timeout calculations */ 450 | int rto, retransmits = 0, more_to_send = 1, i; 451 | char errmsg[80]; 452 | char str[80]; 453 | FILE *targetlist = NULL; 454 | 455 | /* Parse supplied options */ 456 | /**************************/ 457 | if ( argc < 2 ) 458 | { 459 | print_banner (); 460 | usage (); 461 | } 462 | 463 | while ( ( ch = getopt ( argc, argv, "vrdelqhm:s:t:b:f:" ) ) != -1 ) 464 | switch ( ch ) 465 | { 466 | case 'v': 467 | verbose = 1; 468 | break; 469 | case 't': 470 | timeout = atoi ( optarg ); 471 | if ( timeout == 0 ) 472 | { 473 | printf ( "Bad timeout value: %s\n", optarg ); 474 | usage (); 475 | } 476 | break; 477 | case 'r': 478 | #if defined WINDOWS 479 | printf ( "Warning: -r option not supported under Windows. Running " 480 | "without it.\n\n" ); 481 | #else 482 | use137 = 1; 483 | #endif 484 | break; 485 | case 'd': 486 | dump = 1; 487 | break; 488 | case 'e': 489 | etc_hosts = 1; 490 | break; 491 | case 'l': 492 | lmhosts = 1; 493 | break; 494 | case 'q': 495 | quiet = 1; /* Global variable */ 496 | break; 497 | case 'b': 498 | bandwidth = atoi ( optarg ); 499 | if ( bandwidth == 0 ) 500 | err_print ( "Bad bandwidth value, ignoring it", quiet ); 501 | break; 502 | case 'h': 503 | hr = 1; /* human readable service names instead of hex codes */ 504 | break; 505 | case 's': 506 | sf = optarg; /* script-friendly output format */ 507 | break; 508 | case 'm': 509 | retransmits = atoi ( optarg ); 510 | if ( retransmits == 0 ) 511 | { 512 | printf ( "Bad number of retransmits: %s\n", optarg ); 513 | usage (); 514 | } 515 | break; 516 | case 'f': 517 | filename = optarg; 518 | break; 519 | default: 520 | print_banner (); 521 | usage (); 522 | } 523 | 524 | if ( dump && verbose ) 525 | { 526 | printf ( "Cannot be used with both dump (-d) and verbose (-v) " 527 | "options.\n" ); 528 | usage (); 529 | } 530 | 531 | if ( dump && sf ) 532 | { 533 | printf ( "Cannot be used with both dump (-d) and script-friendly (-s) " 534 | "options.\n" ); 535 | usage (); 536 | } 537 | 538 | if ( dump && lmhosts ) 539 | { 540 | printf ( "Cannot be used with both dump (-d) and lmhosts (-l) " 541 | "options.\n" ); 542 | usage (); 543 | } 544 | 545 | if ( dump && etc_hosts ) 546 | { 547 | printf ( "Cannot be used with both dump (-d) and /etc/hosts (-e) " 548 | "options.\n" ); 549 | usage (); 550 | } 551 | 552 | if ( verbose && lmhosts ) 553 | { 554 | printf ( "Cannot be used with both verbose (-v) and lmhosts (-l) " 555 | "options.\n" ); 556 | usage (); 557 | } 558 | 559 | if ( verbose && etc_hosts ) 560 | { 561 | printf ( "Cannot be used with both verbose (-v) and /etc/hosts (-e) " 562 | "options.\n" ); 563 | usage (); 564 | } 565 | 566 | if ( lmhosts && etc_hosts ) 567 | { 568 | printf ( "Cannot be used with both lmhosts (-l) and /etc/hosts (-e) " 569 | "options.\n" ); 570 | usage (); 571 | } 572 | 573 | if ( dump && hr ) 574 | { 575 | printf ( "Cannot be used with both dump (-d) and \"human-readable " 576 | "service names\" (-h) options.\n" ); 577 | usage (); 578 | } 579 | 580 | if ( hr && !verbose ) 581 | { 582 | printf ( "\"Human-readable service names\" (-h) option cannot be used " 583 | "without verbose (-v) option.\n" ); 584 | usage (); 585 | } 586 | 587 | if ( filename ) 588 | { 589 | if ( strcmp ( filename, "-" ) == 0 ) 590 | { /* Get IP addresses from stdin */ 591 | targetlist = stdin; 592 | target_string = "STDIN"; 593 | } 594 | else 595 | { 596 | targetlist = fopen ( filename, "r" ); 597 | target_string = filename; 598 | } 599 | if ( !targetlist ) 600 | { 601 | snprintf ( errmsg, 80, "Cannot open file %s", filename ); 602 | err_die ( errmsg, quiet ); 603 | } 604 | } 605 | else 606 | { 607 | argc -= optind; 608 | argv += optind; 609 | if ( argc != 1 ) 610 | usage (); 611 | 612 | if ( ( target_string = strdup ( argv[0] ) ) == NULL ) 613 | err_die ( "Malloc failed.\n", quiet ); 614 | 615 | if ( !set_range ( target_string, &range ) ) 616 | { 617 | printf ( "Error: %s is not an IP address or address range.\n", 618 | target_string ); 619 | free ( target_string ); 620 | usage (); 621 | } 622 | 623 | temp_target_string = target_string; 624 | } 625 | 626 | if ( !( quiet || sf || lmhosts || etc_hosts ) ) 627 | printf ( "Doing NBT name scan for addresses from %s\n\n", target_string ); 628 | 629 | /* Finished with options */ 630 | /*************************/ 631 | 632 | /* Prepare socket and address structures */ 633 | /*****************************************/ 634 | sock = socket ( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); 635 | if ( sock < 0 ) 636 | err_die ( "Failed to create socket", quiet ); 637 | 638 | memset ( &src_sockaddr, 0, sizeof src_sockaddr ); 639 | src_sockaddr.sin_family = AF_INET; 640 | if ( use137 ) 641 | src_sockaddr.sin_port = htons ( NB_DGRAM ); 642 | if ( bind ( sock, 643 | ( struct sockaddr * ) &src_sockaddr, 644 | sizeof ( src_sockaddr ) ) == -1 ) 645 | err_die ( "Failed to bind", quiet ); 646 | 647 | FD_ZERO ( &fdsr ); 648 | FD_SET ( sock, &fdsr ); 649 | 650 | FD_ZERO ( &fdsw ); 651 | FD_SET ( sock, &fdsw ); 652 | 653 | /* timeout is in milliseconds */ 654 | select_timeout.tv_sec = 60; /* Default 1 min to survive ARP timeouts */ 655 | select_timeout.tv_usec = 0; 656 | 657 | addr_size = sizeof ( struct sockaddr_in ); 658 | 659 | next_in_addr = malloc ( sizeof ( struct in_addr ) ); 660 | if ( !next_in_addr ) 661 | err_die ( "Malloc failed", quiet ); 662 | 663 | buff = malloc ( BUFFSIZE ); 664 | if ( !buff ) 665 | err_die ( "Malloc failed", quiet ); 666 | 667 | /* Calculate interval between subsequent sends */ 668 | 669 | timerclear ( &send_interval ); 670 | if ( bandwidth ) 671 | send_interval.tv_usec = 672 | ( NBNAME_REQUEST_SIZE + UDP_HEADER_SIZE + IP_HEADER_SIZE ) * 8 * 673 | 1000000 / bandwidth; /* Send interval in microseconds */ 674 | else /* Assuming 10baseT bandwidth */ 675 | send_interval.tv_usec = 1; /* for 10baseT interval should be about 1 ms */ 676 | if ( send_interval.tv_usec >= 1000000 ) 677 | { 678 | send_interval.tv_sec = send_interval.tv_usec / 1000000; 679 | send_interval.tv_usec = send_interval.tv_usec % 1000000; 680 | } 681 | 682 | gettimeofday ( &last_send_time, NULL ); /* Get current time */ 683 | 684 | rtt_base = last_send_time.tv_sec; 685 | 686 | /* Send queries, receive answers and print results */ 687 | /***************************************************/ 688 | 689 | scanned = new_list (); 690 | 691 | if ( !( quiet || verbose || dump || sf || lmhosts || etc_hosts ) ) 692 | print_header (); 693 | 694 | for ( i = 0; i <= retransmits; i++ ) 695 | { 696 | gettimeofday ( &transmit_started, NULL ); 697 | while ( ( select ( sock + 1, &fdsr, &fdsw, NULL, &select_timeout ) ) > 0 ) 698 | { 699 | if ( FD_ISSET ( sock, &fdsr ) ) 700 | { 701 | if ( ( size = recvfrom ( sock, 702 | buff, 703 | BUFFSIZE, 704 | 0, 705 | ( struct sockaddr * ) &dest_sockaddr, 706 | &addr_size ) ) <= 0 ) 707 | { 708 | snprintf ( errmsg, 709 | 80, 710 | "%s\tRecvfrom failed", 711 | inet_ntoa ( dest_sockaddr.sin_addr ) ); 712 | err_print ( errmsg, quiet ); 713 | continue; 714 | } 715 | gettimeofday ( &recv_time, NULL ); 716 | hostinfo = 717 | ( struct nb_host_info * ) parse_response ( buff, size ); 718 | if ( !hostinfo ) 719 | { 720 | err_print ( "parse_response returned NULL", quiet ); 721 | continue; 722 | } 723 | /* If this packet isn't a duplicate */ 724 | if ( insert ( scanned, ntohl ( dest_sockaddr.sin_addr.s_addr ) ) ) 725 | { 726 | rtt = recv_time.tv_sec + recv_time.tv_usec / 1000000 - 727 | rtt_base - hostinfo->header->transaction_id / 1000; 728 | /* Using algorithm described in Stevens' 729 | Unix Network Programming */ 730 | delta = rtt - srtt; 731 | srtt += delta / 8; 732 | if ( delta < 0.0 ) 733 | delta = -delta; 734 | rttvar += ( delta - rttvar ) / 4; 735 | 736 | if ( verbose ) 737 | v_print_hostinfo ( 738 | dest_sockaddr.sin_addr, hostinfo, sf, hr ); 739 | else if ( dump ) 740 | d_print_hostinfo ( dest_sockaddr.sin_addr, hostinfo ); 741 | else if ( etc_hosts ) 742 | l_print_hostinfo ( dest_sockaddr.sin_addr, hostinfo, 0 ); 743 | else if ( lmhosts ) 744 | l_print_hostinfo ( dest_sockaddr.sin_addr, hostinfo, 1 ); 745 | else 746 | print_hostinfo ( dest_sockaddr.sin_addr, hostinfo, sf ); 747 | } 748 | 749 | free ( hostinfo->header ); 750 | free ( hostinfo->footer ); 751 | free ( hostinfo->names ); 752 | free ( hostinfo ); 753 | } 754 | 755 | FD_ZERO ( &fdsr ); 756 | FD_SET ( sock, &fdsr ); 757 | 758 | /* check if send_interval time passed since last send */ 759 | gettimeofday ( ¤t_time, NULL ); 760 | timersub ( ¤t_time, &last_send_time, &diff_time ); 761 | send_ok = timercmp ( &diff_time, &send_interval, >= ); 762 | 763 | if ( more_to_send && FD_ISSET ( sock, &fdsw ) && send_ok ) 764 | { 765 | if ( targetlist ) 766 | { 767 | if ( fgets ( str, 80, targetlist ) ) 768 | { 769 | if ( !inet_aton ( str, next_in_addr ) ) 770 | { 771 | /* if(!inet_pton(AF_INET, str, next_in_addr)) { */ 772 | fprintf ( stderr, "%s - bad IP address\n", str ); 773 | } 774 | else 775 | { 776 | if ( !in_list ( scanned, 777 | ntohl ( next_in_addr->s_addr ) ) ) 778 | send_query ( sock, *next_in_addr, rtt_base ); 779 | } 780 | } 781 | else 782 | { 783 | if ( feof ( targetlist ) ) 784 | { 785 | more_to_send = 0; 786 | FD_ZERO ( &fdsw ); 787 | /* timeout is in milliseconds */ 788 | select_timeout.tv_sec = timeout / 1000; 789 | select_timeout.tv_usec = 790 | ( timeout % 1000 ) * 1000; /* Microseconds */ 791 | continue; 792 | } 793 | else 794 | { 795 | snprintf ( errmsg, 796 | 80, 797 | "Read failed from file %s", 798 | filename ); 799 | err_die ( errmsg, quiet ); 800 | } 801 | } 802 | } 803 | else if ( next_address ( &range, prev_in_addr, next_in_addr ) ) 804 | { 805 | if ( !in_list ( scanned, ntohl ( next_in_addr->s_addr ) ) ) 806 | send_query ( sock, *next_in_addr, rtt_base ); 807 | prev_in_addr = next_in_addr; 808 | /* Update last send time */ 809 | gettimeofday ( &last_send_time, NULL ); 810 | } 811 | else 812 | { /* No more queries to send */ 813 | more_to_send = 0; 814 | FD_ZERO ( &fdsw ); 815 | /* timeout is in milliseconds */ 816 | select_timeout.tv_sec = timeout / 1000; 817 | select_timeout.tv_usec = 818 | ( timeout % 1000 ) * 1000; /* Microseconds */ 819 | continue; 820 | } 821 | } 822 | if ( more_to_send ) 823 | { 824 | FD_ZERO ( &fdsw ); 825 | FD_SET ( sock, &fdsw ); 826 | } 827 | } 828 | 829 | if ( i >= retransmits ) 830 | break; /* If we are not going to retransmit 831 | we can finish right now without waiting */ 832 | 833 | rto = ( srtt + 4 * rttvar ) * ( i + 1 ); 834 | 835 | if ( rto < 2.0 ) 836 | rto = 2.0; 837 | if ( rto > 60.0 ) 838 | rto = 60.0; 839 | gettimeofday ( &now, NULL ); 840 | 841 | if ( now.tv_sec < ( transmit_started.tv_sec + rto ) ) 842 | sleep ( ( transmit_started.tv_sec + rto ) - now.tv_sec ); 843 | prev_in_addr = NULL; 844 | more_to_send = 1; 845 | FD_ZERO ( &fdsw ); 846 | FD_SET ( sock, &fdsw ); 847 | FD_ZERO ( &fdsr ); 848 | FD_SET ( sock, &fdsr ); 849 | } 850 | 851 | delete_list ( scanned ); 852 | free ( next_in_addr ); 853 | free ( temp_target_string ); 854 | free ( buff ); 855 | exit ( 0 ); 856 | } 857 | -------------------------------------------------------------------------------- /src/range.c: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2004 Jochen Friedrich 4 | # Copyright 2021 Mayco Souza Berghetti 5 | # 6 | # This program is free software; you can redistribute it and/or 7 | # modify it under the terms of the GNU General Public License 8 | # as published by the Free Software Foundation; either version 2 9 | # of the License, or (at your option) any later version. 10 | # 11 | # This program is distributed in the hope that it will be useful, 12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | # GNU General Public License for more details. 15 | # 16 | # You should have received a copy of the GNU General Public License 17 | # along with this program; if not, write to the Free Software 18 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "range.h" 28 | #include 29 | #include 30 | #include "errors.h" 31 | 32 | #ifndef INADDR_NONE 33 | #define INADDR_NONE ( in_addr_t ) - 1 34 | #endif 35 | 36 | extern int quiet; 37 | 38 | /* is_ip checks if supplied string is an ip address in dotted-decimal 39 | notation, and fills both members of range structure with its numerical value 40 | (host byte order)/ Returns 1 on success, 0 on failure */ 41 | int 42 | is_ip ( char *string, struct ip_range *range ) 43 | { 44 | unsigned long addr; 45 | 46 | addr = inet_addr ( string ); 47 | if ( addr != INADDR_NONE ) 48 | { 49 | range->start_ip = ntohl ( addr ); 50 | range->end_ip = ntohl ( addr ); 51 | return 1; 52 | } 53 | else 54 | return 0; 55 | } 56 | 57 | /* is_range1 checks if supplied string is an IP address range in 58 | form xxx.xxx.xxx.xxx/xx (as in 192.168.1.2/24) and fills 59 | range structure with start and end ip addresses of the interval. 60 | Returns 1 on success, 0 on failure */ 61 | int 62 | is_range1 ( char *string, struct ip_range *range ) 63 | { 64 | char *separator; 65 | unsigned int mask; 66 | char *ip; 67 | 68 | if ( ( ip = malloc ( strlen ( string ) + 1 ) ) == NULL ) 69 | err_die ( "Malloc failed", quiet ); 70 | 71 | if ( strlen ( string ) > 19 ) 72 | return 0; 73 | if ( ( separator = ( char * ) strchr ( string, '/' ) ) ) 74 | { 75 | separator++; 76 | mask = atoi ( separator ); 77 | if ( mask == 0 || mask > 32 ) 78 | return 0; 79 | 80 | strcpy ( ip, string ); 81 | ip[abs ( ( int ) ( string - separator ) ) - 1] = 0; 82 | if ( ( range->start_ip = inet_addr ( ip ) ) == INADDR_NONE ) 83 | return 0; 84 | /* mask=((1<start_ip = 91 | ntohl ( range->start_ip ); // We store ips in host byte order 92 | range->start_ip &= mask; 93 | range->end_ip = range->start_ip | ( ~mask ); 94 | free ( ip ); 95 | return 1; 96 | } 97 | free ( ip ); 98 | return 0; 99 | } 100 | 101 | /* next_address function writes next ip address in range after prev_addr to 102 | structure pointed by next_addr. Returns 1 if next ip found and 0 otherwise */ 103 | int 104 | next_address ( const struct ip_range *range, 105 | const struct in_addr *prev_addr, 106 | struct in_addr *next_addr ) 107 | { 108 | unsigned long pa; // previous address, host byte order 109 | 110 | if ( prev_addr ) 111 | { 112 | pa = ntohl ( prev_addr->s_addr ); 113 | if ( pa < range->end_ip ) 114 | { 115 | next_addr->s_addr = htonl ( ++pa ); 116 | return 1; 117 | } 118 | else 119 | return 0; 120 | } 121 | else 122 | { 123 | next_addr->s_addr = htonl ( range->start_ip ); 124 | return 1; 125 | } 126 | } 127 | 128 | /* is_range2 checks if supplied string is an IP address range in 129 | form xxx.xxx.xxx.xxx-xxx (as in 192.168.1.2-15) and fills 130 | range structure with start and end ip addresses of the interval. 131 | Returns 1 on success, 0 on failure */ 132 | int 133 | is_range2 ( char *string, struct ip_range *range ) 134 | { 135 | unsigned long last_octet; /*last octet of last ip in range*/ 136 | char *separator; 137 | unsigned long addr; 138 | char *ip; 139 | 140 | if ( ( ip = malloc ( strlen ( string ) + 1 ) ) == NULL ) 141 | err_die ( "Malloc failed", quiet ); 142 | strcpy ( ip, string ); 143 | 144 | if ( ( separator = ( char * ) strchr ( ip, '-' ) ) ) 145 | { 146 | *separator = 0; 147 | separator++; 148 | last_octet = atoi ( separator ); 149 | if ( last_octet > 255 ) 150 | { 151 | free ( ip ); 152 | return 0; 153 | } 154 | addr = inet_addr ( ip ); 155 | if ( addr == INADDR_NONE ) 156 | { 157 | free ( ip ); 158 | return 0; 159 | } 160 | range->start_ip = ntohl ( addr ); 161 | range->end_ip = ( range->start_ip & 0xffffff00 ) | last_octet; 162 | if ( range->end_ip < range->start_ip ) 163 | { 164 | free ( ip ); 165 | return 0; 166 | } 167 | free ( ip ); 168 | return 1; 169 | } 170 | free ( ip ); 171 | return 0; 172 | } 173 | 174 | void 175 | print_range ( const struct ip_range *range ) 176 | { 177 | struct in_addr *addr; 178 | 179 | if ( ( addr = malloc ( sizeof ( struct in_addr ) ) ) == NULL ) 180 | err_die ( "Malloc failed", quiet ); 181 | 182 | next_address ( range, 0, addr ); 183 | printf ( "%s\n", inet_ntoa ( *addr ) ); 184 | 185 | while ( next_address ( range, addr, addr ) ) 186 | { 187 | printf ( "%s\n", inet_ntoa ( *addr ) ); 188 | } 189 | free ( addr ); 190 | } 191 | -------------------------------------------------------------------------------- /src/range.h: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 3 | # Copyright 2004 Jochen Friedrich 4 | # 5 | # This program is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU General Public License 7 | # as published by the Free Software Foundation; either version 2 8 | # of the License, or (at your option) any later 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #if !defined RANGE_H 28 | #define RANGE_H 29 | 30 | struct ip_range 31 | { 32 | unsigned long start_ip; // IP addresses in _host_ order, not network 33 | unsigned long end_ip; 34 | }; 35 | 36 | /* is_ip checks if supplied string is an ip address in dotted-decimal 37 | notation, and fills both members of range structure with its numerical value 38 | (host byte order)/ Returns 1 on success, 0 on failure */ 39 | int 40 | is_ip ( char *string, struct ip_range *range ); 41 | 42 | /* is_range1 checks if supplied string is an IP address range in 43 | form xxx.xxx.xxx.xxx/xx (as in 192.168.1.2/24) and fills 44 | range structure with start and end ip addresses of the interval. 45 | Returns 1 on success, 0 on failure */ 46 | int 47 | is_range1 ( char *string, struct ip_range *range ); 48 | 49 | /* next_address function writes next ip address in range after prev_addr to 50 | structure pointed by next_addr. Returns 1 if next ip found and 0 otherwise */ 51 | int 52 | next_address ( const struct ip_range *range, 53 | const struct in_addr *prev_addr, 54 | struct in_addr *next_addr ); 55 | 56 | /* is_range2 checks if supplied string is an IP address range in 57 | form xxx.xxx.xxx.xxx-xxx (as in 192.168.1.2-15) and fills 58 | range structure with start and end ip addresses of the interval. 59 | Returns 1 on success, 0 on failure */ 60 | int 61 | is_range2 ( char *string, struct ip_range *range ); 62 | 63 | void 64 | print_range ( const struct ip_range *range ); 65 | 66 | #endif /* RANGE_H */ 67 | -------------------------------------------------------------------------------- /src/statusq.c: -------------------------------------------------------------------------------- 1 | /* This file contains a portion of code from Samba package, * 2 | / which contains the following license: * 3 | / 4 | Unix SMB/Netbios implementation 5 | Version 1.9 6 | Main SMB server routine 7 | Copyright 1992-1995 Andrew Tridgell 8 | Copyright 2004 Jochen Friedrich 9 | Copyright 2021 Mayco Souza Berghetti 10 | 11 | This program is free software; you can redistribute it and/or modif 12 | it under the terms of the GNU General Public License as published b 13 | the Free Software Foundation; either version 2 of the License, o 14 | (at your option) any later version 15 | 16 | This program is distributed in the hope that it will be useful 17 | but WITHOUT ANY WARRANTY; without even the implied warranty o 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See th 19 | GNU General Public License for more details 20 | 21 | You should have received a copy of the GNU General Public Licens 22 | along with this program; if not, write to the Free Softwar 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA 24 | */ 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include "statusq.h" 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include "errors.h" 38 | 39 | extern int quiet; 40 | 41 | /* Start of code from Samba */ 42 | static int 43 | name_mangle ( char *In, char *Out, char name_type ) 44 | { 45 | int i; 46 | int c; 47 | int len; 48 | char buf[20]; 49 | char *p = Out; 50 | char *scope = ""; 51 | 52 | /* Safely copy the input string, In, into buf[]. */ 53 | ( void ) memset ( buf, 0, 20 ); 54 | if ( strcmp ( In, "*" ) == 0 ) 55 | buf[0] = '*'; 56 | else 57 | #ifdef HAVE_SNPRINTF 58 | ( void ) snprintf ( buf, sizeof ( buf ) - 1, "%-15.15s%c", In, name_type ); 59 | #else 60 | ( void ) sprintf ( buf, "%-15.15s%c", In, name_type ); 61 | #endif /* HAVE_SNPRINTF */ 62 | 63 | /* Place the length of the first field into the output buffer. */ 64 | p[0] = 32; 65 | p++; 66 | 67 | /* Now convert the name to the rfc1001/1002 format. */ 68 | for ( i = 0; i < 16; i++ ) 69 | { 70 | c = toupper ( buf[i] ); 71 | p[i * 2] = ( ( c >> 4 ) & 0x000F ) + 'A'; 72 | p[( i * 2 ) + 1] = ( c & 0x000F ) + 'A'; 73 | } 74 | p += 32; 75 | p[0] = '\0'; 76 | 77 | /* Add the scope string. */ 78 | for ( i = 0, len = 0; NULL != scope; i++, len++ ) 79 | { 80 | switch ( scope[i] ) 81 | { 82 | case '\0': 83 | p[0] = len; 84 | if ( len > 0 ) 85 | p[len + 1] = 0; 86 | return ( strlen ( Out ) ); 87 | case '.': 88 | p[0] = len; 89 | p += ( len + 1 ); 90 | len = 0; 91 | break; 92 | default: 93 | p[len + 1] = scope[i]; 94 | break; 95 | } 96 | } 97 | return ( strlen ( Out ) ); 98 | } /* name_mangle */ 99 | /* end of code from Samba */ 100 | 101 | void 102 | send_query ( int sock, struct in_addr dest_addr, my_uint32_t rtt_base ) 103 | { 104 | struct nbname_request request; 105 | int status; 106 | struct timeval tv; 107 | char errmsg[80]; 108 | 109 | struct sockaddr_in dest_sockaddr = { .sin_family = AF_INET, 110 | .sin_port = htons ( NB_DGRAM ), 111 | .sin_addr = dest_addr }; 112 | 113 | request.flags = htons ( FL_BROADCAST ); 114 | request.question_count = htons ( 1 ); 115 | request.answer_count = 0; 116 | request.name_service_count = 0; 117 | request.additional_record_count = 0; 118 | name_mangle ( "*", request.question_name, 0 ); 119 | request.question_type = htons ( 0x21 ); 120 | request.question_class = htons ( 0x01 ); 121 | 122 | gettimeofday ( &tv, NULL ); 123 | /* Use transaction ID as a timestamp */ 124 | request.transaction_id = 125 | htons ( ( tv.tv_sec - rtt_base ) * 1000 + tv.tv_usec / 1000 ); 126 | // printf("%s: timestamp: %d\n", inet_ntoa(dest_addr), 127 | // request.transaction_id); 128 | 129 | status = sendto ( sock, 130 | ( char * ) &request, 131 | sizeof ( request ), 132 | 0, 133 | ( struct sockaddr * ) &dest_sockaddr, 134 | sizeof ( dest_sockaddr ) ); 135 | if ( status == -1 ) 136 | { 137 | snprintf ( errmsg, 138 | sizeof errmsg, 139 | "%s\tSendto failed", 140 | inet_ntoa ( dest_addr ) ); 141 | err_print ( errmsg, quiet ); 142 | } 143 | } 144 | 145 | static my_uint32_t 146 | get32 ( void *data ) 147 | { 148 | union 149 | { 150 | char bytes[4]; 151 | my_uint32_t all; 152 | } x; 153 | 154 | memcpy ( x.bytes, data, 4 ); 155 | return ( ntohl ( x.all ) ); 156 | } 157 | 158 | static my_uint16_t 159 | get16 ( void *data ) 160 | { 161 | union 162 | { 163 | char bytes[2]; 164 | my_uint16_t all; 165 | } x; 166 | 167 | memcpy ( x.bytes, data, 2 ); 168 | return ( ntohs ( x.all ) ); 169 | } 170 | 171 | struct nb_host_info * 172 | parse_response ( char *buff, unsigned int buffsize ) 173 | { 174 | struct nb_host_info *hostinfo; 175 | nbname_response_footer_t *response_footer; 176 | nbname_response_header_t *response_header; 177 | int name_table_size; 178 | unsigned int offset = 0; 179 | 180 | response_header = calloc ( 1, sizeof ( nbname_response_header_t ) ); 181 | response_footer = calloc ( 1, sizeof ( nbname_response_footer_t ) ); 182 | hostinfo = malloc ( sizeof ( struct nb_host_info ) ); 183 | 184 | if ( !response_header || !response_footer || !hostinfo ) 185 | { 186 | free ( response_header ); 187 | free ( response_footer ); 188 | free ( hostinfo ); 189 | return NULL; 190 | } 191 | 192 | hostinfo->header = NULL; 193 | hostinfo->names = NULL; 194 | hostinfo->footer = NULL; 195 | 196 | /* Parsing received packet */ 197 | /* Start with header */ 198 | if ( offset + sizeof ( response_header->transaction_id ) >= buffsize ) 199 | goto broken_packet; 200 | response_header->transaction_id = get16 ( buff + offset ); 201 | // Move pointer to the next structure field 202 | offset += sizeof ( response_header->transaction_id ); 203 | hostinfo->header = response_header; 204 | 205 | // Check if there is room for next field in buffer 206 | if ( offset + sizeof ( response_header->flags ) >= buffsize ) 207 | goto broken_packet; 208 | response_header->flags = get16 ( buff + offset ); 209 | offset += sizeof ( response_header->flags ); 210 | 211 | if ( offset + sizeof ( response_header->question_count ) >= buffsize ) 212 | goto broken_packet; 213 | response_header->question_count = get16 ( buff + offset ); 214 | offset += sizeof ( response_header->question_count ); 215 | 216 | if ( offset + sizeof ( response_header->answer_count ) >= buffsize ) 217 | goto broken_packet; 218 | response_header->answer_count = get16 ( buff + offset ); 219 | offset += sizeof ( response_header->answer_count ); 220 | 221 | if ( offset + sizeof ( response_header->name_service_count ) >= buffsize ) 222 | goto broken_packet; 223 | response_header->name_service_count = get16 ( buff + offset ); 224 | offset += sizeof ( response_header->name_service_count ); 225 | 226 | if ( offset + sizeof ( response_header->additional_record_count ) >= 227 | buffsize ) 228 | goto broken_packet; 229 | response_header->additional_record_count = get16 ( buff + offset ); 230 | offset += sizeof ( response_header->additional_record_count ); 231 | 232 | if ( offset + sizeof ( response_header->question_name ) >= buffsize ) 233 | goto broken_packet; 234 | strncpy ( response_header->question_name, 235 | buff + offset, 236 | sizeof ( response_header->question_name ) ); 237 | offset += sizeof ( response_header->question_name ); 238 | 239 | if ( offset + sizeof ( response_header->question_type ) >= buffsize ) 240 | goto broken_packet; 241 | response_header->question_type = get16 ( buff + offset ); 242 | offset += sizeof ( response_header->question_type ); 243 | 244 | if ( offset + sizeof ( response_header->question_class ) >= buffsize ) 245 | goto broken_packet; 246 | response_header->question_class = get16 ( buff + offset ); 247 | offset += sizeof ( response_header->question_class ); 248 | 249 | if ( offset + sizeof ( response_header->ttl ) >= buffsize ) 250 | goto broken_packet; 251 | response_header->ttl = get32 ( buff + offset ); 252 | offset += sizeof ( response_header->ttl ); 253 | 254 | if ( offset + sizeof ( response_header->rdata_length ) >= buffsize ) 255 | goto broken_packet; 256 | response_header->rdata_length = get16 ( buff + offset ); 257 | offset += sizeof ( response_header->rdata_length ); 258 | 259 | if ( offset + sizeof ( response_header->number_of_names ) >= buffsize ) 260 | goto broken_packet; 261 | response_header->number_of_names = 262 | *( typeof ( response_header->number_of_names ) * ) ( buff + offset ); 263 | offset += sizeof ( response_header->number_of_names ); 264 | 265 | /* Done with packet header - it is okay */ 266 | 267 | name_table_size = 268 | ( response_header->number_of_names ) * ( sizeof ( struct nbname ) ); 269 | if ( offset + name_table_size >= buffsize ) 270 | goto broken_packet; 271 | 272 | if ( ( hostinfo->names = malloc ( name_table_size ) ) == NULL ) 273 | { 274 | free ( response_header ); 275 | free ( response_footer ); 276 | free ( hostinfo ); 277 | return NULL; 278 | } 279 | 280 | memcpy ( hostinfo->names, buff + offset, name_table_size ); 281 | 282 | offset += name_table_size; 283 | 284 | /* Done with name table - it is okay */ 285 | 286 | /* Now parse response footer */ 287 | 288 | if ( offset + sizeof ( response_footer->adapter_address ) >= buffsize ) 289 | goto broken_packet; 290 | 291 | memcpy ( response_footer->adapter_address, 292 | ( buff + offset ), 293 | sizeof ( response_footer->adapter_address ) ); 294 | 295 | offset += sizeof ( response_footer->adapter_address ); 296 | 297 | hostinfo->footer = response_footer; 298 | 299 | if ( offset + sizeof ( response_footer->version_major ) >= buffsize ) 300 | goto broken_packet; 301 | response_footer->version_major = 302 | *( typeof ( response_footer->version_major ) * ) ( buff + offset ); 303 | offset += sizeof ( response_footer->version_major ); 304 | 305 | if ( offset + sizeof ( response_footer->version_minor ) >= buffsize ) 306 | goto broken_packet; 307 | response_footer->version_minor = 308 | *( typeof ( response_footer->version_minor ) * ) ( buff + offset ); 309 | offset += sizeof ( response_footer->version_minor ); 310 | 311 | if ( offset + sizeof ( response_footer->duration ) >= buffsize ) 312 | goto broken_packet; 313 | response_footer->duration = get16 ( buff + offset ); 314 | offset += sizeof ( response_footer->duration ); 315 | 316 | if ( offset + sizeof ( response_footer->frmps_received ) >= buffsize ) 317 | goto broken_packet; 318 | response_footer->frmps_received = get16 ( buff + offset ); 319 | offset += sizeof ( response_footer->frmps_received ); 320 | 321 | if ( offset + sizeof ( response_footer->frmps_transmitted ) >= buffsize ) 322 | goto broken_packet; 323 | response_footer->frmps_transmitted = get16 ( buff + offset ); 324 | offset += sizeof ( response_footer->frmps_transmitted ); 325 | 326 | if ( offset + sizeof ( response_footer->iframe_receive_errors ) >= buffsize ) 327 | goto broken_packet; 328 | response_footer->iframe_receive_errors = get16 ( buff + offset ); 329 | offset += sizeof ( response_footer->iframe_receive_errors ); 330 | 331 | if ( offset + sizeof ( response_footer->transmit_aborts ) >= buffsize ) 332 | goto broken_packet; 333 | response_footer->transmit_aborts = get16 ( buff + offset ); 334 | offset += sizeof ( response_footer->transmit_aborts ); 335 | 336 | if ( offset + sizeof ( response_footer->transmitted ) >= buffsize ) 337 | goto broken_packet; 338 | response_footer->transmitted = get32 ( buff + offset ); 339 | offset += sizeof ( response_footer->transmitted ); 340 | 341 | if ( offset + sizeof ( response_footer->received ) >= buffsize ) 342 | goto broken_packet; 343 | response_footer->received = get32 ( buff + offset ); 344 | offset += sizeof ( response_footer->received ); 345 | 346 | if ( offset + sizeof ( response_footer->iframe_transmit_errors ) >= buffsize ) 347 | goto broken_packet; 348 | response_footer->iframe_transmit_errors = get16 ( buff + offset ); 349 | offset += sizeof ( response_footer->iframe_transmit_errors ); 350 | 351 | if ( offset + sizeof ( response_footer->no_receive_buffer ) >= buffsize ) 352 | goto broken_packet; 353 | response_footer->no_receive_buffer = get16 ( buff + offset ); 354 | offset += sizeof ( response_footer->no_receive_buffer ); 355 | 356 | if ( offset + sizeof ( response_footer->tl_timeouts ) >= buffsize ) 357 | goto broken_packet; 358 | response_footer->tl_timeouts = get16 ( buff + offset ); 359 | offset += sizeof ( response_footer->tl_timeouts ); 360 | 361 | if ( offset + sizeof ( response_footer->ti_timeouts ) >= buffsize ) 362 | goto broken_packet; 363 | response_footer->ti_timeouts = get16 ( buff + offset ); 364 | offset += sizeof ( response_footer->ti_timeouts ); 365 | 366 | if ( offset + sizeof ( response_footer->free_ncbs ) >= buffsize ) 367 | goto broken_packet; 368 | response_footer->free_ncbs = get16 ( buff + offset ); 369 | offset += sizeof ( response_footer->free_ncbs ); 370 | 371 | if ( offset + sizeof ( response_footer->ncbs ) >= buffsize ) 372 | goto broken_packet; 373 | response_footer->ncbs = get16 ( buff + offset ); 374 | offset += sizeof ( response_footer->ncbs ); 375 | 376 | if ( offset + sizeof ( response_footer->max_ncbs ) >= buffsize ) 377 | goto broken_packet; 378 | response_footer->max_ncbs = get16 ( buff + offset ); 379 | offset += sizeof ( response_footer->max_ncbs ); 380 | 381 | if ( offset + sizeof ( response_footer->no_transmit_buffers ) >= buffsize ) 382 | goto broken_packet; 383 | response_footer->no_transmit_buffers = get16 ( buff + offset ); 384 | offset += sizeof ( response_footer->no_transmit_buffers ); 385 | 386 | if ( offset + sizeof ( response_footer->max_datagram ) >= buffsize ) 387 | goto broken_packet; 388 | response_footer->max_datagram = get16 ( buff + offset ); 389 | offset += sizeof ( response_footer->max_datagram ); 390 | 391 | if ( offset + sizeof ( response_footer->pending_sessions ) >= buffsize ) 392 | goto broken_packet; 393 | response_footer->pending_sessions = get16 ( buff + offset ); 394 | offset += sizeof ( response_footer->pending_sessions ); 395 | 396 | if ( offset + sizeof ( response_footer->max_sessions ) >= buffsize ) 397 | goto broken_packet; 398 | response_footer->max_sessions = get16 ( buff + offset ); 399 | offset += sizeof ( response_footer->max_sessions ); 400 | 401 | if ( offset + sizeof ( response_footer->packet_sessions ) >= buffsize ) 402 | goto broken_packet; 403 | response_footer->packet_sessions = get16 ( buff + offset ); 404 | offset += sizeof ( response_footer->packet_sessions ); 405 | 406 | /* Done with packet footer and the whole packet */ 407 | 408 | return hostinfo; 409 | 410 | broken_packet: 411 | hostinfo->is_broken = offset; 412 | 413 | return hostinfo; 414 | } 415 | 416 | nb_service_t services[] = { 417 | { "__MSBROWSE__", 0x01, 0, "Master Browser" }, 418 | { "INet~Services", 0x1C, 0, "IIS" }, 419 | { "IS~", 0x00, 1, "IIS" }, 420 | { "", 0x00, 1, "Workstation Service" }, 421 | { "", 0x01, 1, "Messenger Service" }, 422 | { "", 0x03, 1, "Messenger Service" }, 423 | { "", 0x06, 1, "RAS Server Service" }, 424 | { "", 0x1F, 1, "NetDDE Service" }, 425 | { "", 0x20, 1, "File Server Service" }, 426 | { "", 0x21, 1, "RAS Client Service" }, 427 | { "", 0x22, 1, "Microsoft Exchange Interchange(MSMail Connector)" }, 428 | { "", 0x23, 1, "Microsoft Exchange Store" }, 429 | { "", 0x24, 1, "Microsoft Exchange Directory" }, 430 | { "", 0x30, 1, "Modem Sharing Server Service" }, 431 | { "", 0x31, 1, "Modem Sharing Client Service" }, 432 | { "", 0x43, 1, "SMS Clients Remote Control" }, 433 | { "", 0x44, 1, "SMS Administrators Remote Control Tool" }, 434 | { "", 0x45, 1, "SMS Clients Remote Chat" }, 435 | { "", 0x46, 1, "SMS Clients Remote Transfer" }, 436 | { "", 0x4C, 1, "DEC Pathworks TCPIP service on Windows NT" }, 437 | { "", 0x52, 1, "DEC Pathworks TCPIP service on Windows NT" }, 438 | { "", 0x87, 1, "Microsoft Exchange MTA" }, 439 | { "", 0x6A, 1, "Microsoft Exchange IMC" }, 440 | { "", 0xBE, 1, "Network Monitor Agent" }, 441 | { "", 0xBF, 1, "Network Monitor Application" }, 442 | { "", 0x03, 1, "Messenger Service" }, 443 | { "", 0x00, 0, "Domain Name" }, 444 | { "", 0x1B, 1, "Domain Master Browser" }, 445 | { "", 0x1C, 0, "Domain Controllers" }, 446 | { "", 0x1D, 1, "Master Browser" }, 447 | { "", 0x1E, 0, "Browser Service Elections" }, 448 | { "", 0x2B, 1, "Lotus Notes Server Service" }, 449 | { "IRISMULTICAST", 0x2F, 0, "Lotus Notes" }, 450 | { "IRISNAMESERVER", 0x33, 0, "Lotus Notes" }, 451 | { "Forte_$ND800ZA", 0x20, 1, "DCA IrmaLan Gateway Server Service" } }; 452 | 453 | char * 454 | getnbservicename ( my_uint8_t service, int unique, char *name ) 455 | { 456 | unsigned int i; 457 | char *unknown; 458 | 459 | unknown = malloc ( 100 ); 460 | 461 | if ( !unknown ) 462 | err_die ( "Malloc failed.\n", 0 ); 463 | 464 | for ( i = 0; i < sizeof services / sizeof services[0]; i++ ) 465 | { 466 | if ( service == services[i].service_number && 467 | unique == services[i].unique && 468 | strstr ( name, services[i].nb_name ) ) 469 | return services[i].service_name; 470 | } 471 | 472 | snprintf ( unknown, 100, "Unknown service (code %x)", service ); 473 | return ( unknown ); 474 | } 475 | -------------------------------------------------------------------------------- /src/statusq.h: -------------------------------------------------------------------------------- 1 | #if !defined STATUSQ_H 2 | #define STATUSQ_H 3 | 4 | #if defined HAVE_STDINT_H 5 | #include 6 | #endif 7 | #include 8 | 9 | #define FL_REQUEST 0x8000 10 | #define FL_QUERY 0x7800 11 | #define FL_NON_AUTH_ANSWER 0x0400 12 | #define FL_DGRAM_NOT_TRUNCATED 0x0200 13 | #define FL_RECURSION_NOT_DESIRED 0x0100 14 | #define FL_RECURSION_NOT_AVAIl 0x0080 15 | #define FL_RESERVED1 0x0040 16 | #define FL_RESERVED2 0x0020 17 | #define FL_BROADCAST 0x0010 18 | #define FL_SUCCESS 0x000F 19 | 20 | #define QT_NODE_STATUS_REQUEST 0x0021 21 | #define QC_INTERNET 0x0001 22 | 23 | #define NB_DGRAM 137 24 | 25 | struct nbname 26 | { 27 | char ascii_name[16]; 28 | my_uint16_t rr_flags; 29 | }; 30 | 31 | struct nbname_request 32 | { 33 | my_uint16_t transaction_id; 34 | my_uint16_t flags; 35 | my_uint16_t question_count; 36 | my_uint16_t answer_count; 37 | my_uint16_t name_service_count; 38 | my_uint16_t additional_record_count; 39 | char question_name[34]; 40 | my_uint16_t question_type; 41 | my_uint16_t question_class; 42 | }; 43 | 44 | #define NBNAME_REQUEST_SIZE 50 45 | #define UDP_HEADER_SIZE 8 46 | #define IP_HEADER_SIZE 20 47 | 48 | typedef struct nbname_response_header 49 | { 50 | my_uint16_t transaction_id; 51 | my_uint16_t flags; 52 | my_uint16_t question_count; 53 | my_uint16_t answer_count; 54 | my_uint16_t name_service_count; 55 | my_uint16_t additional_record_count; 56 | char question_name[34]; 57 | my_uint16_t question_type; 58 | my_uint16_t question_class; 59 | my_uint32_t ttl; 60 | my_uint16_t rdata_length; 61 | my_uint8_t number_of_names; 62 | } nbname_response_header_t; 63 | 64 | /* #define NBNAME_RESPONSE_NUMBER_OF_NAMES_OFFSET 56 */ 65 | 66 | #define NBNAME_RESPONSE_HEADER_SIZE 57 67 | 68 | typedef struct nbname_response_footer 69 | { 70 | my_uint8_t adapter_address[6]; 71 | my_uint8_t version_major; 72 | my_uint8_t version_minor; 73 | my_uint16_t duration; 74 | my_uint16_t frmps_received; 75 | my_uint16_t frmps_transmitted; 76 | my_uint16_t iframe_receive_errors; 77 | my_uint16_t transmit_aborts; 78 | my_uint32_t transmitted; 79 | my_uint32_t received; 80 | my_uint16_t iframe_transmit_errors; 81 | my_uint16_t no_receive_buffer; 82 | my_uint16_t tl_timeouts; 83 | my_uint16_t ti_timeouts; 84 | my_uint16_t free_ncbs; 85 | my_uint16_t ncbs; 86 | my_uint16_t max_ncbs; 87 | my_uint16_t no_transmit_buffers; 88 | my_uint16_t max_datagram; 89 | my_uint16_t pending_sessions; 90 | my_uint16_t max_sessions; 91 | my_uint16_t packet_sessions; 92 | } nbname_response_footer_t; 93 | 94 | #define NBNAME_RESPONSE_FOOTER_SIZE 50 95 | 96 | struct nb_host_info 97 | { 98 | struct nbname_response_header *header; 99 | struct nbname *names; 100 | struct nbname_response_footer *footer; 101 | int is_broken; 102 | }; 103 | 104 | typedef struct nb_service 105 | { 106 | char nb_name[16]; 107 | my_uint8_t service_number; 108 | int unique; 109 | char *service_name; 110 | } nb_service_t; 111 | 112 | char * 113 | getnbservicename ( my_uint8_t service, int unique, char *name ); 114 | 115 | struct nb_host_info * 116 | parse_response ( char *buff, unsigned int buffsize ); 117 | 118 | void 119 | send_query ( int sock, struct in_addr dest_addr, my_uint32_t rtt_base ); 120 | 121 | #endif /* STATUSQ_H */ 122 | -------------------------------------------------------------------------------- /src/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | # Copyright 1999-2003 Alla Bezroutchko 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 version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | */ 18 | 19 | #ifndef timerclear 20 | #define timerclear( tvp ) ( tvp )->tv_sec = ( tvp )->tv_usec = 0 21 | #endif 22 | 23 | #ifndef timercmp 24 | #define timercmp( tvp, uvp, cmp ) \ 25 | ( ( ( tvp )->tv_sec == ( uvp )->tv_sec ) \ 26 | ? ( ( tvp )->tv_usec cmp ( uvp )->tv_usec ) \ 27 | : ( ( tvp )->tv_sec cmp ( uvp )->tv_sec ) ) 28 | #endif 29 | 30 | #ifndef timersub 31 | #define timersub( tvp, uvp, vvp ) \ 32 | do \ 33 | { \ 34 | ( vvp )->tv_sec = ( tvp )->tv_sec - ( uvp )->tv_sec; \ 35 | ( vvp )->tv_usec = ( tvp )->tv_usec - ( uvp )->tv_usec; \ 36 | if ( ( vvp )->tv_usec < 0 ) \ 37 | { \ 38 | ( vvp )->tv_sec--; \ 39 | ( vvp )->tv_usec += 1000000; \ 40 | } \ 41 | } \ 42 | while ( 0 ) 43 | #endif 44 | --------------------------------------------------------------------------------