Skip to content

Commit

Permalink
Whew -- big reorganization to allow ethernet sends of IP packets
Browse files Browse the repository at this point in the history
  • Loading branch information
fyodor committed Jul 19, 2005
1 parent 0595d89 commit 555c986
Show file tree
Hide file tree
Showing 29 changed files with 1,958 additions and 1,357 deletions.
24 changes: 15 additions & 9 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,27 @@ o Chagned the interesting ports array from a 65K-member array of
some cases, and should also give a slight runtime performance
boost. This patch was written by Paul Tarjan (ptarjan(a)gmail.com).

o Integrated a bunch of nmap-service-probes fingerprints from Doug
o Integrated a ton of nmap-service-probes fingerprints from Doug
Hoyte (doug(a)hcsw.org)

o The OS fingerprint is now provided in XML output if debugging is
enabled (-d) or verbosity is at least 2 (-v -v). This patch was
sent by Okan Demirmen (okan(a)demirmen.com)
o Integrated many nmap-service-probes changes from Bo Jiang
(jiangbo(a)brandeis.edu)

o Added a stripped-down version of Dug Song's excellent libdnet
networking library (v. 1.10). This allows Nmap to send raw ethernet
frames for the new ARP ping feature.

o The OS fingerprint is now provided in XML output if debugging is
enabled (-d) or verbosity is at least 2 (-v -v). This patch was
sent by Okan Demirmen (okan(a)demirmen.com)

o Fixed the way tcp connect scan (-sT) respons to ICMP network
unreachable responses (patch by Richard Moore
(rich(a)westpoint.ltd.uk).

o Changed routethrough() to use libdnet rather than all of my custom
code.

o Fixed a crash problem related to non-portable varargs (vsnprintf)
usage. Reports of this crash came from Alan William Somers
(somers(a)its.caltech.edu) and Christophe (chris.branch(a)gmx.de).
Expand Down Expand Up @@ -94,6 +100,11 @@ o ultra_scan() now sets pseudo-random ACK values (rather than 0) for
o Added a bunch of RPC numbers from nmap-rpc maintainer Eilon Gishri
(eilon(a)aristo.tau.ac.il)

o Added 'leet ASCII art to the confugrator! ARTIST NOTE: If you think
the ASCII art sucks, feel free to send me alternatives. Note that
only people compiling the UNIX source code get this. (ASCII artist
unknown).

o Added a distcc probes and a bunch of smtp matches from Dirk Mueller
(mueller(a)kde.org) to nmap-service-probes. Also added AFS version
probe and matches from Lionel Cons (lionel.cons(a)cern.ch). And
Expand Down Expand Up @@ -126,11 +137,6 @@ o Changed from CVS to Subversion source control system (which
change users will see is that "Id" tags in file headers use the SVN
format for version numbering and such.

o Added 'leet ASCII art to the confugrator! ARTIST NOTE: If you think
the ASCII art sucks, feel free to send me alternatives. Note that
only people compiling the UNIX source code get this. (ASCII artist
unknown).

Nmap 3.81

o Nmap now ships with and installs (in the same directory as other
Expand Down
2 changes: 1 addition & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export NMAP_VERSION = 3.83
export NMAP_VERSION = 3.83.SOC1
NMAP_NAME= nmap
NMAP_URL= http://www.insecure.org/nmap/
NMAP_PLATFORM=@host@
Expand Down
8 changes: 8 additions & 0 deletions NmapOps.cc
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ void NmapOps::Initialize() {
debugging = DEBUGGING;
verbose = DEBUGGING;
randomize_hosts = 0;
sendpref = PACKET_SEND_NOPREF;
spoofsource = 0;
device[0] = '\0';
interactivemode = 0;
Expand Down Expand Up @@ -328,6 +329,13 @@ void NmapOps::ValidateOptions() {
fatal("Ping scan is not valid with any other scan types (the other ones all include a ping scan");
}

if (sendpref == PACKET_SEND_NOPREF) {
#ifdef WIN32
sendpref = PACKET_SEND_ETH_STRONG;
#else
sendpref = PACKET_SEND_IP_WEAK;
#endif
}
/* We start with stuff users should not do if they are not root */
if (!isr00t) {

Expand Down
23 changes: 23 additions & 0 deletions NmapOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ class NmapOps {
int TimeSinceStartMS(struct timeval *now=NULL);
struct in_addr v4source();
const struct in_addr *v4sourceip();



bool TCPScan(); /* Returns true if at least one chosen scan type is TCP */
bool UDPScan(); /* Returns true if at least one chosen scan type is UDP */

Expand All @@ -138,6 +141,26 @@ class NmapOps {
user). */
int isr00t;
int debugging;

#define PACKET_SEND_NOPREF 1
#define PACKET_SEND_ETH_WEAK 2
#define PACKET_SEND_ETH_STRONG 4
#define PACKET_SEND_ETH 6
#define PACKET_SEND_IP_WEAK 8
#define PACKET_SEND_IP_STRONG 16
#define PACKET_SEND_IP 24

/* How should we send raw IP packets? Nmap can generally use either
ethernet or raw ip sockets. Which is better depends on platform
and goals. A _STRONG preference means that Nmap should use the
preferred method whenever it is possible (obviously it isn't
always possible -- sending ethernet frames won't work over a PPP
connection). This is useful when the other type doesn't work at
all. A _WEAK preference means that Nmap may use the other type
where it is substantially more efficient to do so. For example,
Nmap will still do an ARP ping scan of a local network even when
the pref is SEND_IP_WEAK */
int sendpref;
bool packetTrace() { return (debugging >= 3)? true : pTrace; }
bool versionTrace() { return packetTrace()? true : vTrace; }
// Note that packetTrace may turn on at high debug levels even if
Expand Down
68 changes: 64 additions & 4 deletions Target.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,17 +119,21 @@ void Target::Initialize() {
osscan_performed = 0;
wierd_responses = flags = 0;
memset(&to, 0, sizeof(to));
device[0] = '\0';
memset(&targetsock, 0, sizeof(targetsock));
memset(&sourcesock, 0, sizeof(sourcesock));
targetsocklen = sourcesocklen = 0;
memset(&nexthopsock, 0, sizeof(nexthopsock));
targetsocklen = sourcesocklen = nexthopsocklen = 0;
directly_connected = -1;
targetipstring[0] = '\0';
nameIPBuf = NULL;
memset(&MACaddress, 0, sizeof(MACaddress));
memset(&SrcMACaddress, 0, sizeof(SrcMACaddress));
MACaddress_set = SrcMACaddress_set = false;
memset(&NextHopMACaddress, 0, sizeof(NextHopMACaddress));
MACaddress_set = SrcMACaddress_set = NextHopMACaddress_set = false;
htn.msecs_used = 0;
htn.toclock_running = false;
interface_type = devt_other;
devname[0] = devfullname[0] = '\0';
}

void Target::Recycle() {
Expand Down Expand Up @@ -177,7 +181,8 @@ void Target::GenerateIPString() {
/* Fills a sockaddr_storage with the AF_INET or AF_INET6 address
information of the target. This is a preferred way to get the
address since it is portable for IPv6 hosts. Returns 0 for
success. */
success. ss_len must be provided. It is not examined, but is set
to the size of the sockaddr copied in. */
int Target::TargetSockAddr(struct sockaddr_storage *ss, size_t *ss_len) {
assert(ss);
assert(ss_len);
Expand Down Expand Up @@ -307,6 +312,41 @@ const char *Target::NameIP() {
return NameIP(nameIPBuf, MAXHOSTNAMELEN + INET6_ADDRSTRLEN);
}

/* Returns the next hop for sending packets to this host. Returns true if
next_hop was filled in. It might be false, for example, if
next_hop has never been set */
bool Target::nextHop(struct sockaddr_storage *next_hop, size_t *next_hop_len) {
if (nexthopsocklen <= 0)
return false;
assert(nexthopsocklen <= sizeof(*next_hop));
if (next_hop)
memcpy(next_hop, &nexthopsock, nexthopsocklen);
if (next_hop_len)
*next_hop_len = nexthopsocklen;
return true;
}

/* If the host is directly connected on a network, set and retrieve
that information here. directlyConnected() will abort if it hasn't
been set yet. */
void Target::setDirectlyConnected(bool connected) {
directly_connected = connected? 1 : 0;
}

bool Target::directlyConnected() {
assert(directly_connected == 0 || directly_connected == 1);
return directly_connected;
}

/* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
to sockaddr_storage */
void Target::setNextHop(struct sockaddr_storage *next_hop, size_t next_hop_len) {
assert(next_hop_len > 0 && next_hop_len <= sizeof(nexthopsock));
memcpy(&nexthopsock, next_hop, next_hop_len);
nexthopsocklen = next_hop_len;
}


/* Starts the timeout clock for the host running (e.g. you are
beginning a scan). If you do not have the current time handy,
you can pass in NULL. When done, call stopTimeOutClock (it will
Expand Down Expand Up @@ -360,6 +400,22 @@ int Target::setSrcMACAddress(const u8 *addy) {
return 0;
}

int Target::setNextHopMACAddress(const u8 *addy) {
if (!addy) return 1;
memcpy(NextHopMACaddress, addy, 6);
NextHopMACaddress_set = 1;
return 0;
}

/* Set the device names so that they can be returned by deviceName()
and deviceFullName(). The normal name may not include alias
qualifier, while the full name may include it (e.g. "eth1:1"). If
these are non-null, they will overwrite the stored version */
void Target::setDeviceNames(const char *name, const char *fullname) {
if (name) Strncpy(devname, name, sizeof(devname));
if (fullname) Strncpy(devfullname, fullname, sizeof(devfullname));
}

/* Returns the 6-byte long MAC address, or NULL if none has been set */
const u8 *Target::MACAddress() {
return (MACaddress_set)? MACaddress : NULL;
Expand All @@ -368,3 +424,7 @@ const u8 *Target::MACAddress() {
const u8 *Target::SrcMACAddress() {
return (SrcMACaddress_set)? SrcMACaddress : NULL;
}

const u8 *Target::NextHopMACAddress() {
return (NextHopMACaddress_set)? NextHopMACaddress : NULL;
}
52 changes: 43 additions & 9 deletions Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ class Target {
/* Fills a sockaddr_storage with the AF_INET or AF_INET6 address
information of the target. This is a preferred way to get the
address since it is portable for IPv6 hosts. Returns 0 for
success. */
success. ss_len must be provided. It is not examined, but is set
to the size of the sockaddr copied in. */
int TargetSockAddr(struct sockaddr_storage *ss, size_t *ss_len);
/* Note that it is OK to pass in a sockaddr_in or sockaddr_in6 casted
to sockaddr_storage */
Expand Down Expand Up @@ -159,6 +160,27 @@ class Target {
/* This next version returns a STATIC buffer -- so no concurrency */
const char *NameIP();

/* If the host is directly connected on a network, set and retrieve
that information here. directlyConnected() will abort if it hasn't
been set yet. */
void setDirectlyConnected(bool connected);
bool directlyConnected();

/* If the host is NOT directly connected, you can set the next hop
value here. It is OK to pass in a sockaddr_in or sockaddr_in6
casted to sockaddr_storage*/
void setNextHop(struct sockaddr_storage *next_hop, size_t next_hop_len);
/* Returns the next hop for sending packets to this host. Returns true if
next_hop was filled in. It might be false, for example, if
next_hop has never been set */
bool nextHop(struct sockaddr_storage *next_hop, size_t *next_hop_len);

/* Sets the interface type to one of:
devt_ethernet, devt_loopback, devt_p2p, devt_other
*/
void setIfType(devtype iftype) { interface_type = iftype; }
/* Returns -1 if it has not yet been set with setIfType() */
devtype ifType() { return interface_type; }
/* Starts the timeout clock for the host running (e.g. you are
beginning a scan). If you do not have the current time handy,
you can pass in NULL. When done, call stopTimeOutClock (it will
Expand All @@ -177,9 +199,20 @@ class Target {
/* Takes a 6-byte MAC address */
int setMACAddress(const u8 *addy);
int setSrcMACAddress(const u8 *addy);
int setNextHopMACAddress(const u8 *addy); // this should be the target's own MAC if directlyConnected()

/* Returns a pointer to 6-byte MAC address, or NULL if none is set */
const u8 *MACAddress();
const u8 *SrcMACAddress();
const u8 *NextHopMACAddress();

/* Set the device names so that they can be returned by deviceName()
and deviceFullName(). The normal name may not include alias
qualifier, while the full name may include it (e.g. "eth1:1"). If
these are non-null, they will overwrite the stored version */
void setDeviceNames(const char *name, const char *fullname);
const char *deviceName() { return *devname? devname : NULL; }
const char *deviceFullName() { return *devfullname? devfullname : NULL; }

struct seq_info seq;
FingerPrintResults *FPR;
Expand All @@ -191,26 +224,27 @@ class Target {
int wierd_responses; /* echo responses from other addresses, Ie a network broadcast address */
unsigned int flags; /* HOST_UP, HOST_DOWN, HOST_FIREWALLED, HOST_BROADCAST (instead of HOST_BROADCAST use wierd_responses */
struct timeout_info to;
char device[64]; /* The device we transmit on -- make sure to adjust some str* calls if I ever change this size*/

private:

private:
char *hostname; // Null if unable to resolve or unset
void Initialize();
void FreeInternal(); // Free memory allocated inside this object
// Creates a "presentation" formatted string out of the IPv4/IPv6 address
void GenerateIPString();
struct sockaddr_storage targetsock, sourcesock;
size_t targetsocklen, sourcesocklen;
struct sockaddr_storage targetsock, sourcesock, nexthopsock;
size_t targetsocklen, sourcesocklen, nexthopsocklen;
int directly_connected; // -1 = unset; 0 = no; 1 = yes
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
char targetipstring[INET6_ADDRSTRLEN];
char *nameIPBuf; /* for the NameIP(void) function to return */
u8 MACaddress[6];
bool MACaddress_set;
u8 SrcMACaddress[6];
bool SrcMACaddress_set;
u8 MACaddress[6], SrcMACaddress[6], NextHopMACaddress[6];
bool MACaddress_set, SrcMACaddress_set, NextHopMACaddress_set;
struct host_timeout_nfo htn;
devtype interface_type;
char devname[32], devfullname[32];
};

#endif /* TARGET_H */
3 changes: 3 additions & 0 deletions docs/nmap.dtd
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@

<!-- these elements are written by output.c: printosscanoutput() -->

hostname CDATA #IMPLIED
ostype CDATA #IMPLIED
devicetype CDATA #IMPLIED
<!ELEMENT os ( portused* , osclass*, osmatch* ) >

<!ELEMENT portused EMPTY >
Expand Down
2 changes: 1 addition & 1 deletion docs/nmap.usage.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Nmap 3.83.DC1 Usage: nmap [Scan Type(s)] [Options] <host or net list>
Nmap 3.83.SOC1 Usage: nmap [Scan Type(s)] [Options] <host or net list>
Some Common Scan Types ('*' options require root privileges)
* -sS TCP SYN stealth port scan (default if privileged (root))
-sT TCP connect() port scan (default for unprivileged users)
Expand Down
Loading

0 comments on commit 555c986

Please sign in to comment.