1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-06 04:31:29 +00:00

Merged nmap-dedup branch from nmap-exp/luis/nmap-dedup. This completes the Nmap/Nping code de-duplication phase.

This commit is contained in:
luis
2010-06-22 17:24:34 +00:00
parent c069b10c27
commit da126c8b78
29 changed files with 6665 additions and 7504 deletions

View File

@@ -8,6 +8,7 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
sbindir = @sbindir@
mandir = @mandir@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
nmapdatadir = @datadir@/nmap
deskdir = $(prefix)/share/applications
@@ -46,7 +47,7 @@ export CFLAGS = $(CXXFLAGS)
# CFLAGS = $(DEFS) $(INCLS)
STATIC =
LDFLAGS = @LDFLAGS@ $(DBGFLAGS) $(STATIC)
LIBS = @LIBNBASE_LIBS@ @LIBNSOCK_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ @OPENSSL_LIBS@ @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBS@
LIBS = @LIBNBASE_LIBS@ @LIBNSOCK_LIBS@ @LIBPCRE_LIBS@ @LIBPCAP_LIBS@ @OPENSSL_LIBS@ libnetutil/libnetutil.a @LIBDNET_LIBS@ @LIBLUA_LIBS@ @LIBS@
# LIBS = -lefence @LIBS@
# LIBS = -lrmalloc @LIBS@
INSTALL = @INSTALL@
@@ -101,10 +102,10 @@ OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o
.cc.o:
$(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@
all: @LUA_BUILD@ @PCAP_BUILD@ @PCRE_BUILD@ @DNET_BUILD@ @NBASE_BUILD@ @NSOCK_BUILD@ @NCAT_BUILD@
all: @LUA_BUILD@ @PCAP_BUILD@ @PCRE_BUILD@ @DNET_BUILD@ @NBASE_BUILD@ @NSOCK_BUILD@ @NCAT_BUILD@ netutil_build
$(MAKE) $(TARGET) $(BUILDZENMAP) $(BUILDNDIFF) $(BUILDNPING)
$(TARGET): @LUA_DEPENDS@ @PCAP_DEPENDS@ @PCRE_DEPENDS@ @DNET_DEPENDS@ $(NBASEDIR)/libnbase.a $(NSOCKDIR)/src/libnsock.a $(OBJS)
$(TARGET): @LUA_DEPENDS@ @PCAP_DEPENDS@ @PCRE_DEPENDS@ @DNET_DEPENDS@ $(NBASEDIR)/libnbase.a $(NSOCKDIR)/src/libnsock.a libnetutil/libnetutil.a $(OBJS)
@echo Compiling nmap
rm -f $@
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
@@ -126,6 +127,10 @@ nsock_build: $(NSOCKDIR)/src/Makefile nbase_build
@echo Compiling libnsock;
cd $(NSOCKDIR)/src && $(MAKE)
netutil_build: libnetutil/Makefile
@echo Compiling libnetutil;
cd libnetutil && $(MAKE)
ncat_build: $(NCATDIR)/Makefile nbase_build nsock_build $(NCATDIR)/ncat.h
cd $(NCATDIR) && $(MAKE)
@@ -160,7 +165,7 @@ release-rpms:
web:
cd $(NMAPDEVDIR) && $(MAKE) web
clean: @LUA_CLEAN@ @PCAP_CLEAN@ @PCRE_CLEAN@ @DNET_CLEAN@ nsock_clean nbase_clean my_clean @NPING_CLEAN@ @ZENMAP_CLEAN@ @NCAT_CLEAN@
clean: @LUA_CLEAN@ @PCAP_CLEAN@ @PCRE_CLEAN@ @DNET_CLEAN@ nsock_clean nbase_clean netutil_clean my_clean @NPING_CLEAN@ @ZENMAP_CLEAN@ @NCAT_CLEAN@
my_clean:
rm -f dependencies.mk makefile.dep
@@ -175,6 +180,8 @@ nbase_clean:
-cd $(NBASEDIR) && $(MAKE) clean
nsock_clean:
-cd $(NSOCKDIR)/src && $(MAKE) clean
netutil_clean:
-cd libnetutil && $(MAKE) clean
ncat_clean:
-cd $(NCATDIR) && $(MAKE) clean
lua_clean:
@@ -197,6 +204,8 @@ nbase_dist_clean:
-cd $(NBASEDIR) && $(MAKE) distclean
nsock_dist_clean:
-cd $(NSOCKDIR)/src && $(MAKE) distclean
netutil_dist_clean:
-cd libnetutil && $(MAKE) distclean
ncat_dist_clean:
-cd $(NCATDIR) && $(MAKE) distclean
zenmap_dist_clean: zenmap_clean
@@ -208,7 +217,7 @@ nping_dist_clean:
debugclean:
rm -f *.gcov *.gcda *.gcno gmon.out
distclean: my_clean my_distclean @LUA_DIST_CLEAN@ @PCAP_DIST_CLEAN@ @PCRE_DIST_CLEAN@ @DNET_DIST_CLEAN@ @NPING_DIST_CLEAN@ @ZENMAP_DIST_CLEAN@ @NCAT_DIST_CLEAN@ nbase_dist_clean nsock_dist_clean
distclean: my_clean my_distclean @LUA_DIST_CLEAN@ @PCAP_DIST_CLEAN@ @PCRE_DIST_CLEAN@ @DNET_DIST_CLEAN@ @NPING_DIST_CLEAN@ @ZENMAP_DIST_CLEAN@ @NCAT_DIST_CLEAN@ nbase_dist_clean nsock_dist_clean netutil_dist_clean
my_distclean:
rm -f Makefile Makefile.bak makefile.dep nmap_config.h stamp-h stamp-h.in \
@@ -281,7 +290,7 @@ install-zenmap: $(ZENMAPDIR)/setup.py
build-ndiff:
cd $(NDIFFDIR) && $(PYTHON) setup.py build $(if $(DESTDIR),--executable "$(DEFAULT_PYTHON_PATH)")
build-nping: $(NPINGDIR)/Makefile nbase_build nsock_build $(NPINGDIR)/nping.h
build-nping: $(NPINGDIR)/Makefile nbase_build nsock_build netutil_build $(NPINGDIR)/nping.h
@cd $(NPINGDIR) && $(MAKE)
install-ndiff:

View File

@@ -96,6 +96,7 @@
#include "nmap.h"
#include "FingerPrintResults.h"
#include "libnetutil/netutil.h"
#ifndef NOLUA
#include "nse_main.h"

6647
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -47,6 +47,7 @@ AC_C_INLINE
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
AC_PROG_INSTALL
if test -n "$GXX"; then
@@ -172,6 +173,23 @@ AC_SUBST(LUA_CFLAGS)
dnl Checks for header files.
AC_CHECK_HEADERS(pwd.h termios.h sys/sockio.h)
dnl A special check required for <net/if.h> on Darwin. See
dnl http://www.gnu.org/software/autoconf/manual/html_node/Header-Portability.html.
AC_CHECK_HEADERS([sys/socket.h])
AC_CHECK_HEADERS([net/if.h], [], [],
[#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
])
dnl If any socket libraries needed
AC_SEARCH_LIBS(setsockopt, socket)
@@ -382,7 +400,7 @@ if test $have_libpcap != yes; then
if test "${LIBPCAP_INC+set}" = "set"; then
CPPFLAGS="$CPPFLAGS -I$LIBPCAP_INC"
else
CPPFLAGS="$CPPFLAGS -I$libpcapdir"
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$libpcapdir"
fi
LIBPCAP_LIBS='$(LIBPCAPDIR)/libpcap.a'
PCAP_DEPENDS='$(LIBPCAPDIR)/libpcap.a'
@@ -439,7 +457,7 @@ fi
# If we still don't have it, we use our own
if test $have_pcre != yes ; then
AC_CONFIG_SUBDIRS( libpcre )
CPPFLAGS="-I$LIBPCREDIR $CPPFLAGS"
CPPFLAGS="-I\$(top_srcdir)/$LIBPCREDIR $CPPFLAGS"
LIBPCRE_LIBS="$LIBPCREDIR/libpcre.a"
PCRE_DEPENDS="$LIBPCREDIR/libpcre.a"
PCRE_BUILD="pcre_build"
@@ -491,9 +509,9 @@ AC_HELP_STRING([--with-libdnet=included], [Use the libdnet version included with
# If they didn't provide location, we use the included one
if test $have_dnet != yes ; then
AC_CONFIG_SUBDIRS( libdnet-stripped )
CPPFLAGS="-I$LIBDNETDIR/include $CPPFLAGS"
LIBDNET_LIBS="$LIBDNETDIR/src/.libs/libdnet.a"
DNET_DEPENDS="$LIBDNETDIR/src/.libs/libdnet.a"
CPPFLAGS="-I\$(top_srcdir)/$LIBDNETDIR/include $CPPFLAGS"
LIBDNET_LIBS="\$(top_srcdir)/$LIBDNETDIR/src/.libs/libdnet.a"
DNET_DEPENDS="\$(top_srcdir)/$LIBDNETDIR/src/.libs/libdnet.a"
DNET_BUILD="dnet_build"
DNET_CLEAN="dnet_clean"
DNET_DIST_CLEAN="dnet_dist_clean"
@@ -527,9 +545,9 @@ AC_HELP_STRING([--without-liblua], [Compile without lua (this will exclude all o
yes)
;;
included)
CPPFLAGS="-I$LIBLUADIR $CPPFLAGS"
LIBLUA_LIBS="$LIBLUADIR/liblua.a"
LUA_DEPENDS="$LIBLUADIR/liblua.a"
CPPFLAGS="-I\$(top_srcdir)/$LIBLUADIR $CPPFLAGS"
LIBLUA_LIBS="\$(top_srcdir)/$LIBLUADIR/liblua.a"
LUA_DEPENDS="\$(top_srcdir)/$LIBLUADIR/liblua.a"
LUA_BUILD="lua_build"
LUA_CLEAN="lua_clean"
LUA_DIST_CLEAN="lua_dist_clean"
@@ -588,9 +606,9 @@ else
# if we didn't find we use our own
if test $have_lua != yes; then
AC_MSG_RESULT(no)
CPPFLAGS="-I$LIBLUADIR $CPPFLAGS"
LIBLUA_LIBS="$LIBLUADIR/liblua.a"
LUA_DEPENDS="$LIBLUADIR/liblua.a"
CPPFLAGS="-I\$(top_srcdir)/$LIBLUADIR $CPPFLAGS"
LIBLUA_LIBS="\$(top_srcdir)/$LIBLUADIR/liblua.a"
LUA_DEPENDS="\$(top_srcdir)/$LIBLUADIR/liblua.a"
LUA_BUILD="lua_build"
LUA_CLEAN="lua_clean"
LUA_DIST_CLEAN="lua_dist_clean"
@@ -712,7 +730,7 @@ NBASEDIR="nbase"
)
LDFLAGS="$LDFLAGS -L$NBASEDIR"
CPPFLAGS="$CPPFLAGS -I$NBASEDIR"
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$NBASEDIR"
LIBNBASE_LIBS="-lnbase"
AC_SUBST(NBASEDIR)
@@ -736,7 +754,7 @@ AC_HELP_STRING([--with-libnsock=DIR], [Compile and link to libnsock in DIR]),
)
LDFLAGS="$LDFLAGS -L$NSOCKDIR/src/"
CPPFLAGS="$CPPFLAGS -I$NSOCKDIR/include"
CPPFLAGS="$CPPFLAGS -I\$(top_srcdir)/$NSOCKDIR/include"
LIBNSOCK_LIBS="-lnsock"
AC_SUBST(NSOCKDIR)
@@ -772,7 +790,7 @@ AC_SUBST(NCAT_UNINSTALL)
AC_SUBST(NCAT_CLEAN)
AC_SUBST(NCAT_DIST_CLEAN)
AC_OUTPUT(Makefile)
AC_OUTPUT(Makefile libnetutil/Makefile)
# Krad ASCII ART#!#@$!@#$
if test -f docs/leet-nmap-ascii-art.txt; then
cat docs/leet-nmap-ascii-art.txt

View File

@@ -102,6 +102,7 @@
#include "services.h"
#include "Target.h"
#include "utils.h"
#include "output.h"
#include <stdio.h>
@@ -329,7 +330,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
}
proxy->host.setHostName(name);
if (resolve(name, &ss, &sslen, o.pf()) == 0) {
if (resolve(name, 0, 0, &ss, &sslen, o.pf()) == 0) {
fatal("Could not resolve idle scan zombie host: %s", name);
}
proxy->host.setTargetSockAddr(&ss, sslen);
@@ -337,7 +338,7 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
/* Lets figure out the appropriate source address to use when sending
the pr0bez */
proxy->host.TargetSockAddr(&ss, &sslen);
if (!route_dst(&ss, &rnfo))
if (!nmap_route_dst(&ss, &rnfo))
fatal("Unable to find appropriate source address and device interface to use when sending packets to %s", proxyName);
if (o.spoofsource) {
@@ -390,7 +391,9 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
/* Now for the pcap opening nonsense ... */
/* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer
* header + 64 byte max TCP header. */
proxy->pd = my_pcap_open_live(proxy->host.deviceName(), 152, (o.spoofsource)? 1 : 0, 50);
if((proxy->pd=my_pcap_open_live(proxy->host.deviceName(), 152, (o.spoofsource)? 1 : 0, 50))==NULL)
fatal("%s", PCAP_OPEN_ERRMSG);
p = strdup(proxy->host.targetipstr());
q = strdup(inet_ntoa(proxy->host.v4source()));
@@ -398,6 +401,8 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
free(p);
free(q);
set_pcap_filter(proxy->host.deviceFullName(), proxy->pd, filter);
if (o.debugging)
log_write(LOG_STDOUT, "Packet capture filter (device %s): %s\n", proxy->host.deviceFullName(), filter);
/* Windows nonsense -- I am not sure why this is needed, but I should
get rid of it at sometime */

40
libnetutil/Makefile.in Normal file
View File

@@ -0,0 +1,40 @@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
CXX = @CXX@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@
DEFS += -D_FORTIFY_SOURCE=2
CPPFLAGS = @CPPFLAGS@
LIBDNETDIR = @LIBDNETDIR@
LIBPCAPDIR = @libpcapdir@
TARGET = libnetutil.a
SRCS = $(srcdir)/netutil.cc
OBJS = netutil.o
all: $(TARGET)
$(TARGET): $(OBJS)
rm -f $@
$(AR) cr $@ $(OBJS)
$(RANLIB) $@
clean:
rm -f $(OBJS) $(TARGET)
distclean: clean
rm -rf Makefile
Makefile: Makefile.in $(top_srcdir)/config.status
cd $(top_srcdir) && ./config.status
.cc.o:
$(CXX) -c $(CPPFLAGS) $(DEFS) $*.cc
makefile.dep:
$(CXX) -MM $(CPPFLAGS) $(SRCS) > $@
include makefile.dep

View File

@@ -0,0 +1,178 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Name="libnetutil"
ProjectGUID="{99157C3F-39F6-4663-99D7-1D9C1484494E}"
RootNamespace="libnetutil"
Keyword="Win32Proj"
TargetFrameworkVersion="196613"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="."
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..;../mswin32;../nbase;../mswin32/pcap-include;../libdnet-stripped/include"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)/libnetutil.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
AdditionalIncludeDirectories="..;../mswin32;../nbase;../mswin32/pcap-include;../libdnet-stripped/include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
RuntimeLibrary="2"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
WarningLevel="3"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\netutil.cc"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\netutil.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

3686
libnetutil/netutil.cc Normal file

File diff suppressed because it is too large Load Diff

476
libnetutil/netutil.h Normal file
View File

@@ -0,0 +1,476 @@
/***************************************************************************
* netutil.h -- The main include file exposing the external API for *
* libnetutil, a library that provides network-related functions or *
* classes that make it easier to handle things like network interfaces, *
* routing tables, raw packet manipulation, etc. The lib was originally *
* written for use in the Nmap Security Scanner ( http://nmap.org ). *
* *
***********************IMPORTANT NMAP LICENSE TERMS************************
* *
* The Nmap Security Scanner is (C) 1996-2010 Insecure.Com LLC. Nmap is *
* also a registered trademark of Insecure.Com LLC. This program is free *
* software; you may redistribute and/or modify it under the terms of the *
* GNU General Public License as published by the Free Software *
* Foundation; Version 2 with the clarifications and exceptions described *
* below. This guarantees your right to use, modify, and redistribute *
* this software under certain conditions. If you wish to embed Nmap *
* technology into proprietary software, we sell alternative licenses *
* (contact sales@insecure.com). Dozens of software vendors already *
* license Nmap technology such as host discovery, port scanning, OS *
* detection, and version detection. *
* *
* Note that the GPL places important restrictions on "derived works", yet *
* it does not provide a detailed definition of that term. To avoid *
* misunderstandings, we consider an application to constitute a *
* "derivative work" for the purpose of this license if it does any of the *
* following: *
* o Integrates source code from Nmap *
* o Reads or includes Nmap copyrighted data files, such as *
* nmap-os-db or nmap-service-probes. *
* o Executes Nmap and parses the results (as opposed to typical shell or *
* execution-menu apps, which simply display raw Nmap output and so are *
* not derivative works.) *
* o Integrates/includes/aggregates Nmap into a proprietary executable *
* installer, such as those produced by InstallShield. *
* o Links to a library or executes a program that does any of the above *
* *
* The term "Nmap" should be taken to also include any portions or derived *
* works of Nmap. This list is not exclusive, but is meant to clarify our *
* interpretation of derived works with some common examples. Our *
* interpretation applies only to Nmap--we don't speak for other people's *
* GPL works. *
* *
* If you have any questions about the GPL licensing restrictions on using *
* Nmap in non-GPL works, we would be happy to help. As mentioned above, *
* we also offer alternative license to integrate Nmap into proprietary *
* applications and appliances. These contracts have been sold to dozens *
* of software vendors, and generally include a perpetual license as well *
* as providing for priority support and updates as well as helping to *
* fund the continued development of Nmap technology. Please email *
* sales@insecure.com for further information. *
* *
* As a special exception to the GPL terms, Insecure.Com LLC grants *
* permission to link the code of this program with any version of the *
* OpenSSL library which is distributed under a license identical to that *
* listed in the included COPYING.OpenSSL file, and distribute linked *
* combinations including the two. You must obey the GNU GPL in all *
* respects for all of the code used other than OpenSSL. If you modify *
* this file, you may extend this exception to your version of the file, *
* but you are not obligated to do so. *
* *
* If you received these files with a written license agreement or *
* contract stating terms other than the terms above, then that *
* alternative license agreement takes precedence over these comments. *
* *
* Source is provided to this software because we believe users have a *
* right to know exactly what a program is going to do before they run it. *
* This also allows you to audit the software for security holes (none *
* have been found so far). *
* *
* Source code also allows you to port Nmap to new platforms, fix bugs, *
* and add new features. You are highly encouraged to send your changes *
* to nmap-dev@insecure.org for possible incorporation into the main *
* distribution. By sending these changes to Fyodor or one of the *
* Insecure.Org development mailing lists, it is assumed that you are *
* offering the Nmap Project (Insecure.Com LLC) the unlimited, *
* non-exclusive right to reuse, modify, and relicense the code. Nmap *
* will always be available Open Source, but this is important because the *
* inability to relicense code has caused devastating problems for other *
* Free Software projects (such as KDE and NASM). We also occasionally *
* relicense the code to third parties as discussed above. If you wish to *
* specify special license conditions of your contributions, just say so *
* when you send them. *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License v2.0 for more details at *
* http://www.gnu.org/licenses/gpl-2.0.html , or in the COPYING file *
* included with Nmap. *
* *
***************************************************************************/
/* $Id: netutil.h 18098 2010-06-14 11:50:12Z luis $ */
#ifndef _NETUTIL_H_
#define _NETUTIL_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include <pcap.h>
#ifdef __cplusplus
}
#endif
#include "dnet.h"
enum { OP_FAILURE = -1, OP_SUCCESS = 0 };
/* For systems without SCTP in netinet/in.h, such as MacOS X or Win */
#ifndef IPPROTO_SCTP
#define IPPROTO_SCTP 132
#endif
int netutil_fatal(const char *str, ...)
__attribute__ ((format (printf, 1, 2)));
int netutil_error(const char *str, ...)
__attribute__ ((format (printf, 1, 2)));
/* This function converts zero-terminated 'txt' string to binary 'data'.
It is used to parse user input for ip options. Some examples of possible input
strings and results:
'\x01*2\xA2' -> [0x01,0x01,0xA2] // with 'x' number is parsed in hex
'\01\01\255' -> [0x01,0x01,0xFF] // without 'x' its in decimal
'\x01\x00*2' -> [0x01,0x00,0x00] // '*' is copying char
'R' -> Record Route with 9 slots
'S 192.168.0.1 172.16.0.1' -> Strict Route with 2 slots
'L 192.168.0.1 172.16.0.1' -> Loose Route with 2 slots
'T' -> Record Timestamp with 9 slots
'U' -> Record Timestamp and Ip Address with 4 slots
On success, the function returns the length of the final binary
options stored in "data". In case of error, OP_FAILURE is returned
and the "errstr" buffer is filled with an error message
(unless it's NULL). Note that the returned error message does NOT
contain a newline character at the end. */
int parse_ip_options(const char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff, char *errstr, size_t errstrlen);
/* Tries to resolve the given name (or literal IP) into a sockaddr structure.
- Parameter "hostname" is the name to be resolved.
- Parameter "port" sets the port in each returned address structure
(you can safely pass 0 for the port if you don't care)
- Parameter "nodns": If set, it means that the supplied hostname is actually a
numeric IP address. The flag prevents any type of name resolution service
from being called. In 99% of the cases this should be 0.
Returns 1 on success or 0 if hostname could not be resolved. */
int resolve(const char *hostname, u16 port, int nodns, struct sockaddr_storage *ss, size_t *sslen, int af);
/*
* Returns 1 if this is a reserved IP address, where "reserved" means
* either a private address, non-routable address, or even a non-reserved
* but unassigned address which has an extremely high probability of being
* black-holed.
*
* We try to optimize speed when ordering the tests. This optimization
* assumes that all byte values are equally likely in the input.
*
* Warning: This function needs frequent attention because IANA has been
* allocating address blocks many times per year (although it's questionable
* how much longer this trend can be kept up).
*
* Check
* <http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt>
* for the most recent assigments and
* <http://www.cymru.com/Documents/bogon-bn-nonagg.txt> for bogon
* netblocks.
*/
int ip_is_reserved(struct in_addr *ip);
/* A couple of trivial functions that maintain a cache of IP to MAC
* Address entries. Function arp_cache_get() looks for the IPv4 address
* in ss and fills in the 'mac' parameter and returns true if it is
* found. Otherwise (not found), the function returns false.
* Function arp_cache_set() adds an entry with the given ip (ss) and
* mac address. An existing entry for the IP ss will be overwritten
* with the new MAC address. arp_cache_set() always returns true. */
int arp_cache_get(struct sockaddr_storage *ss, u8 *mac);
int arp_cache_set(struct sockaddr_storage *ss, u8 *mac);
/* Standard BSD internet checksum routine. */
unsigned short in_cksum(u16 *ptr, int nbytes);
/* For computing TCP/UDP checksums, see RFC 1071 and TCP/IP Illustrated
sections 3.2, 11.3, and 17.3.*/
unsigned short tcpudp_cksum(const struct in_addr *src, const struct in_addr *dst,
u8 proto, u16 len, const void *hstart);
void sethdrinclude(int sd);
void set_ipoptions(int sd, void *opts, size_t optslen);
void set_ttl(int sd, int ttl);
/* Returns whether the system supports pcap_get_selectable_fd() properly */
int pcap_selectable_fd_valid();
/* Call this instead of pcap_get_selectable_fd directly (or your code
won't compile on Windows). On systems which don't seem to support
the pcap_get_selectable_fd() function properly, returns -1,
otherwise simply calls pcap_selectable_fd and returns the
results. If you just want to test whether the function is supported,
use pcap_selectable_fd_valid() instead. */
int my_pcap_get_selectable_fd(pcap_t *p);
/* These two function return -1 if we can't use select() on the pcap
* device, 0 for timeout, and >0 for success. If select() fails we bail
* out because it couldn't work with the file descriptor we got from
* my_pcap_get_selectable_fd() */
int pcap_select(pcap_t *p, struct timeval *timeout);
int pcap_select(pcap_t *p, long usecs);
typedef enum { devt_ethernet, devt_loopback, devt_p2p, devt_other } devtype;
#define MAX_LINK_HEADERSZ 24
struct link_header {
int datalinktype; /* pcap_datalink(), such as DLT_EN10MB */
int headerlen; /* 0 if header was too big or unavailaable */
u8 header[MAX_LINK_HEADERSZ];
};
/* Relevant (to Nmap) information about an interface */
struct interface_info {
char devname[16];
char devfullname[16]; /* can include alias info, such as eth0:2. */
struct sockaddr_storage addr;
u16 netmask_bits; /* CIDR-style. So 24 means class C (255.255.255.0)*/
devtype device_type; /* devt_ethernet, devt_loopback, devt_p2p, devt_other */
int device_up; /* True if the device is up (enabled) */
u8 mac[6]; /* Interface MAC address if device_type is devt_ethernet */
};
struct route_nfo {
struct interface_info ii;
/* true if the target is directly connected on the network (no routing
required). */
int direct_connect;
/* This is the source address that should be used by the packets. It
may be different than ii.addr if you are using localhost interface
to scan the IP of another interface on the machine */
struct sockaddr_storage srcaddr;
/* If direct_connect is 0, this is filled in with the next hop
required to route to the target */
struct sockaddr_storage nexthop;
};
struct sys_route {
struct interface_info *device;
u32 dest;
u32 netmask;
struct in_addr gw; /* gateway - 0 if none */
};
struct eth_nfo {
char srcmac[6];
char dstmac[6];
eth_t *ethsd; // Optional, but improves performance. Set to NULL if unavail
char devname[16]; // Only needed if ethsd is NULL.
};
/* A simple function that caches the eth_t from dnet for one device,
to avoid opening, closing, and re-opening it thousands of tims. If
you give a different device, this function will close the first
one. Thus this should never be used by programs that need to deal
with multiple devices at once. In addition, you MUST NEVER
eth_close() A DEVICE OBTAINED FROM THIS FUNCTION. Instead, you can
call eth_close_cached() to close whichever device (if any) is
cached. Returns NULL if it fails to open the device. */
eth_t *eth_open_cached(const char *device);
/* See the description for eth_open_cached */
void eth_close_cached();
/* Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or
* IPPROTO_IP and returns a ascii representation (or "unknown" if it
* doesn't recognize the number). Returned string is in lowercase. */
const char *proto2ascii_lowercase(u8 proto) ;
/* Same as proto2ascii() but returns a string in uppercase. */
const char *proto2ascii_uppercase(u8 proto);
/* Get an ASCII information about a tcp option which is pointed by
optp, with a length of len. The result is stored in the result
buffer. The result may look like "<mss 1452,sackOK,timestamp
45848914 0,nop,wscale 7>" */
void tcppacketoptinfo(u8 *optp, int len, char *result, int bufsize);
/* Convert an IP address to the device (IE ppp0 eth0) using that
* address. Supplied "dev" must be able to hold at least 32 bytes.
* Returns 0 on success or -1 in case of error. */
int ipaddr2devname( char *dev, const struct in_addr *addr );
/* Convert a network interface name (IE ppp0 eth0) to an IPv4 address.
* Returns 0 on success or -1 in case of error. */
int devname2ipaddr(char *dev, struct in_addr *addr);
/* Returns an allocated array of struct interface_info representing the
available interfaces. The number of interfaces is returned in *howmany. This
function just does caching of results; the real work is done in
getinterfaces_dnet() or getinterfaces_siocgifconf().
On error, NULL is returned, howmany is set to -1 and the supplied
error buffer "errstr", if not NULL, will contain an error message. */
struct interface_info *getinterfaces(int *howmany, char *errstr, size_t errstrlen);
/* This struct is abused to carry either routes or interfaces, depending on the
function it's used in. */
struct dnet_collector_route_nfo {
struct sys_route *routes;
int numroutes;
int capacity; /* Capacity of routes or ifaces, depending on context */
struct interface_info *ifaces;
int numifaces;
};
/* Looks for an interface with the given name (iname), and returns the
corresponding interface_info if found. Will accept a match of
devname or devfullname. Returns NULL if none found */
struct interface_info *getInterfaceByName(char *iname);
/* Parse the system routing table, converting each route into a
sys_route entry. Returns an array of sys_routes. numroutes is set
to the number of routes in the array. The routing table is only
read the first time this is called -- later results are cached.
The returned route array is sorted by netmask with the most
specific matches first.
On error, NULL is returned, howmany is set to -1 and the supplied
error buffer "errstr", if not NULL, will contain an error message. */
struct sys_route *getsysroutes(int *howmany, char *errstr, size_t errstrlen);
/* Tries to determine whether the supplied address corresponds to
* localhost. (eg: the address is something like 127.x.x.x, the address
* matches one of the local network interfaces' address, etc).
* Returns 1 if the address is thought to be localhost and 0 otherwise */
int islocalhost(const struct in_addr *const addr);
/* Determines whether the supplied address corresponds to a private,
* non-Internet-routable address. See RFC1918 for details.
* Returns 1 if the address is private or 0 otherwise. */
int isipprivate(const struct in_addr *const addr);
/* Takes binary data found in the IP Options field of an IPv4 packet
* and returns a string containing an ASCII description of the options
* found. The function returns a pointer to a static buffer that
* subsequent calls will overwrite. On error, NULL is returned. */
char *format_ip_options(u8* ipopt, int ipoptlen);
/* Returns a buffer of ASCII information about an IP packet that may
* look like "TCP 127.0.0.1:50923 > 127.0.0.1:3 S ttl=61 id=39516
* iplen=40 seq=625950769" or "ICMP PING (0/1) ttl=61 id=39516 iplen=40".
* Returned buffer is static so it is NOT safe to call this in
* multi-threaded environments without appropriate sync protection, or
* call it twice in the same sentence (eg: as two printf parameters).
* Obviously, the caller should never attempt to free() the buffer. The
* returned buffer is guaranteed to be NULL-terminated but no
* assumptions should be made concerning its length.
*
* The function provides full support for IPv4,TCP,UDP,SCTP and ICMPv4.
* It also provides support for standard IPv6 but not for its extension
* headers. If an IPv6 packet contains an ICMPv6 Header, the output will
* reflect this but no parsing of ICMPv6 contents will be performed.
*
* The output has three different levels of detail. Parameter "detail"
* determines how verbose the output should be. It should take one of
* the following values:
*
* LOW_DETAIL (0x01): Traditional output.
* MEDIUM_DETAIL (0x02): More verbose than traditional.
* HIGH_DETAIL (0x03): Contents of virtually every field of the
* protocol headers .
*/
#define LOW_DETAIL 1
#define MEDIUM_DETAIL 2
#define HIGH_DETAIL 3
const char *ippackethdrinfo(const u8 *packet, u32 len, int detail);
/* Takes an IPv4 destination address (dst) and tries to determine the
* source address and interface necessary to route to this address.
* If no route is found, 0 is returned and "rnfo" is undefined. If
* a route is found, 1 is returned and "rnfo" is filled in with all
* of the routing details. If the source address needs to be spoofed,
* it should be passed through "spoofss" (otherwise NULL should be
* specified), along with a suitable network device (parameter "device").
* Even if spoofss is NULL, if user specified a network device with -e,
* it should still be passed. Note that it's OK to pass either NULL or
* an empty string as the "device", as long as spoofss==NULL. */
int route_dst(const struct sockaddr_storage * const dst, struct route_nfo *rnfo,
char *device, struct sockaddr_storage *spoofss);
/* Send an IP packet over a raw socket. */
int send_ip_packet_sd(int sd, u8 *packet, unsigned int packetlen);
/* Send an IP packet over an ethernet handle. */
int send_ip_packet_eth(struct eth_nfo *eth, u8 *packet, unsigned int packetlen);
/* Sends the supplied pre-built IPv4 packet. The packet is sent through
* the raw socket "sd" if "eth" is NULL. Otherwise, it gets sent at raw
* ethernet level. */
int send_ip_packet_eth_or_sd(int sd, struct eth_nfo *eth, u8 *packet, unsigned int packetlen);
/* Create and send all fragments of a pre-built IPv4 packet.
* Minimal MTU for IPv4 is 68 and maximal IPv4 header size is 60
* which gives us a right to cut TCP header after 8th byte */
int send_frag_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
unsigned int packetlen, unsigned int mtu);
/* Wrapper for system function sendto(), which retries a few times when
* the call fails. It also prints informational messages about the
* errors encountered. It returns the number of bytes sent or -1 in
* case of error. */
int Sendto(const char *functionname, int sd, const unsigned char *packet,
int len, unsigned int flags, struct sockaddr *to, int tolen);
/* This function is used to obtain a packet capture handle to look at
* packets on the network. It is actually a wrapper for libpcap's
* pcap_open_live() that takes care of compatibility issues and error
* checking. Prints an error and fatal()s if the call fails, so a
* valid pcap_t will always be returned. */
pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc, int to_ms);
/* Set a pcap filter */
void set_pcap_filter(const char *device, pcap_t *pd, const char *bpf, ...);
/* Issues an ARP request for the MAC of targetss (which will be placed
in targetmac if obtained) from the source IP (srcip) and source mac
(srcmac) given. "The request is ussued using device dev to the
broadcast MAC address. The transmission is attempted up to 3
times. If none of these elicit a response, false will be returned.
If the mac is determined, true is returned. The last parameter is
a pointer to a callback function that can be used for packet traceing.
This is intended to be used by Nmap only. Any other calling this
should pass NULL instead. */
bool doArp(const char *dev, const u8 *srcmac,
const struct sockaddr_storage *srcip,
const struct sockaddr_storage *targetip,
u8 *targetmac,
void (*traceArp_callback)(int, const u8 *, u32 , struct timeval *));
/* Attempts to read one IPv4/Ethernet ARP reply packet from the pcap
descriptor pd. If it receives one, fills in sendermac (must pass
in 6 bytes), senderIP, and rcvdtime (can be NULL if you don't care)
and returns 1. If it times out and reads no arp requests, returns
0. to_usec is the timeout period in microseconds. Use 0 to avoid
blocking to the extent possible. Returns -1 or exits if there is
an error. The last parameter is a pointer to a callback function
that can be used for packet tracing. This is intended to be used
by Nmap only. Any other calling this should pass NULL instead. */
int read_arp_reply_pcap(pcap_t *pd, u8 *sendermac,
struct in_addr *senderIP, long to_usec,
struct timeval *rcvdtime,
void (*traceArp_callback)(int, const u8 *, u32 , struct timeval *));
/* Read a single host specification from a file, as for -iL and --excludefile.
It returns the length of the string read; an overflow is indicated when the
return value is >= n. Returns 0 if there was no specification to be read. The
buffer is always null-terminated. */
size_t read_host_from_file(FILE *fp, char *buf, size_t n);
/* Return next target host specification from the supplied stream.
* if parameter "random" is set to true, then the function will
* return a random, non-reserved, IP address in decimal-dot notation */
char *grab_next_host_spec(FILE *inputfd, bool random, int argc, char **fakeargv);
#ifdef WIN32
/* Convert a dnet interface name into the long pcap style. This also caches the
data to speed things up. Fills out pcapdev (up to pcapdevlen) and returns
true if it finds anything. Otherwise returns false. This is only necessary
on Windows. */
int DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen);
#endif
#endif /* _NETUTIL_H_ */

View File

@@ -1,5 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nmap", "nmap.vcproj", "{361719F0-AB42-4C93-9DE8-7D2144B96625}"
ProjectSection(ProjectDependencies) = postProject
{31FB0767-A71F-4575-8379-002D72B8AF86} = {31FB0767-A71F-4575-8379-002D72B8AF86}
@@ -30,6 +30,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ncat", "..\ncat\ncat.vcproj
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nping", "..\nping\nping.vcproj", "{CDB10BBA-9085-4B9B-AC8F-BA31D3906B36}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnetutil", "..\libnetutil\libnetutil.vcproj", "{99157C3F-39F6-4663-99D7-1D9C1484494E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -68,6 +70,10 @@ Global
{CDB10BBA-9085-4B9B-AC8F-BA31D3906B36}.Debug|Win32.Build.0 = Debug|Win32
{CDB10BBA-9085-4B9B-AC8F-BA31D3906B36}.Release|Win32.ActiveCfg = Release|Win32
{CDB10BBA-9085-4B9B-AC8F-BA31D3906B36}.Release|Win32.Build.0 = Release|Win32
{99157C3F-39F6-4663-99D7-1D9C1484494E}.Debug|Win32.ActiveCfg = Debug|Win32
{99157C3F-39F6-4663-99D7-1D9C1484494E}.Debug|Win32.Build.0 = Debug|Win32
{99157C3F-39F6-4663-99D7-1D9C1484494E}.Release|Win32.ActiveCfg = Release|Win32
{99157C3F-39F6-4663-99D7-1D9C1484494E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="nmap"
ProjectGUID="{361719F0-AB42-4C93-9DE8-7D2144B96625}"
RootNamespace="nmap"
@@ -72,11 +72,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="liblua.lib nsock.lib libpcre.lib nbase.lib libdnet-stripped.lib ws2_32.lib IPHlpAPI.Lib wpcap.lib packet.lib advapi32.lib libeay32.lib ssleay32.lib shell32.lib $(NOINHERIT)"
AdditionalDependencies="liblua.lib nsock.lib libpcre.lib nbase.lib libdnet-stripped.lib ws2_32.lib IPHlpAPI.Lib wpcap.lib packet.lib advapi32.lib libeay32.lib ssleay32.lib shell32.lib libnetutil.lib $(NOINHERIT)"
OutputFile=".\Debug\nmap.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="lib;..\liblua;..\libpcre;..\nsock;..\nbase;&quot;..\libdnet-stripped&quot;;OpenSSL\lib;"
AdditionalLibraryDirectories="lib;..\liblua;..\libpcre;..\nsock;..\nbase;&quot;..\libdnet-stripped&quot;;../libnetutil;OpenSSL\lib"
IgnoreDefaultLibraryNames=""
DelayLoadDLLs="packet.dll,wpcap.dll,iphlpapi.dll"
GenerateDebugInformation="true"
@@ -165,11 +165,11 @@
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="liblua.lib nsock.lib libpcre.lib nbase.lib libdnet-stripped.lib ws2_32.lib IPHlpAPI.Lib wpcap.lib packet.lib advapi32.lib libeay32.lib ssleay32.lib shell32.lib $(NOINHERIT)"
AdditionalDependencies="liblua.lib nsock.lib libpcre.lib nbase.lib libdnet-stripped.lib ws2_32.lib IPHlpAPI.Lib wpcap.lib packet.lib advapi32.lib libeay32.lib ssleay32.lib shell32.lib libnetutil.lib $(NOINHERIT)"
OutputFile=".\Release/nmap.exe"
LinkIncremental="2"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="lib;..\liblua;..\libpcre;..\nsock;..\nbase;&quot;..\libdnet-stripped&quot;;OpenSSL\lib;"
AdditionalLibraryDirectories="lib;..\liblua;..\libpcre;..\nsock;..\nbase;&quot;..\libdnet-stripped&quot;;../libnetutil;OpenSSL\lib"
IgnoreDefaultLibraryNames=""
DelayLoadDLLs="packet.dll,wpcap.dll,iphlpapi.dll"
ProgramDatabaseFile=".\Release/nmap.pdb"

165
nmap.cc
View File

@@ -320,123 +320,6 @@ printf("%s %s ( %s )\n"
exit(rc);
}
/**
* Returns 1 if this is a reserved IP address, where "reserved" means
* either a private address, non-routable address, or even a non-reserved
* but unassigned address which has an extremely high probability of being
* black-holed.
*
* We try to optimize speed when ordering the tests. This optimization
* assumes that all byte values are equally likely in the input.
*
* Warning: This function needs frequent attention because IANA has been
* allocating address blocks many times per year (although it's questionable
* how much longer this trend can be kept up).
*
* Check
* <http://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.txt>
* for the most recent assigments and
* <http://www.cymru.com/Documents/bogon-bn-nonagg.txt> for bogon
* netblocks.
*/
static int ip_is_reserved(struct in_addr *ip)
{
char *ipc = (char *) &(ip->s_addr);
unsigned char i1 = ipc[0], i2 = ipc[1], i3 = ipc[2]; /* i4 not currently used - , i4 = ipc[3]; */
/* do all the /7's and /8's with a big switch statement, hopefully the
* compiler will be able to optimize this a little better using a jump table
* or what have you
*/
switch (i1)
{
case 0: /* 000/8 is IANA reserved */
case 5: /* 005/8 is IANA reserved */
case 6: /* USA Army ISC */
case 7: /* used for BGP protocol */
case 10: /* the infamous 10.0.0.0/8 */
case 23: /* 023/8 is IANA reserved */
case 36: /* 036/8 is IANA reserved */
case 37: /* 037/8 is IANA reserved */
case 39: /* 039/8 is IANA reserved */
case 42: /* 042/8 is IANA reserved */
case 49: /* 049/8 is IANA reserved */
case 55: /* misc. U.S.A. Armed forces */
case 127: /* 127/8 is reserved for loopback */
case 179: /* 179/8 is IANA reserved */
case 185: /* 185/8 is IANA reserved */
return 1;
default:
break;
}
/* 100-106/8 is IANA reserved */
if (i1 >= 100 && i1 <= 106)
return 1;
/* 172.16.0.0/12 is reserved for private nets by RFC1819 */
if (i1 == 172 && i2 >= 16 && i2 <= 31)
return 1;
/* 192.0.2.0/24 is reserved for documentation and examples (RFC5737) */
/* 192.88.99.0/24 is used as 6to4 Relay anycast prefix by RFC3068 */
/* 192.168.0.0/16 is reserved for private nets by RFC1819 */
if (i1 == 192) {
if (i2 == 0 && i3 == 2)
return 1;
if (i2 == 88 && i3 == 99)
return 1;
if (i2 == 168)
return 1;
}
/* 198.18.0.0/15 is used for benchmark tests by RFC2544 */
/* 198.51.100.0/24 is reserved for documentation (RFC5737) */
if (i1 == 198) {
if (i2 == 18 || i2 == 19)
return 1;
if (i2 == 51 && i3 == 100)
return 1;
}
/* 169.254.0.0/16 is reserved for DHCP clients seeking addresses */
if (i1 == 169 && i2 == 254)
return 1;
/* 203.0.113.0/24 is reserved for documentation (RFC5737) */
if (i1 == 203 && i2 == 0 && i3 == 113)
return 1;
/* 224-239/8 is all multicast stuff */
/* 240-255/8 is IANA reserved */
if (i1 >= 224)
return 1;
return 0;
}
static char *grab_next_host_spec(FILE *inputfd, int argc, char **fakeargv) {
static char host_spec[1024];
struct in_addr ip;
size_t n;
if (o.generate_random_ips) {
do {
ip.s_addr = get_random_unique_u32();
} while (ip_is_reserved(&ip));
Strncpy(host_spec, inet_ntoa(ip), sizeof(host_spec));
} else if (!inputfd) {
return( (optind < argc)? fakeargv[optind++] : NULL);
} else {
n = read_host_from_file(inputfd, host_spec, sizeof(host_spec));
if (n == 0)
return NULL;
else if (n >= sizeof(host_spec))
fatal("One of the host specifications from your input file is too long (>= %u chars)", (unsigned int) sizeof(host_spec));
}
return host_spec;
}
static void insert_port_into_merge_list(unsigned short *mlist,
int *merged_port_count,
unsigned short p) {
@@ -581,6 +464,7 @@ int nmap_main(int argc, char *argv[]) {
time_t timep;
char mytime[128];
char tbuf[128];
char errstr[256];
struct sockaddr_storage ss;
size_t sslen;
int option_index;
@@ -980,7 +864,8 @@ int nmap_main(int argc, char *argv[]) {
fatal("--top-ports should be an integer 1 or greater");
} else if (optcmp(long_options[option_index].name, "ip-options") == 0){
o.ipoptions = (u8*) safe_malloc(4*10+1);
o.ipoptionslen = parse_ip_options(optarg, o.ipoptions, 4*10+1, &o.ipopt_firsthop, &o.ipopt_lasthop);
if( (o.ipoptionslen=parse_ip_options(optarg, o.ipoptions, 4*10+1, &o.ipopt_firsthop, &o.ipopt_lasthop, errstr, sizeof(errstr)))==OP_FAILURE )
fatal("%s", errstr);
if(o.ipoptionslen > 4*10)
fatal("Ip options can't be more than 40 bytes long");
if(o.ipoptionslen %4 != 0)
@@ -1060,7 +945,12 @@ int nmap_main(int argc, char *argv[]) {
} else {
if (o.numdecoys >= MAX_DECOYS -1)
fatal("You are only allowed %d decoys (if you need more redefine MAX_DECOYS in nmap.h)", MAX_DECOYS);
if (resolve(p, &o.decoys[o.numdecoys])) {
/* Try to resolve it */
struct sockaddr_in decoytemp;
size_t decoytemplen=sizeof(struct sockaddr_in);
if( resolve(p, 0, 0, (sockaddr_storage*)&decoytemp, &decoytemplen, AF_INET) == 1 ){
o.decoys[o.numdecoys]=decoytemp.sin_addr;
o.numdecoys++;
} else {
fatal("Failed to resolve decoy host: %s (must be hostname or IP address)", p);
@@ -1244,7 +1134,7 @@ int nmap_main(int argc, char *argv[]) {
case 'S':
if (o.spoofsource)
fatal("You can only use the source option once! Use -D <decoy1> -D <decoy2> etc. for decoys\n");
if (resolve(optarg, &ss, &sslen, o.af()) == 0) {
if (resolve(optarg, 0, 0, &ss, &sslen, o.af()) == 0) {
fatal("Failed to resolve/decode supposed %s source address %s. Note that if you are using IPv6, the -6 argument must come before -S", (o.af() == AF_INET)? "IPv4" : "IPv6", optarg);
}
o.setSourceSockAddr(&ss, sslen);
@@ -1384,7 +1274,7 @@ int nmap_main(int argc, char *argv[]) {
if (o.ipoptionslen >= 8) // at least one ip address
log_write(LOG_STDOUT, "Binary ip options to be send:\n%s", buf);
log_write(LOG_STDOUT, "Parsed ip options to be send:\n%s\n",
print_ip_options(o.ipoptions, o.ipoptionslen));
format_ip_options(o.ipoptions, o.ipoptionslen));
}
/* Open the log files, now that we know whether the user wants them appended
@@ -1740,7 +1630,7 @@ int nmap_main(int argc, char *argv[]) {
/* Now grab any new expressions */
while(num_host_exp_groups < o.ping_group_sz &&
(!o.max_ips_to_scan || o.max_ips_to_scan > o.numhosts_scanned + (int) Targets.size() + num_host_exp_groups) &&
(host_spec = grab_next_host_spec(inputfd, argc, fakeargv))) {
(host_spec = grab_next_host_spec(inputfd, o.generate_random_ips, argc, fakeargv))) {
// For purposes of random scan
host_exp_group[num_host_exp_groups++] = strdup(host_spec);
}
@@ -1804,7 +1694,7 @@ int nmap_main(int argc, char *argv[]) {
currenths->setSourceSockAddr(&ss, sslen);
} else {
if (gethostname(myname, MAXHOSTNAMELEN) ||
resolve(myname, &ss, &sslen, o.af()) == 0)
resolve(myname, 0, 0, &ss, &sslen, o.af()) == 0)
fatal("Cannot get hostname! Try using -S <my_IP_address> or -e <interface to scan through>\n");
o.setSourceSockAddr(&ss, sslen);
@@ -2782,36 +2672,7 @@ int ftp_anon_connect(struct ftpinfo *ftp) {
return sd;
}
/* Returns one if the file pathname given exists, is not a directory and
* is readable by the executing process. Returns two if it is readable
* and is a directory. Otherwise returns 0.
*/
int fileexistsandisreadable(const char *pathname) {
char *pathname_buf = strdup(pathname);
int status = 0;
#ifdef WIN32
// stat on windows only works for "dir_name" not for "dir_name/" or "dir_name\\"
int pathname_len = strlen(pathname_buf);
char last_char = pathname_buf[pathname_len - 1];
if( last_char == '/'
|| last_char == '\\')
pathname_buf[pathname_len - 1] = '\0';
#endif
struct stat st;
if (stat(pathname_buf, &st) == -1)
status = 0;
else if (access(pathname_buf, R_OK) != -1)
status = S_ISDIR(st.st_mode) ? 2 : 1;
free(pathname_buf);
return status;
}
int nmap_fileexistsandisreadable(const char* pathname) {
return fileexistsandisreadable(pathname);

View File

@@ -132,6 +132,8 @@
#undef HAVE_SYS_STAT_H
#undef HAVE_NET_IF_H
#undef HAVE_FCNTL_H
#undef HAVE_TERMIOS_H

View File

@@ -799,7 +799,7 @@ static void add_dns_server(char *ipaddrs) {
for (hostname = strtok(ipaddrs, " ,"); hostname != NULL; hostname = strtok(NULL, " ,")) {
if (!resolve(hostname, (struct sockaddr_storage *) &addr, &addr_len, PF_UNSPEC)) continue;
if (!resolve(hostname, 0, 0, (struct sockaddr_storage *) &addr, &addr_len, PF_UNSPEC)) continue;
for(servI = servs.begin(); servI != servs.end(); servI++) {
tpserv = *servI;

View File

@@ -100,6 +100,7 @@
#include "timing.h"
#include "nmap_error.h"
#include "utils.h"
#include "nbase.h"
extern NmapOps o;
static struct rpc_info ri;
@@ -230,7 +231,7 @@ int send_rpc_query(Target *target_host, unsigned short portno,
rpc_xid_base = (unsigned long) get_random_uint();
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Sending RPC probe for program %li to %hu/%s -- scan_offset=%d trynum=%d xid=%lX\n", program, portno, proto2ascii(ipproto), scan_offset, trynum, rpc_xid_base + ((portno & 0x3FFF) << 16) + (trynum << 30) + scan_offset);
log_write(LOG_PLAIN, "Sending RPC probe for program %li to %hu/%s -- scan_offset=%d trynum=%d xid=%lX\n", program, portno, proto2ascii_lowercase(ipproto), scan_offset, trynum, rpc_xid_base + ((portno & 0x3FFF) << 16) + (trynum << 30) + scan_offset);
}
memset(&sock, 0, sizeof(sock));
@@ -372,7 +373,7 @@ static int rpc_are_we_done(char *msg, int msg_len, Target *target,
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because of invalid sized message (%d)\n",
rsi->rpc_current_port->portno,
proto2ascii(rsi->rpc_current_port->proto, true), msg_len);
proto2ascii_uppercase(rsi->rpc_current_port->proto), msg_len);
}
rsi->rpc_status = RPC_STATUS_NOT_RPC;
ss->numqueries_outstanding = 0;
@@ -385,7 +386,7 @@ static int rpc_are_we_done(char *msg, int msg_len, Target *target,
if (((scan_offset >> 16) & 0x3FFF) != (unsigned long) (rsi->rpc_current_port->portno & 0x3FFF)) {
/* Doh -- this doesn't seem right */
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because ((scan_offset >> 16) & 0x3FFF) is %li\n", rsi->rpc_current_port->portno, proto2ascii(rsi->rpc_current_port->proto, true), ((scan_offset >> 16) & 0x3FFF));
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because ((scan_offset >> 16) & 0x3FFF) is %li\n", rsi->rpc_current_port->portno, proto2ascii_uppercase(rsi->rpc_current_port->proto), ((scan_offset >> 16) & 0x3FFF));
}
rsi->rpc_status = RPC_STATUS_NOT_RPC;
ss->numqueries_outstanding = 0;
@@ -465,13 +466,13 @@ static int rpc_are_we_done(char *msg, int msg_len, Target *target,
if (o.debugging > 1) {
error("Port %hu/%s claims that it is not RPC service %li",
rsi->rpc_current_port->portno,
proto2ascii(rsi->rpc_current_port->proto, true), current->portno);
proto2ascii_uppercase(rsi->rpc_current_port->proto), current->portno);
}
rsi->valid_responses_this_port++;
return 0;
} else if (ntohl(rpc_pack->accept_stat) == PROG_MISMATCH) {
if (o.debugging > 1) {
error("Port %hu/%s claims IT IS RPC service %li", rsi->rpc_current_port->portno, proto2ascii(rsi->rpc_current_port->proto, true), current->portno);
error("Port %hu/%s claims IT IS RPC service %li", rsi->rpc_current_port->portno, proto2ascii_uppercase(rsi->rpc_current_port->proto), current->portno);
}
current->state = PORT_OPEN;
rsi->rpc_status = RPC_STATUS_GOOD_PROG;
@@ -589,7 +590,7 @@ void get_rpc_results(Target *target, struct portinfo *scan,
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because tcp_readlen is %d (should be at least 28)\n",
rsi->rpc_current_port->portno,
proto2ascii(rsi->rpc_current_port->proto, true),
proto2ascii_uppercase(rsi->rpc_current_port->proto),
(int) tcp_readlen);
}
ss->numqueries_outstanding = 0;
@@ -603,7 +604,7 @@ void get_rpc_results(Target *target, struct portinfo *scan,
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because current_msg_len is %li while tcp_readlen is %d\n",
rsi->rpc_current_port->portno,
proto2ascii(rsi->rpc_current_port->proto, true),
proto2ascii_uppercase(rsi->rpc_current_port->proto),
current_msg_len, (int) tcp_readlen);
}
ss->numqueries_outstanding = 0;
@@ -634,7 +635,7 @@ void get_rpc_results(Target *target, struct portinfo *scan,
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Port %hu/%s labelled NON_RPC because current_msg_len is %li\n",
rsi->rpc_current_port->portno,
proto2ascii(rsi->rpc_current_port->proto, true),
proto2ascii_uppercase(rsi->rpc_current_port->proto),
current_msg_len);
}
rsi->rpc_status = RPC_STATUS_NOT_RPC;

View File

@@ -21,6 +21,7 @@ extern "C"
#include "utils.h"
#include "tcpip.h"
#include "protocols.h"
#include "libnetutil/netutil.h"
#if HAVE_OPENSSL
# include <openssl/ssl.h>
@@ -1324,10 +1325,6 @@ int l_nsock_sleep(lua_State * L)
}
/****************** NCAP_SOCKET ***********************************************/
#ifdef WIN32
/* From tcpip.cc. Gets pcap device name from dnet name. */
bool DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen);
#endif
/* fuckin' C++ maps stuff */
/* here we store ncap_sockets */
@@ -2144,7 +2141,7 @@ static int l_dnet_send_ip(lua_State * L)
dstsin->sin_family = AF_INET;
dstsin->sin_addr.s_addr = ip->ip_dst.s_addr;
if (!route_dst(&dstss, &route))
if (!nmap_route_dst(&dstss, &route))
goto usesock;
strncpy(dev, route.ii.devname, sizeof(dev));

View File

@@ -2992,7 +2992,7 @@ int HostOsScan::send_closedudp_probe(HostOsScanStats *hss,
udp->uh_ulen = htons(8 + datalen);
/* OK, now we should be able to compute a valid checksum */
realcheck = magic_tcpudp_cksum(source, hss->target->v4hostip(), IPPROTO_UDP,
realcheck = tcpudp_cksum(source, hss->target->v4hostip(), IPPROTO_UDP,
sizeof(struct udp_hdr) + datalen, (char *) udp);
#if STUPID_SOLARIS_CHECKSUM_BUG
udp->uh_sum = sizeof(struct udp_hdr) + datalen;
@@ -3207,7 +3207,8 @@ static void begin_sniffer(HostOsScan *HOS, vector<Target *> &Targets) {
}
filterlen = 0;
HOS->pd = my_pcap_open_live(Targets[0]->deviceName(), 8192, (o.spoofsource)? 1 : 0, pcap_selectable_fd_valid()? 200 : 2);
if((HOS->pd=my_pcap_open_live(Targets[0]->deviceName(), 8192, (o.spoofsource)? 1 : 0, pcap_selectable_fd_valid()? 200 : 2))==NULL)
fatal("%s", PCAP_OPEN_ERRMSG);
if (doIndividual)
len = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s and (icmp or (tcp and (%s",
@@ -3219,9 +3220,9 @@ static void begin_sniffer(HostOsScan *HOS, vector<Target *> &Targets) {
fatal("ran out of space in pcap filter");
filterlen = len;
if (o.debugging > 2) log_write(LOG_PLAIN, "Pcap filter: %s\n", pcap_filter);
if (o.debugging) log_write(LOG_PLAIN, "Packet capture filter (device %s): %s\n", Targets[0]->deviceFullName(), pcap_filter);
set_pcap_filter(Targets[0]->deviceFullName(), HOS->pd, pcap_filter);
return;
}

View File

@@ -105,6 +105,8 @@
#include "Target.h"
#include "utils.h"
#include "xml.h"
#include "nbase.h"
#include "libnetutil/netutil.h"
#include <math.h>
@@ -251,9 +253,6 @@ void win32_warn_raw_sockets(const char *devname) {
}
}
/* From tcpip.cc. */
bool DnetName2PcapName(const char *dnetdev, char *pcapdev, int pcapdevlen);
/* Display the mapping from libdnet interface names (like "eth0") to WinPcap
interface names (like "\Device\NPF_{...}"). This is the same mapping used by
eth_open and so can help diagnose connection problems. Additionally display
@@ -325,11 +324,17 @@ int print_iflist(void) {
struct interface_info *iflist;
struct sys_route *routes;
NmapOutputTable *Tbl = NULL;
iflist = getinterfaces(&numifs);
char errstr[256];
errstr[0]='\0';
iflist = getinterfaces(&numifs, errstr, sizeof(errstr));
int i;
/* First let's handle interfaces ... */
if (numifs == 0) {
if (iflist==NULL || numifs<=0) {
log_write(LOG_PLAIN, "INTERFACES: NONE FOUND(!)\n");
if (o.debugging)
log_write(LOG_STDOUT, "Reason: %s\n", errstr);
} else {
int devcol = 0, shortdevcol = 1, ipcol = 2, typecol = 3, upcol = 4, maccol = 5;
Tbl = new NmapOutputTable(numifs + 1, 6);
@@ -374,12 +379,15 @@ int print_iflist(void) {
#endif
/* OK -- time to handle routes */
routes = getsysroutes(&numroutes);
errstr[0]='\0';
routes = getsysroutes(&numroutes, errstr, sizeof(errstr));
u32 mask_nbo;
u16 nbits;
struct in_addr ia;
if (numroutes == 0) {
if (routes==NULL || numroutes<= 0) {
log_write(LOG_PLAIN, "ROUTES: NONE FOUND(!)\n");
if (o.debugging)
log_write(LOG_STDOUT, "Reason: %s\n", errstr);
} else {
int dstcol = 0, devcol = 1, gwcol = 2;
Tbl = new NmapOutputTable(numroutes + 1, 3);
@@ -1950,13 +1958,13 @@ static void printtraceroute_normal(Target * currenths) {
probe = currenths->traceroute_probespec;
if (probe.type == PS_TCP) {
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
probe.pd.tcp.dport, proto2ascii(probe.proto));
probe.pd.tcp.dport, proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_UDP) {
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
probe.pd.udp.dport, proto2ascii(probe.proto));
probe.pd.udp.dport, proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_SCTP) {
log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n",
probe.pd.sctp.dport, proto2ascii(probe.proto));
probe.pd.sctp.dport, proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_ICMP || probe.type == PS_PROTO) {
struct protoent *proto = nmap_getprotbynum(htons(probe.proto));
log_write(LOG_PLAIN, "TRACEROUTE (using proto %d/%s)\n",
@@ -2055,13 +2063,13 @@ static void printtraceroute_xml(Target * currenths) {
probe = currenths->traceroute_probespec;
if (probe.type == PS_TCP) {
xml_attribute("port", "%d", probe.pd.tcp.dport);
xml_attribute("proto", "%s", proto2ascii(probe.proto));
xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_UDP) {
xml_attribute("port", "%d", probe.pd.udp.dport);
xml_attribute("proto", "%s", proto2ascii(probe.proto));
xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_SCTP) {
xml_attribute("port", "%d", probe.pd.sctp.dport);
xml_attribute("proto", "%s", proto2ascii(probe.proto));
xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto));
} else if (probe.type == PS_ICMP || probe.type == PS_PROTO) {
struct protoent *proto = nmap_getprotbynum(htons(probe.proto));
if (proto == NULL)

View File

@@ -112,6 +112,23 @@
#define LOG_NAMES {"normal", "machine", "$Cr!pT |<!dd!3", "XML"}
#define PCAP_OPEN_ERRMSG "Call to pcap_open_live() failed three times. "\
"There are several possible reasons for this, depending on your operating "\
"system:\nLINUX: If you are getting Socket type not supported, try "\
"modprobe af_packet or recompile your kernel with SOCK_PACKET enabled.\n "\
"*BSD: If you are getting device not configured, you need to recompile "\
"your kernel with Berkeley Packet Filter support. If you are getting "\
"No such file or directory, try creating the device (eg cd /dev; "\
"MAKEDEV <device>; or use mknod).\n*WINDOWS: Nmap only supports "\
"ethernet interfaces on Windows for most operations because Microsoft "\
"disabled raw sockets as of Windows XP SP2. Depending on the reason for "\
"this error, it is possible that the --unprivileged command-line argument "\
"will help.\nSOLARIS: If you are trying to scan localhost or the "\
"address of an interface and are getting '/dev/lo0: No such file or "\
"directory' or 'lo0: No DLPI device found', complain to Sun. I don't "\
"think Solaris can support advanced localhost scans. You can probably "\
"use \"-Pn -sT localhost\" though.\n\n"
#include "portlist.h"
#include "nmap.h"
#include "global_structures.h"

View File

@@ -98,6 +98,7 @@
#include "protocols.h"
#include "nmap_rpc.h"
#include "tcpip.h"
#include "libnetutil/netutil.h"
using namespace std;
@@ -503,7 +504,7 @@ void PortList::setPortState(u16 portno, u8 protocol, int state) {
if ((state == PORT_OPEN && o.verbose) || (o.debugging > 1)) {
log_write(LOG_STDOUT, "Discovered %s port %hu/%s%s\n",
statenum2str(state), portno,
proto2ascii(protocol), idstr? idstr : "");
proto2ascii_lowercase(protocol), idstr? idstr : "");
log_flush(LOG_STDOUT);
}
@@ -521,7 +522,7 @@ void PortList::setPortState(u16 portno, u8 protocol, int state) {
/* We must discount our statistics from the old values. Also warn
if a complete duplicate */
if (o.debugging && oldport->state == state) {
error("Duplicate port (%hu/%s)", portno, proto2ascii(protocol));
error("Duplicate port (%hu/%s)", portno, proto2ascii_lowercase(protocol));
}
state_counts_proto[proto][oldport->state]--;
} else {
@@ -716,7 +717,7 @@ int PortList::forgetPort(u16 portno, u8 protocol) {
if (o.verbose) {
log_write(LOG_STDOUT, "Deleting port %hu/%s, which we thought was %s\n",
portno, proto2ascii(answer->proto),
portno, proto2ascii_lowercase(answer->proto),
statenum2str(answer->state));
log_flush(LOG_STDOUT);
}

View File

@@ -3933,7 +3933,7 @@ static bool get_arp_result(UltraScanInfo *USI, struct timeval *stime) {
do {
to_usec = TIMEVAL_SUBTRACT(*stime, USI->now);
if (to_usec < 2000) to_usec = 2000;
rc = read_arp_reply_pcap(USI->pd, rcvdmac, &rcvdIP, to_usec, &rcvdtime);
rc = read_arp_reply_pcap(USI->pd, rcvdmac, &rcvdIP, to_usec, &rcvdtime, PacketTrace::traceArp);
gettimeofday(&USI->now, NULL);
if (rc == -1) fatal("Received -1 response from readarp_reply_pcap");
if (rc == 0) {
@@ -4884,7 +4884,9 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
}
}
USI->pd = my_pcap_open_live(Targets[0]->deviceName(), 100, (o.spoofsource)? 1 : 0, pcap_selectable_fd_valid()? 200 : 2);
if((USI->pd=my_pcap_open_live(Targets[0]->deviceName(), 100, (o.spoofsource)? 1 : 0, pcap_selectable_fd_valid()? 200 : 2))==NULL)
fatal("%s", PCAP_OPEN_ERRMSG);
if (USI->ping_scan_arp){
/* Some OSs including Windows 7 and Solaris 10 have been seen to send their
ARP replies to the broadcast address, not to the (unicast) address that
@@ -4931,7 +4933,7 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
pcap_filter+=" and (icmp or tcp or udp or sctp)";
}
}else assert(0);
if (o.debugging > 2) log_write(LOG_PLAIN, "Pcap filter: %s\n", pcap_filter.c_str());
if (o.debugging) log_write(LOG_PLAIN, "Packet capture filter (device %s): %s\n", Targets[0]->deviceFullName(), pcap_filter.c_str());
set_pcap_filter(Targets[0]->deviceFullName(), USI->pd, pcap_filter.c_str());
/* pcap_setnonblock(USI->pd, 1, NULL); */
return;

View File

@@ -1420,7 +1420,7 @@ void ServiceNFO::addToServiceFingerprint(const char *probeName, const u8 *resp,
if (servicefplen == 0) {
timep = time(NULL);
ltime = localtime(&timep);
servicefplen = Snprintf(servicefp, spaceleft, "SF-Port%hu-%s:V=%s%s%%I=%d%%D=%d/%d%%Time=%X%%P=%s", portno, proto2ascii(proto, true), NMAP_VERSION, (tunnel == SERVICE_TUNNEL_SSL)? "%T=SSL" : "", o.version_intensity, ltime->tm_mon + 1, ltime->tm_mday, (int) timep, NMAP_PLATFORM);
servicefplen = Snprintf(servicefp, spaceleft, "SF-Port%hu-%s:V=%s%s%%I=%d%%D=%d/%d%%Time=%X%%P=%s", portno, proto2ascii_uppercase(proto), NMAP_VERSION, (tunnel == SERVICE_TUNNEL_SSL)? "%T=SSL" : "", o.version_intensity, ltime->tm_mon + 1, ltime->tm_mday, (int) timep, NMAP_PLATFORM);
}
// Note that we give the total length of the response, even though we
@@ -1711,7 +1711,7 @@ static void adjustPortStateIfNecessary(ServiceNFO *svc) {
svc->target->NameIP(host, sizeof(host));
log_write(LOG_STDOUT, "Discovered %s port %hu/%s on %s is actually open\n",
statenum2str(oldstate), svc->portno, proto2ascii(svc->proto), host);
statenum2str(oldstate), svc->portno, proto2ascii_lowercase(svc->proto), host);
log_flush(LOG_STDOUT);
}
}
@@ -1728,7 +1728,7 @@ static void adjustPortStateIfNecessary(ServiceNFO *svc) {
// Report data as probes are sent if --version-trace has been requested
if (o.debugging > 1 || o.versionTrace()) {
log_write(LOG_PLAIN, "Service scan sending probe %s to %s:%hu (%s)\n", probe->getName(), svc->target->targetipstr(), svc->portno, proto2ascii(svc->proto));
log_write(LOG_PLAIN, "Service scan sending probe %s to %s:%hu (%s)\n", probe->getName(), svc->target->targetipstr(), svc->portno, proto2ascii_lowercase(svc->proto));
}
assert(probe);
@@ -1984,7 +1984,7 @@ static int launchSomeServiceProbes(nsock_pool nsp, ServiceGroup *SG) {
fatal("Failed to allocate Nsock I/O descriptor in %s()", __func__);
}
if (o.debugging > 1) {
log_write(LOG_PLAIN, "Starting probes against new service: %s:%hu (%s)\n", svc->target->targetipstr(), svc->portno, proto2ascii(svc->proto));
log_write(LOG_PLAIN, "Starting probes against new service: %s:%hu (%s)\n", svc->target->targetipstr(), svc->portno, proto2ascii_lowercase(svc->proto));
}
if (o.spoofsource) {
o.SourceSockAddr(&ss, &ss_len);

View File

@@ -285,46 +285,6 @@ TargetGroup* load_exclude_string(const char *s) {
return specs_to_targetgroups(specs);
}
static inline bool is_host_separator(int c) {
return c == ' ' || c == '\r' || c == '\n' || c == '\t' || c == '\0';
}
/* Read a single host specification from a file, as for -iL and --excludefile.
It returns the length of the string read; an overflow is indicated when the
return value is >= n. Returns 0 if there was no specification to be read. The
buffer is always null-terminated. */
size_t read_host_from_file(FILE *fp, char *buf, size_t n)
{
int ch;
size_t i;
i = 0;
ch = getc(fp);
while (is_host_separator(ch) || ch == '#') {
if (ch == '#') {
/* Skip comments to the end of the line. */
while ((ch = getc(fp)) != EOF && ch != '\n')
;
} else {
ch = getc(fp);
}
}
while (ch != EOF && !(is_host_separator(ch) || ch == '#')) {
if (i < n)
buf[i] = ch;
i++;
ch = getc(fp);
}
if (ch != EOF)
ungetc(ch, fp);
if (i < n)
buf[i] = '\0';
else if (n > 0)
/* Null-terminate even though it was too long. */
buf[n - 1] = '\0';
return i;
}
/* A debug routine to dump some information to stdout. Invoked if debugging is
set to 3 or higher. I had to make significant changes from wam's code.
@@ -505,7 +465,7 @@ Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
#endif // WIN32
)) {
t->TargetSockAddr(&ss, &sslen);
if (!route_dst(&ss, &rnfo)) {
if (!nmap_route_dst(&ss, &rnfo)) {
fatal("%s: failed to determine route to %s", __func__, t->NameIP());
}
if (rnfo.direct_connect) {

View File

@@ -161,8 +161,6 @@ Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
struct scan_lists *ports, int pingtype);
TargetGroup* load_exclude_file(FILE *fp);
TargetGroup* load_exclude_string(const char *s);
/* Read a single host specification from a file, as for -iL and --excludefile. */
size_t read_host_from_file(FILE *fp, char *buf, size_t n);
/* a debugging routine to dump an exclude list to stdout. */
int dumpExclude(TargetGroup*exclude_group);
/* Returns the last host obtained by nexthost. It will be given again the next

2209
tcpip.cc

File diff suppressed because it is too large Load Diff

137
tcpip.h
View File

@@ -212,7 +212,7 @@ extern "C" {
#include <netinet/ip_icmp.h>
#endif
typedef enum { devt_ethernet, devt_loopback, devt_p2p, devt_other } devtype;
#include "nmap.h"
#include "global_structures.h"
@@ -224,11 +224,12 @@ typedef enum { devt_ethernet, devt_loopback, devt_p2p, devt_other } devtype;
/* Used for tracing all packets sent or received (eg the
--packet-trace option) */
class PacketTrace {
public:
/* static const int SEND=1;
static const int RCV=2; */
enum pdirection { SENT=1, RCVD=2 };
static const int SENT=1; /* These two values must not be changed */
static const int RCVD=2;
typedef int pdirection;
/* Takes an IP PACKET and prints it if packet tracing is enabled.
'packet' must point to the IPv4 header. The direction must be
PacketTrace::SENT or PacketTrace::RCVD . Optional 'now' argument
@@ -265,54 +266,6 @@ class PacketCounter {
sendPackets, sendBytes, recvPackets, recvBytes;
};
#define MAX_LINK_HEADERSZ 24
struct link_header {
int datalinktype; /* pcap_datalink(), such as DLT_EN10MB */
int headerlen; /* 0 if header was too big or unavailaable */
u8 header[MAX_LINK_HEADERSZ];
};
/* Relevant (to Nmap) information about an interface */
struct interface_info {
char devname[16];
char devfullname[16]; /* can include alias info, such as eth0:2. */
struct sockaddr_storage addr;
u16 netmask_bits; /* CIDR-style. So 24 means class C (255.255.255.0)*/
devtype device_type; /* devt_ethernet, devt_loopback, devt_p2p, devt_other */
bool device_up; /* True if the device is up (enabled) */
u8 mac[6]; /* Interface MAC address if device_type is devt_ethernet */
};
struct route_nfo {
struct interface_info ii;
/* true if the target is directly connected on the network (no routing
required). */
bool direct_connect;
/* This is the source address that should be used by the packets. It
may be different than ii.addr if you are using localhost interface
to scan the IP of another interface on the machine */
struct sockaddr_storage srcaddr;
/* If direct_connect is 0, this is filled in with the next hop
required to route to the target */
struct sockaddr_storage nexthop;
};
struct sys_route {
struct interface_info *device;
u32 dest;
u32 netmask;
struct in_addr gw; /* gateway - 0 if none */
};
struct eth_nfo {
char srcmac[6];
char dstmac[6];
eth_t *ethsd; // Optional, but improves performance. Set to NULL if unavail
char devname[16]; // Only needed if ethsd is NULL.
};
#ifndef HAVE_STRUCT_IP
#define HAVE_STRUCT_IP
@@ -435,23 +388,12 @@ struct icmp
not thread-safe and can only be used once in calls like printf()
*/
const char *inet_socktop(struct sockaddr_storage *ss);
/* Tries to resolve the given name (or literal IP) into a sockaddr
structure. This function calls getaddrinfo and returns the same
addrinfo linked list that getaddrinfo produces. Returns NULL for any
error or failure to resolve. */
struct addrinfo *resolve_all(char *hostname, int pf);
/* Tries to resolve the given name (or literal IP) into a sockaddr
structure. The af should be PF_INET (for IPv4) or PF_INET6. Returns 0
if hostname cannot be resolved. It is OK to pass in a sockaddr_in or
sockaddr_in6 casted to a sockaddr_storage as long as you use the matching
pf.*/
int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen,
int pf);
/* LEGACY resolve() function that only supports IPv4 -- see IPv6 version
above. Tries to resolve given hostname and stores
result in ip . returns 0 if hostname cannot
be resolved */
int resolve(char *hostname, struct in_addr *ip);
/* Takes a destination address (dst) and tries to determine the
source address and interface necessary to route to this address.
@@ -459,7 +401,7 @@ int resolve(char *hostname, struct in_addr *ip);
a route is found, true is returned and rnfo is filled in with all
of the routing details. This function takes into account -S and -e
options set by user (o.spoofsource, o.device) */
bool route_dst(const struct sockaddr_storage *const dst, struct route_nfo *rnfo);
int nmap_route_dst(const struct sockaddr_storage * const dst, struct route_nfo *rnfo);
/* Determines what interface packets destined to 'dest' should be
routed through. It can also discover the appropriate next hop (if
@@ -475,9 +417,6 @@ bool routethrough(const struct sockaddr_storage * const dest,
unsigned short in_cksum(u16 *ptr,int nbytes);
unsigned short magic_tcpudp_cksum(const struct in_addr *src,
const struct in_addr *dst,
u8 proto, u16 len, const void *hstart);
/* Build and send a raw tcp packet. If TTL is -1, a partially random
(but likely large enough) one is chosen */
@@ -606,22 +545,6 @@ int send_udp_raw_decoys( int sd, struct eth_nfo *eth,
char *data, u16 datalen);
/* Calls pcap_open_live and spits out an error (and quits) if the call fails.
So a valid pcap_t will always be returned. */
pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc,
int to_ms);
// Returns whether the system supports pcap_get_selectable_fd() properly
bool pcap_selectable_fd_valid();
/* Call this instead of pcap_get_selectable_fd directly (or your code
won't compile on Windows). On systems which don't seem to support
the pcap_get_selectable_fd() function properly, returns -1,
otherwise simply calls pcap_selectable_fd and returns the
results. If you just want to test whether the function is supported,
use pcap_selectable_fd_valid() instead. */
int my_pcap_get_selectable_fd(pcap_t *p);
// Returns whether the packet receive time value obtaned from libpcap
// (and thus by readip_pcap()) should be considered valid. When
// invalid (Windows and Amiga), readip_pcap returns the time you called it.
@@ -631,51 +554,20 @@ bool pcap_recv_timeval_valid();
packets). */
void pcap_print_stats(int logt, pcap_t *pd);
/* A simple function that caches the eth_t from dnet for one device,
to avoid opening, closing, and re-opening it thousands of tims. If
you give a different device, this function will close the first
one. Thus this should never be used by programs that need to deal
with multiple devices at once. In addition, you MUST NEVER
eth_close() A DEVICE OBTAINED FROM THIS FUNCTION. Instead, you can
call eth_close_cached() to close whichever device (if any) is
cached. Returns NULL if it fails to open the device. */
eth_t *eth_open_cached(const char *device);
/* See the description for eth_open_cached */
void eth_close_cached();
/* A simple function I wrote to help in debugging, shows the important fields
of a TCP packet*/
int readtcppacket(const u8 *packet, int readdata);
int readudppacket(const u8 *packet, int readdata);
/* Convert an IP address to the device (IE ppp0 eth0) using that address. Dev passed in must be at least
32 bytes long */
int ipaddr2devname( char *dev, const struct in_addr *addr );
/* And vice versa */
int devname2ipaddr(char *dev, struct in_addr *addr);
/* Looks for an interface assigned to the given IP (ss), and returns
the interface_info for the first one found. If non found, returns NULL */
struct interface_info *getInterfaceByIP(struct sockaddr_storage *ss);
/* Looks for an interface with the given name (iname), and returns the
corresponding interface_info if found. Will accept a match of
devname or devfullname. Returns NULL if none found */
struct interface_info *getInterfaceByName(char *iname);
/* Where the above 4 functions get their info */
struct interface_info *getinterfaces(int *howmany);
pcap_if_t *getpcapinterfaces();
/* Parse the system routing table, converting each route into a
sys_route entry. Returns an array of sys_routes. numroutes is set
to the number of routes in the array. The routing table is only
read the first time this is called -- later results are cached.
The returned route array is sorted by netmask with the most
specific matches first. */
struct sys_route *getsysroutes(int *howmany);
void sethdrinclude(int sd);
void set_ipoptions(int sd, void *opts, size_t optslen);
void set_ttl(int sd, int ttl);
/* Fill buf (up to buflen -- truncate if necessary but always
terminate) with a short representation of the packet stats.
@@ -711,15 +603,8 @@ bool setTargetNextHopMAC(Target *target);
bool getNextHopMAC(char *iface, u8 *srcmac, struct sockaddr_storage *srcss,
struct sockaddr_storage *dstss, u8 *dstmac);
int islocalhost(const struct in_addr * const addr);
int isipprivate(const struct in_addr * const addr);
// Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or
// IPPROTO_IP and returns a ascii representation (or "unknown" if it
// doesn't recognize the number). If uppercase is true, the returned
// value will be in all uppercase letters. You can skip this
// parameter to use lowercase.
const char *proto2ascii(u8 proto, bool uppercase=false);
/* Hex dump */
int get_link_offset(char *device);
/* If rcvdtime is non-null and a packet is returned, rcvd will be

View File

@@ -781,14 +781,16 @@ TracerouteState::TracerouteState(std::vector<Target *> &targets) {
}
/* Assume that all the targets share the same device. */
pd = my_pcap_open_live(targets[0]->deviceName(), 128, o.spoofsource, 2);
if((pd=my_pcap_open_live(targets[0]->deviceName(), 128, o.spoofsource, 2))==NULL)
fatal("%s", PCAP_OPEN_ERRMSG);
sslen = sizeof(srcaddr);
targets[0]->SourceSockAddr(&srcaddr, &sslen);
n = Snprintf(pcap_filter, sizeof(pcap_filter), "dst host %s",
ss_to_string(&srcaddr));
assert(n < (int) sizeof(pcap_filter));
set_pcap_filter(targets[0]->deviceFullName(), pd, pcap_filter);
if (o.debugging)
log_write(LOG_STDOUT, "Packet capture filter (device %s): %s\n", targets[0]->deviceFullName(), pcap_filter);
for (it = targets.begin(); it != targets.end(); it++) {
HostState *state = new HostState(*it);
hosts.push_back(state);

352
utils.cc
View File

@@ -171,24 +171,6 @@ char *chomp(char *string) {
return string;
}
/* Compare a canonical option name (e.g. "max-scan-delay") with a
user-generated option such as "max_scan_delay" and returns 0 if the
two values are considered equivalant (for example, - and _ are
considered to be the same), nonzero otherwise. */
int optcmp(const char *a, const char *b) {
while(*a && *b) {
if (*a == '_' || *a == '-') {
if (*b != '_' && *b != '-')
return 1;
}
else if (*a != *b)
return 1;
a++; b++;
}
if (*a || *b)
return 1;
return 0;
}
/* Scramble the contents of an array*/
void genfry(unsigned char *arr, int elem_sz, int num_elem) {
@@ -447,143 +429,6 @@ char *cstring_unescape(char *str, unsigned int *newlen) {
return str;
}
/* This function converts zero-terminated 'txt' string to binary 'data'.
It is used to parse user input for ip options. Some examples of possible input
strings and results:
'\x01*2\xA2' -> [0x01,0x01,0xA2] // with 'x' number is parsed in hex
'\01\01\255' -> [0x01,0x01,0xFF] // without 'x' its in decimal
'\x01\x00*2' -> [0x01,0x00,0x00] // '*' is copying char
'R' -> Record Route with 9 slots
'S 192.168.0.1 172.16.0.1' -> Strict Route with 2 slots
'L 192.168.0.1 172.16.0.1' -> Loose Route with 2 slots
'T' -> Record Timestamp with 9 slots
'U' -> Record Timestamp and Ip Address with 4 slots
*/
int parse_ip_options(char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff){
enum{
NONE = 0,
SLASH = 1,
MUL = 2,
RR = 3,
TIME = 4,
} s = NONE;
char *n, lc;
char *c = txt;
u8 *d = data;
int i,j;
int base = 10;
u8 *dataend = &data[datalen];
u8 *len = NULL;
char buf[32];
memset(data, 0, datalen);
bool sourcerouting = false;
for(;*c;c++){
switch(s){
case SLASH:
// parse \x00 string
if(*c == 'x'){// just ignore this char
base = 16;
break;
}
if(isxdigit((int) (unsigned char) *c)){
*d++ = strtol(c, &n, base);
c=n-1;
}else
fatal("not a digit after '\\'");
s = NONE;
break;
case MUL:
if(d==data)
fatal("nothing before '*' char");
i = strtol(c, &n, 10);
if(i<2)
fatal("bad number after '*'");
c = n-1; // move current txt pointer
lc = *(d-1); // last char, we'll copy this
for(j=1; j<i; j++){
*d++ = lc;
if(d == dataend) // check for overflow
goto after;
}
s = NONE;
break;
case RR:
if(*c==' ' || *c==',')
break;
n = buf;
while((*c=='.' || (*c>='0' && *c<='9')) && n-buf <= ((int)sizeof(buf)-1))
*n++ = *c++;
*n = '\0'; c--;
if(d+4>=dataend)
fatal("Buffer too small. Or input data too big :)");
i = inet_pton(AF_INET, buf, d);
if(i<1)
fatal("Not a valid ipv4 address '%s'",buf);
// remember offset of first hop
if(sourcerouting && !*firsthopoff)
*firsthopoff = d - data;
d+=4;
if(*len<37)
*len += 4;
break;
case TIME:
fatal("No more arguments allowed!");
default:
switch(*c){
case '\\':s = SLASH;base=10;break;
case '*':s = MUL;break;
case 'R':
case 'S':
case 'L':
if(d != data)
fatal("This option can't be used in that way");
*d++ = '\x01';//NOP
switch(*c){
case 'R':*d++ = 7;break;
case 'S':*d++ = 137; sourcerouting=true; break;
case 'L':*d++ = 131; sourcerouting=true; break;
}
len = d;
*d++ = (*c=='R')? 39 : 3; // length: 3+4*9 bytes
*d++ = 4; //pointer
s = RR;
break;
case 'T':
case 'U':
if(d != data)
fatal("This option can't be used in that way");
*d++ = 68; // option type
len = d;
*d++ = (*c=='U') ? 36 : 40; // length: 3+4*9 bytes or 4+4*9 bytes
*d++ = 5; // pointer
*d++ = (*c=='U') ? 1 : 0; // flag: address and Time fields
s = TIME;
break;
default://*d++ = *c;
fatal("Bad character in ip option '%c'",*c);
}
}
if(d == dataend)
break;
assert(d<dataend);
}
if(sourcerouting){
if(*len<37){
*len+=4;
*lasthopoff = d - data;
*d++ = 0;*d++ = 0;*d++ = 0;*d++ = 0;
}else
fatal("When using source routing you must leave at least one slot for target's ip.");
}
if(s == RR)
return(*len+1); // because we inject NOP before
if(s == TIME)
return(*len);
after:
return(d - data);
}
void bintohexstr(char *buf, int buflen, char *src, int srclen){
int bp=0;
@@ -604,203 +449,6 @@ void bintohexstr(char *buf, int buflen, char *src, int srclen){
bp += Snprintf(buf+bp, buflen-bp,"\n");
}
static inline char* STRAPP(const char *fmt, ...) {
static char buf[256];
static int bp;
int left = (int)sizeof(buf)-bp;
if(!fmt){
bp = 0;
return(buf);
}
if (left <= 0)
return buf;
va_list ap;
va_start(ap, fmt);
bp += Vsnprintf (buf+bp, left, fmt, ap);
va_end(ap);
return(buf);
}
#define HEXDUMP -2
#define UNKNOWN -1
#define BREAK() \
{option_type = HEXDUMP; break;}
#define CHECK(tt) \
if(tt >= option_end) \
{option_type = HEXDUMP; break;}
/* It tries to decode ip options.
Returns static buffer. watch out. */
char* print_ip_options(u8* ipopt, int ipoptlen) {
char ipstring[32];
int option_type = UNKNOWN;// option type
int option_len = 0; // option length
int option_pt = 0; // option pointer
int option_fl = 0; // option flag
u8 *tptr; // temp pointer
u32 *tint; // temp int
int option_sta = 0; // option start offset
int option_end = 0; // option end offset
int pt = 0; // current offset
// clear buffer
STRAPP(NULL,NULL);
if(!ipoptlen)
return(NULL);
while(pt<ipoptlen){ // for every char in ipopt
// read ip option header
if(option_type == UNKNOWN) {
option_sta = pt;
option_type = ipopt[pt++];
if(option_type != 0 && option_type != 1) { // should we be interested in length field?
if(pt >= ipoptlen) // no more chars
{option_type = HEXDUMP;pt--; option_end = 255; continue;} // no length field, hex dump to the end
option_len = ipopt[pt++];
// end must not be greater than length
option_end = MIN(option_sta + option_len, ipoptlen);
// end must not be smaller than current position
option_end = MAX(option_end, option_sta+2);
}
}
switch(option_type) {
case 0: // IPOPT_END
STRAPP(" EOL", NULL);
option_type = UNKNOWN;
break;
case 1: // IPOPT_NOP
STRAPP(" NOP", NULL);
option_type = UNKNOWN;
break;
/* case 130: // IPOPT_SECURITY
option_type=-1;
break;*/
case 131: // IPOPT_LSRR -> Loose Source and Record Route
case 137: // IPOPT_SSRR -> Strict Source and Record Route
case 7: // IPOPT_RR -> Record Route
if(pt - option_sta == 2) {
STRAPP(" %s%s{", (option_type==131)?"LS":(option_type==137)?"SS":"", "RR");
// option pointer
CHECK(pt);
option_pt = ipopt[pt++];
if(option_pt%4 != 0 || (option_sta + option_pt-1)>option_end || option_pt<4) //bad or too big pointer
STRAPP(" [bad ptr=%02i]", option_pt);
}
if(pt - option_sta > 2) { // ip's
int i, s = (option_pt)%4;
// if pointer is mangled, fix it. it's max 3 bytes wrong
CHECK(pt+3);
for(i=0; i<s; i++)
STRAPP("\\x%02x", ipopt[pt++]);
option_pt -= i;
// okay, now we can start printing ip's
CHECK(pt+3);
tptr = &ipopt[pt]; pt+=4;
if(inet_ntop(AF_INET, (char *) tptr, ipstring, sizeof(ipstring)) == NULL)
fatal("Failed to convert target address to presentation format!?! Error: %s", strerror(socket_errno()));
STRAPP("%c%s",(pt-3-option_sta)==option_pt?'#':' ', ipstring);
if(pt == option_end)
STRAPP("%s",(pt-option_sta)==(option_pt-1)?"#":""); // pointer in the end?
}else BREAK();
break;
case 68: // IPOPT_TS -> Internet Timestamp
if(pt - option_sta == 2){
STRAPP(" TM{");
// pointer
CHECK(pt);
option_pt = ipopt[pt++];
// bad or too big pointer
if(option_pt%4 != 1 || (option_sta + option_pt-1)>option_end || option_pt<5)
STRAPP(" [bad ptr=%02i]", option_pt);
// flags + overflow
CHECK(pt);
option_fl = ipopt[pt++];
if((option_fl&0x0C) || (option_fl&0x03)==2)
STRAPP(" [bad flags=\\x%01hhx]", option_fl&0x0F);
STRAPP("[%i hosts not recorded]", option_fl>>4);
option_fl &= 0x03;
}
if(pt - option_sta > 2) {// ip's
int i, s = (option_pt+3)%(option_fl==0?4:8);
// if pointer is mangled, fix it. it's max 3 bytes wrong
CHECK(pt+(option_fl==0?3:7));
for(i=0; i<s; i++)
STRAPP("\\x%02x", ipopt[pt++]);
option_pt-=i;
// print pt
STRAPP("%c",(pt+1-option_sta)==option_pt?'#':' ');
// okay, first grab ip.
if(option_fl!=0){
CHECK(pt+3);
tptr = &ipopt[pt]; pt+=4;
if(inet_ntop(AF_INET, (char *) tptr, ipstring, sizeof(ipstring)) == NULL)
fatal("Failed to convert target address to presentation format!?! Error: %s", strerror(socket_errno()));
STRAPP("%s@", ipstring);
}
CHECK(pt+3);
tint = (u32*)&ipopt[pt]; pt+=4;
STRAPP("%u", ntohl(*tint));
if(pt == option_end)
STRAPP("%s",(pt-option_sta)==(option_pt-1)?"#":" ");
}else BREAK();
break;
case 136: // IPOPT_SATID -> (SANET) Stream Identifier
if(pt - option_sta == 2){
u16 *sh;
STRAPP(" SI{",NULL);
// length
if(option_sta+option_len > ipoptlen || option_len!=4)
STRAPP("[bad len %02i]", option_len);
// stream id
CHECK(pt+1);
sh = (u16*) &ipopt[pt]; pt+=2;
option_pt = ntohs(*sh);
STRAPP("id=%i", option_pt);
if(pt != option_end)
BREAK();
}else BREAK();
break;
case UNKNOWN:
default:
// we read option_type and option_len, print them.
STRAPP(" ??{\\x%02hhx\\x%02hhx", option_type, option_len);
// check option_end once more:
if(option_len < ipoptlen)
option_end = MIN(MAX(option_sta+option_len, option_sta+2),ipoptlen);
else
option_end = 255;
option_type = HEXDUMP;
break;
case HEXDUMP:
assert(pt<=option_end);
if(pt == option_end){
STRAPP("}",NULL);
option_type=-1;
break;
}
STRAPP("\\x%02hhx", ipopt[pt++]);
break;
}
if(pt == option_end && option_type != UNKNOWN) {
STRAPP("}",NULL);
option_type = UNKNOWN;
}
} // while
if(option_type != UNKNOWN)
STRAPP("}");
return(STRAPP("",NULL));
}
#undef CHECK
#undef BREAK
#undef UNKNOWN
#undef HEXDUMP
/* mmap() an entire file into the address space. Returns a pointer

21
utils.h
View File

@@ -175,12 +175,6 @@ int wildtest(char *wild, char *test);
void nmap_hexdump(unsigned char *cp, unsigned int length);
/* Compare a canonical option name (e.g. "max-scan-delay") with a
user-generated option such as "max_scan_delay" and returns 0 if the
two values are considered equivalant (for example, - and _ are
considered to be the same), nonzero otherwise. */
int optcmp(const char *canonical, const char *instance);
/* Scramble the contents of an array*/
void genfry(unsigned char *arr, int elem_sz, int num_elem);
void shortfry(unsigned short *arr, int num_elem);
@@ -204,23 +198,8 @@ void arg_parse_free(char **argv);
str is returned. */
char *cstring_unescape(char *str, unsigned int *len);
/* This function converts zero-terminated 'txt' string to binary 'data'.
It is used to parse user input for ip options. Some examples of possible input
strings and results:
'\x01*2\xA2' -> [0x01,0x01,0xA2] // with 'x' number is parsed in hex
'\01\01\255' -> [0x01,0x01,0xFF] // without 'x' its in decimal
'\x01\x00*2' -> [0x01,0x00,0x00] // '*' is copying char
'R' -> Record Route with 9 slots
'S 192.168.0.1 172.16.0.1' -> Strict Route with 2 slots
'L 192.168.0.1 172.16.0.1' -> Loose Route with 2 slots
'T' -> Record Timestamp with 9 slots
'U' -> Record Timestamp and Ip Address with 4 slots
*/
int parse_ip_options(char *txt, u8 *data, int datalen, int* firsthopoff, int* lasthopoff);
void bintohexstr(char *buf, int buflen, char *src, int srclen);
char* print_ip_options(u8* ipopt, int ipoptlen);
#ifndef HAVE_STRERROR
char *strerror(int errnum);