mirror of
https://github.com/nmap/nmap.git
synced 2026-05-13 08:46:45 +00:00
Whew -- big reorganization to allow ethernet sends of IP packets
This commit is contained in:
parent
0595d89f96
commit
555c986ac3
29 changed files with 1963 additions and 1362 deletions
24
CHANGELOG
24
CHANGELOG
|
|
@ -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).
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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@
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
23
NmapOps.h
23
NmapOps.h
|
|
@ -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 */
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
68
Target.cc
68
Target.cc
|
|
@ -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() {
|
||||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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
Target.h
52
Target.h
|
|
@ -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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 >
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
85
idle_scan.cc
85
idle_scan.cc
|
|
@ -149,6 +149,8 @@ struct idle_proxy_info {
|
|||
initialize_idleproxy) listens for TCP packets from
|
||||
the probe_port of the proxy box */
|
||||
int rawsd; /* Socket descriptor for sending probe packets to the proxy */
|
||||
struct eth_nfo eth; // For when we want to send probes via raw IP instead.
|
||||
struct eth_nfo *ethptr; // points to eth if filled out, otherwise NULL
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -189,7 +191,7 @@ int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
|
|||
gettimeofday(&tv_sent[tries], NULL);
|
||||
|
||||
/* Time to send the pr0be!*/
|
||||
send_tcp_raw(proxy->rawsd, proxy->host.v4sourceip(),
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(),
|
||||
proxy->host.v4hostip(), o.ttl, base_port + tries,
|
||||
proxy->probe_port,
|
||||
seq_base + (packet_send_count++ * 500) + 1, ack,
|
||||
|
|
@ -281,7 +283,6 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
char *p, *q;
|
||||
char *endptr = NULL;
|
||||
int seq_response_num;
|
||||
char *dev;
|
||||
int newipid;
|
||||
int i;
|
||||
char filter[512]; /* Libpcap filter string */
|
||||
|
|
@ -297,6 +298,7 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
int distance;
|
||||
u16 ipids[NUM_IPID_PROBES];
|
||||
u8 probe_returned[NUM_IPID_PROBES];
|
||||
struct route_nfo rnfo;
|
||||
assert(proxy);
|
||||
assert(proxyName);
|
||||
|
||||
|
|
@ -330,47 +332,66 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
fatal("Could not resolve idlescan zombie host: %s", name);
|
||||
}
|
||||
proxy->host.setTargetSockAddr(&ss, sslen);
|
||||
|
||||
|
||||
/* Lets figure out the appropriate source address to use when sending
|
||||
the pr0bez */
|
||||
proxy->host.TargetSockAddr(&ss, &sslen);
|
||||
if (!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) {
|
||||
o.SourceSockAddr(&ss, &sslen);
|
||||
proxy->host.setSourceSockAddr(&ss, sslen);
|
||||
Strncpy(proxy->host.device, o.device, sizeof(proxy->host.device));
|
||||
proxy->host.setDeviceNames(o.device, o.device);
|
||||
} else {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *)&ss;
|
||||
sslen = sizeof(*sin);
|
||||
memset(sin, 0, sslen);
|
||||
dev = routethrough(proxy->host.v4hostip(), &(sin->sin_addr));
|
||||
if (!dev) fatal("Unable to find appropriate source address and device interface to use when sending packets to %s", proxyName);
|
||||
Strncpy(proxy->host.device, dev, sizeof(proxy->host.device));
|
||||
sin->sin_family = AF_INET;
|
||||
#if HAVE_SOCKADDR_SA_LEN
|
||||
sin->sin_len = sslen;
|
||||
#endif
|
||||
proxy->host.setSourceSockAddr((struct sockaddr_storage *) sin, sslen);
|
||||
proxy->host.setDeviceNames(rnfo.ii.devname, rnfo.ii.devfullname);
|
||||
proxy->host.setSourceSockAddr(&rnfo.srcaddr, sizeof(rnfo.srcaddr));
|
||||
}
|
||||
if (rnfo.direct_connect) {
|
||||
proxy->host.setDirectlyConnected(true);
|
||||
} else {
|
||||
proxy->host.setDirectlyConnected(false);
|
||||
proxy->host.setNextHop(&rnfo.nexthop,
|
||||
sizeof(rnfo.nexthop));
|
||||
}
|
||||
proxy->host.setIfType(rnfo.ii.device_type);
|
||||
if (rnfo.ii.device_type == devt_ethernet)
|
||||
proxy->host.setSrcMACAddress(rnfo.ii.mac);
|
||||
|
||||
/* Now lets send some probes to check IPID algorithm ... */
|
||||
/* First we need a raw socket ... */
|
||||
if ((proxy->rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket trobles in get_fingerprint");
|
||||
unblock_socket(proxy->rawsd);
|
||||
broadcast_socket(proxy->rawsd);
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && proxy->host.ifType() == devt_ethernet) {
|
||||
if (!setTargetNextHopMAC(&proxy->host))
|
||||
fatal("%s: Failed to determine dst MAC address for Idle proxy",
|
||||
__FUNCTION__);
|
||||
memcpy(proxy->eth.srcmac, proxy->host.SrcMACAddress(), 6);
|
||||
memcpy(proxy->eth.dstmac, proxy->host.NextHopMACAddress(), 6);
|
||||
proxy->eth.ethsd = eth_open(proxy->host.deviceName());
|
||||
proxy->rawsd = -1;
|
||||
proxy->ethptr = &proxy->eth;
|
||||
} else {
|
||||
if ((proxy->rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket trobles in get_fingerprint");
|
||||
unblock_socket(proxy->rawsd);
|
||||
broadcast_socket(proxy->rawsd);
|
||||
#ifndef WIN32
|
||||
sethdrinclude(proxy->rawsd);
|
||||
sethdrinclude(proxy->rawsd);
|
||||
#endif
|
||||
proxy->eth.ethsd = NULL;
|
||||
proxy->ethptr = NULL;
|
||||
}
|
||||
|
||||
/* 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.device, 152, (o.spoofsource)? 1 : 0, 50);
|
||||
proxy->pd = my_pcap_open_live(proxy->host.deviceName(), 152, (o.spoofsource)? 1 : 0, 50);
|
||||
|
||||
p = strdup(proxy->host.targetipstr());
|
||||
q = strdup(inet_ntoa(proxy->host.v4source()));
|
||||
snprintf(filter, sizeof(filter), "tcp and src host %s and dst host %s and src port %hu", p, q, proxy->probe_port);
|
||||
free(p);
|
||||
free(q);
|
||||
set_pcap_filter(&(proxy->host), proxy->pd, flt_icmptcp, filter);
|
||||
set_pcap_filter(proxy->host.deviceName(), proxy->pd, flt_icmptcp, filter);
|
||||
/* Windows nonsense -- I am not sure why this is needed, but I should
|
||||
get rid of it at sometime */
|
||||
|
||||
|
|
@ -391,7 +412,7 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
a response with the exact request for timing purposes. So I
|
||||
think I'll use TH_SYN, although it is a tough call. */
|
||||
/* We can't use decoys 'cause that would screw up the IPIDs */
|
||||
send_tcp_raw(proxy->rawsd, proxy->host.v4sourceip(),
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(),
|
||||
proxy->host.v4hostip(), o.ttl,
|
||||
o.magic_port + probes_sent + 1, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, 0, TH_SYN|TH_ACK,
|
||||
|
|
@ -428,7 +449,6 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
continue;
|
||||
|
||||
if (ip->ip_p == IPPROTO_TCP) {
|
||||
/* readtcppacket((char *) ip, ntohs(ip->ip_len)); */
|
||||
tcp = ((struct tcphdr *) (((char *) ip) + 4 * ip->ip_hl));
|
||||
if (ntohs(tcp->th_dport) < (o.magic_port+1) || ntohs(tcp->th_dport) - o.magic_port > NUM_IPID_PROBES || ntohs(tcp->th_sport) != proxy->probe_port || ((tcp->th_flags & TH_RST) == 0)) {
|
||||
if (o.debugging > 1) error("Received unexpected response packet from %s during initial ipid zombie testing", inet_ntoa(ip->ip_src));
|
||||
|
|
@ -508,7 +528,8 @@ void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
|
|||
if (first_target) {
|
||||
for (probes_sent = 0; probes_sent < 4; probes_sent++) {
|
||||
if (probes_sent) usleep(50000);
|
||||
send_tcp_raw(proxy->rawsd, first_target, proxy->host.v4hostip(),
|
||||
send_tcp_raw(proxy->rawsd, proxy->ethptr, first_target,
|
||||
proxy->host.v4hostip(),
|
||||
o.ttl, o.magic_port, proxy->probe_port,
|
||||
sequence_base + probes_sent + 1, 0, TH_SYN|TH_ACK,
|
||||
ack, NULL, 0, NULL, 0);
|
||||
|
|
@ -634,6 +655,7 @@ int idlescan_countopen2(struct idle_proxy_info *proxy,
|
|||
int sleeptime;
|
||||
int lasttry = 0;
|
||||
int dotry3 = 0;
|
||||
struct eth_nfo eth;
|
||||
|
||||
if (seq == 0) seq = get_random_u32();
|
||||
|
||||
|
|
@ -643,6 +665,15 @@ int idlescan_countopen2(struct idle_proxy_info *proxy,
|
|||
if (sent_time) memset(sent_time, 0, sizeof(*sent_time));
|
||||
if (rcv_time) memset(rcv_time, 0, sizeof(*rcv_time));
|
||||
|
||||
if (proxy->rawsd < 0) {
|
||||
if (!setTargetNextHopMAC(target))
|
||||
fatal("%s: Failed to determine dst MAC address for Idle proxy",
|
||||
__FUNCTION__);
|
||||
memcpy(eth.srcmac, target->SrcMACAddress(), 6);
|
||||
memcpy(eth.dstmac, target->NextHopMACAddress(), 6);
|
||||
eth.ethsd = eth_open(target->deviceName());
|
||||
} else eth.ethsd = NULL;
|
||||
|
||||
/* I start by sending out the SYN pr0bez */
|
||||
for(pr0be = 0; pr0be < numports; pr0be++) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
|
|
@ -652,7 +683,8 @@ int idlescan_countopen2(struct idle_proxy_info *proxy,
|
|||
but doing it the straightforward way (using the same decoys as
|
||||
we use in probing the proxy box is risky. I'll have to think
|
||||
about this more. */
|
||||
send_tcp_raw(proxy->rawsd, proxy->host.v4hostip(), target->v4hostip(),
|
||||
send_tcp_raw(proxy->rawsd, eth.ethsd? ð : NULL, proxy->host.v4hostip(),
|
||||
target->v4hostip(),
|
||||
o.ttl, proxy->probe_port, ports[pr0be], seq, 0, TH_SYN, 0,
|
||||
NULL, 0, o.extra_payload, o.extra_payload_length);
|
||||
}
|
||||
|
|
@ -739,6 +771,7 @@ int idlescan_countopen2(struct idle_proxy_info *proxy,
|
|||
if (rcv_time) *rcv_time = latestchange;
|
||||
}
|
||||
if (newipid > 0) proxy->latestid = newipid;
|
||||
if (eth.ethsd) { eth_close(eth.ethsd); eth.ethsd = NULL; }
|
||||
return openports;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ AUTOMAKE = ${SHELL} /home/fyodor/nmap/libdnet-stripped/config/missing --run auto
|
|||
AWK = gawk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=none
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS = -g -Wall
|
||||
CHECKINC =
|
||||
CHECKLIB =
|
||||
CPP = gcc -E
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ AUTOMAKE = ${SHELL} /home/fyodor/nmap/libdnet-stripped/config/missing --run auto
|
|||
AWK = gawk
|
||||
CC = gcc
|
||||
CCDEPMODE = depmode=none
|
||||
CFLAGS = -g -O2 -Wall
|
||||
CFLAGS = -g -Wall
|
||||
CHECKINC =
|
||||
CHECKLIB =
|
||||
CPP = gcc -E
|
||||
|
|
|
|||
|
|
@ -119,12 +119,16 @@ intf_t *
|
|||
intf_open(void)
|
||||
{
|
||||
intf_t *intf;
|
||||
|
||||
int one = 1;
|
||||
|
||||
if ((intf = calloc(1, sizeof(*intf))) != NULL) {
|
||||
intf->fd = intf->fd6 = -1;
|
||||
|
||||
if ((intf->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
|
||||
return (intf_close(intf));
|
||||
|
||||
setsockopt(intf->fd, SOL_SOCKET, SO_BROADCAST,
|
||||
(const char *) &one, sizeof(one));
|
||||
#ifdef SIOCGIFNETMASK_IN6
|
||||
if ((intf->fd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
|
||||
# ifdef EPROTONOSUPPORT
|
||||
|
|
@ -472,6 +476,7 @@ static int
|
|||
_intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
||||
{
|
||||
struct ifreq *ifr, *lifr;
|
||||
struct ifreq tmpifr;
|
||||
struct addr *ap, *lap;
|
||||
char *p;
|
||||
|
||||
|
|
@ -492,12 +497,15 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
|||
if ((p = strchr(ifr->ifr_name, ':')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
if (strcmp(ifr->ifr_name, entry->intf_name) != 0)
|
||||
if (strcmp(ifr->ifr_name, entry->intf_name) != 0) {
|
||||
if (p) *p = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (p) *p = ':'; /* Fix the name back up */
|
||||
if (addr_ston(&ifr->ifr_addr, ap) < 0)
|
||||
continue;
|
||||
|
||||
|
||||
/* XXX */
|
||||
if (ap->addr_type == ADDR_TYPE_ETH) {
|
||||
memcpy(&entry->intf_link_addr, ap, sizeof(*ap));
|
||||
|
|
@ -506,6 +514,11 @@ _intf_get_aliases(intf_t *intf, struct intf_entry *entry)
|
|||
if (ap->addr_ip == entry->intf_addr.addr_ip ||
|
||||
ap->addr_ip == entry->intf_dst_addr.addr_ip)
|
||||
continue;
|
||||
strlcpy(tmpifr.ifr_name, ifr->ifr_name,
|
||||
sizeof(tmpifr.ifr_name));
|
||||
if (ioctl(intf->fd, SIOCGIFNETMASK, &tmpifr) == 0)
|
||||
addr_stob(&tmpifr.ifr_addr, &ap->addr_bits);
|
||||
|
||||
}
|
||||
#ifdef SIOCGIFNETMASK_IN6
|
||||
else if (ap->addr_type == ADDR_TYPE_IP6 && intf->fd6 != -1) {
|
||||
|
|
@ -547,16 +560,28 @@ intf_get(intf_t *intf, struct intf_entry *entry)
|
|||
static int
|
||||
_match_intf_src(const struct intf_entry *entry, void *arg)
|
||||
{
|
||||
int matched = 0;
|
||||
int cnt;
|
||||
struct intf_entry *save = (struct intf_entry *)arg;
|
||||
|
||||
if (entry->intf_addr.addr_type == ADDR_TYPE_IP &&
|
||||
entry->intf_addr.addr_ip == save->intf_addr.addr_ip) {
|
||||
/* XXX - truncated result if entry is too small. */
|
||||
if (save->intf_len < entry->intf_len)
|
||||
memcpy(save, entry, save->intf_len);
|
||||
else
|
||||
memcpy(save, entry, entry->intf_len);
|
||||
return (1);
|
||||
if (entry->intf_addr.addr_type == ADDR_TYPE_IP &&
|
||||
entry->intf_addr.addr_ip == save->intf_addr.addr_ip)
|
||||
matched = 1;
|
||||
|
||||
for (cnt = 0; !matched && cnt < (int) entry->intf_alias_num; cnt++) {
|
||||
if (entry->intf_alias_addrs[cnt].addr_type != ADDR_TYPE_IP)
|
||||
continue;
|
||||
if (entry->intf_alias_addrs[cnt].addr_ip == save->intf_addr.addr_ip)
|
||||
matched = 1;
|
||||
}
|
||||
|
||||
if (matched) {
|
||||
/* XXX - truncated result if entry is too small. */
|
||||
if (save->intf_len < entry->intf_len)
|
||||
memcpy(save, entry, save->intf_len);
|
||||
else
|
||||
memcpy(save, entry, entry->intf_len);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -678,14 +703,18 @@ intf_loop(intf_t *intf, intf_handler callback, void *arg)
|
|||
if ((p = strchr(ifr->ifr_name, ':')) != NULL)
|
||||
*p = '\0';
|
||||
|
||||
if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0)
|
||||
if (pifr != NULL && strcmp(ifr->ifr_name, pifr->ifr_name) == 0) {
|
||||
if (p) *p = ':';
|
||||
continue;
|
||||
}
|
||||
|
||||
memset(ebuf, 0, sizeof(ebuf));
|
||||
strlcpy(entry->intf_name, ifr->ifr_name,
|
||||
sizeof(entry->intf_name));
|
||||
entry->intf_len = sizeof(ebuf);
|
||||
|
||||
/* Repair the alias name back up. */
|
||||
if (p) *p = ':';
|
||||
if (_intf_get_noalias(intf, entry) < 0)
|
||||
return (-1);
|
||||
if (_intf_get_aliases(intf, entry) < 0)
|
||||
|
|
|
|||
|
|
@ -653,126 +653,7 @@ static void winip_list_interfaces()
|
|||
}
|
||||
}
|
||||
|
||||
// Find a route to dest. Fill in source, return device
|
||||
|
||||
// I will fail this if no raw, so nmap will still work
|
||||
|
||||
typedef DWORD (__stdcall *PGBI)(IPAddr, PDWORD);
|
||||
char *routethrough(const struct in_addr *dest, struct in_addr *source)
|
||||
{
|
||||
/*
|
||||
In theory, GetBestInterface is ideal. But we need
|
||||
the source address. Even though GetBestInterface
|
||||
is still the fastest way to get the name,
|
||||
ipaddr2devname is fast enough. So we use
|
||||
SIO_ROUTING_INTERFACE_QUERY.
|
||||
*/
|
||||
|
||||
// the raw senders tend to iterate this
|
||||
// so we cache the results
|
||||
static DWORD last_dest = 0;
|
||||
static DWORD last_source;
|
||||
static char dev[128];
|
||||
struct sockaddr_in sin_dest, sin_source;
|
||||
|
||||
winip_test(0);
|
||||
if(inited == 3)
|
||||
{
|
||||
static int warned = 0;
|
||||
if(!warned)
|
||||
printf("routethrough: failing due to lack of any raw support\n");
|
||||
warned = 1;
|
||||
}
|
||||
|
||||
if(last_dest == dest->s_addr)
|
||||
{
|
||||
source->s_addr = last_source;
|
||||
return dev;
|
||||
}
|
||||
|
||||
ZeroMemory(&sin_dest, sizeof(sin_dest));
|
||||
sin_dest.sin_family = AF_INET;
|
||||
sin_dest.sin_addr = *dest;
|
||||
|
||||
if(wo.nt4route)
|
||||
{
|
||||
MIB_IPFORWARDROW ir;
|
||||
int ifi;
|
||||
|
||||
if(0 != get_best_route(sin_dest.sin_addr.s_addr, &ir))
|
||||
{
|
||||
if(o.debugging > 1)
|
||||
printf("get_best_route failed, so routethrough will fail\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(-1 == (ifi = winif2ifi(ir.dwForwardIfIndex)))
|
||||
fatal("routethrough: got unmappable (new?) interface\n");
|
||||
|
||||
if(0 != ifi2ipaddr(ifi, &sin_source.sin_addr))
|
||||
fatal("routethrough: no IP for device %s\n", ifi2name(ifi));
|
||||
|
||||
if(!rawsock_avail && !iftable[ifi].pcapname) return NULL;
|
||||
|
||||
strcpy(dev, ifi2name(ifi));
|
||||
}
|
||||
else
|
||||
{
|
||||
SOCKET s;
|
||||
DWORD br;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if(s == INVALID_SOCKET)
|
||||
fatal("failed to create socket\n");
|
||||
|
||||
if(0 != WSAIoctl(s, SIO_ROUTING_INTERFACE_QUERY,
|
||||
&sin_dest, sizeof(sin_dest),
|
||||
&sin_source, sizeof(sin_source), &br, 0, 0))
|
||||
{
|
||||
if(o.debugging)
|
||||
printf("SIO_ROUTING_INTERFACE_QUERY(%s) failed (%d)\n", inet_ntoa(*dest), WSAGetLastError());
|
||||
closesocket(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
closesocket(s);
|
||||
}
|
||||
|
||||
// localhost scan (fake) support
|
||||
// this allows localhost, but not 127.0.0.1, scans to seem to work
|
||||
if(sin_source.sin_addr.s_addr == htonl(INADDR_LOOPBACK))
|
||||
sin_source.sin_addr.s_addr = dest->s_addr;
|
||||
|
||||
if(0 != ipaddr2devname(dev, &sin_source.sin_addr))
|
||||
{
|
||||
if(o.debugging)
|
||||
{
|
||||
printf("routethrough: %s routes through ", inet_ntoa(*dest));
|
||||
printf("%s, but inaddr2devname failed\n",
|
||||
inet_ntoa(sin_source.sin_addr));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!rawsock_avail &&
|
||||
!iftable[ipaddr2ifi(sin_source.sin_addr.s_addr)].pcapname)
|
||||
return NULL;
|
||||
|
||||
last_dest = dest->s_addr;
|
||||
last_source = sin_source.sin_addr.s_addr;
|
||||
*source = sin_source.sin_addr;
|
||||
|
||||
if(o.debugging > 1)
|
||||
{
|
||||
printf("%s will use interface ", inet_ntoa(*(struct in_addr*)&last_dest));
|
||||
printf("%s\n", inet_ntoa(*(struct in_addr*)&last_source));
|
||||
}
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
// socket and sendto replacements
|
||||
int win32_sendto(int sd, const char *packet, int len,
|
||||
|
|
@ -816,7 +697,7 @@ void win32_pcap_close(pcap_t *pd)
|
|||
else rawrecv_close(pd);
|
||||
}
|
||||
|
||||
pcap_t *my_pcap_open_live(char *device, int snaplen, int promisc, int to_ms)
|
||||
pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc, int to_ms)
|
||||
{
|
||||
int ifi = name2ifi(device);
|
||||
if(ifi == -1)
|
||||
|
|
@ -856,7 +737,7 @@ void sethdrinclude(int sd)
|
|||
}
|
||||
}
|
||||
|
||||
void set_pcap_filter(Target *target,
|
||||
void set_pcap_filter(const char *device,
|
||||
pcap_t *pd, PFILTERFN filter, char *bpf, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
|
@ -871,7 +752,7 @@ void set_pcap_filter(Target *target,
|
|||
return;
|
||||
}
|
||||
|
||||
if (pcap_lookupnet(target->device, &localnet, &netmask, err0r) == -1)
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, err0r) == -1)
|
||||
; /* fatal("Failed to lookup device subnet/netmask: %s", err0r);*/
|
||||
|
||||
va_start(ap, bpf);
|
||||
|
|
@ -884,10 +765,6 @@ void set_pcap_filter(Target *target,
|
|||
if (o.debugging)
|
||||
log_write(LOG_STDOUT, "Packet capture filter: %s\n", buf);
|
||||
|
||||
/* Due to apparent bug in libpcap */
|
||||
if (islocalhost(target->v4hostip()))
|
||||
buf[0] = '\0';
|
||||
|
||||
if (pcap_compile(pd, &fcode, buf, 0, netmask) < 0)
|
||||
fatal("Error compiling our pcap filter: %s\n", pcap_geterr(pd));
|
||||
if (pcap_setfilter(pd, &fcode) < 0 )
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ typedef int (*PFILTERFN)(const char *packet, unsigned int len); /* 1 to keep */
|
|||
// Makes gcc happy
|
||||
// One wonders why VC doesn't complain...
|
||||
class Target;
|
||||
EXTERNC void set_pcap_filter(Target *target, pcap_t *pd, PFILTERFN filter, char *bpf, ...);
|
||||
EXTERNC void set_pcap_filter(const char *device, pcap_t *pd, PFILTERFN filter, char *bpf, ...);
|
||||
|
||||
|
||||
typedef struct _IPNODE {
|
||||
|
|
@ -173,7 +173,7 @@ EXTERNC int get_best_route(DWORD dest, PMIB_IPFORWARDROW r);
|
|||
|
||||
// pcapsend interface
|
||||
EXTERNC void pcapsend_init();
|
||||
EXTERNC pcap_t *my_real_pcap_open_live(char *device, int snaplen, int promisc, int to_ms);
|
||||
EXTERNC pcap_t *my_real_pcap_open_live(const char *device, int snaplen, int promisc, int to_ms);
|
||||
EXTERNC int pcapsendraw(const char *packet, int len,
|
||||
struct sockaddr *to, int tolen);
|
||||
|
||||
|
|
|
|||
|
|
@ -3951,7 +3951,7 @@ PU(Resp=N)
|
|||
# Brocade Fibre Switch, Firmware 2.6.0
|
||||
# Cisco Aironet 340 WAP running v 12.03T of the firmware (and VxWorks OS)
|
||||
Fingerprint Cisco Aironet WAP, Brocade Fibre Switch, or Sun Remote System Console
|
||||
Class Cisco | vxworks || WAP
|
||||
Class Cisco | VxWorks || WAP
|
||||
Class Brocade | embedded || switch
|
||||
Class Sun | embedded || remote management
|
||||
TSeq(Class=64K%IPID=I%TS=U)
|
||||
|
|
@ -10791,19 +10791,6 @@ T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
|
|||
T7(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
PU(Resp=N)
|
||||
|
||||
# Microsoft Windows Longhorn Preview, Version 6.0 Build 4051.idx 02.031001-1340
|
||||
Fingerprint Microsoft Windows Longhorn Preview
|
||||
Class Microsoft | Windows | Windows Longhorn | general purpose
|
||||
TSeq(Class=TR%gcd=<6%IPID=I%TS=100HZ)
|
||||
T1(DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
T2(Resp=N)
|
||||
T3(Resp=N)
|
||||
T4(DF=Y%W=0%ACK=O%Flags=R%Ops=)
|
||||
T5(DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
T6(DF=Y%W=0%ACK=O%Flags=R%Ops=)
|
||||
T7(Resp=N)
|
||||
PU(DF=N%TOS=0%IPLEN=164%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
|
||||
|
||||
# Microsoft Windows Server 2003, Enterprise Edition, Build 3790
|
||||
# Microsoft .NET Enterprise Server RC2 (Version 5.2 build 3718.dnsrv.021114-1947)
|
||||
Fingerprint Microsoft Windows .NET Enterprise Server RC2 (Version 5.2, build 3718.dnsrv.021114-1947)
|
||||
|
|
@ -12388,6 +12375,19 @@ T6(DF=N%W=0%ACK=O%Flags=R%Ops=)
|
|||
T7(DF=N%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
PU(DF=N%TOS=0%IPLEN=38%RIPTL=148%RID=E|F%RIPCK=E%UCK=E%ULEN=134%DAT=E)
|
||||
|
||||
# Microsoft Windows Longhorn Preview, Version 6.0 Build 4051.idx 02.031001-1340
|
||||
Fingerprint Microsoft Windows Longhorn Preview
|
||||
Class Microsoft | Windows | Windows Longhorn | general purpose
|
||||
TSeq(Class=TR%gcd=<6%IPID=I%TS=100HZ)
|
||||
T1(DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
T2(Resp=N)
|
||||
T3(Resp=N)
|
||||
T4(DF=Y%W=0%ACK=O%Flags=R%Ops=)
|
||||
T5(DF=Y%W=0%ACK=S++%Flags=AR%Ops=)
|
||||
T6(DF=Y%W=0%ACK=O%Flags=R%Ops=)
|
||||
T7(Resp=N)
|
||||
PU(DF=N%TOS=0%IPLEN=164%RIPTL=148%RID=E%RIPCK=E%UCK=E%ULEN=134%DAT=E)
|
||||
|
||||
# Windows 2000 Pro, Build 2195 SP4
|
||||
Fingerprint Microsoft Windows 2000 Pro SP4
|
||||
Class Microsoft | Windows || general purpose
|
||||
|
|
|
|||
1346
nmap-service-probes
1346
nmap-service-probes
File diff suppressed because it is too large
Load diff
15
nmap.cc
15
nmap.cc
|
|
@ -275,6 +275,8 @@ int nmap_main(int argc, char *argv[]) {
|
|||
{"version_trace", no_argument, 0, 0}, /* Display -sV related activity */
|
||||
{"fuzzy", no_argument, 0, 0}, /* Alias for osscan_guess */
|
||||
{"data_length", required_argument, 0, 0},
|
||||
{"send_eth", no_argument, 0, 0},
|
||||
{"send_ip", no_argument, 0, 0},
|
||||
{"stylesheet", required_argument, 0, 0},
|
||||
{"no-stylesheet", no_argument, 0, 0},
|
||||
{"rH", no_argument, 0, 0},
|
||||
|
|
@ -444,6 +446,10 @@ int nmap_main(int argc, char *argv[]) {
|
|||
o.extra_payload = (char *) safe_malloc(o.extra_payload_length);
|
||||
get_random_bytes(o.extra_payload, o.extra_payload_length);
|
||||
}
|
||||
} else if (strcmp(long_options[option_index].name, "send_eth") == 0) {
|
||||
o.sendpref = PACKET_SEND_ETH_STRONG;
|
||||
} else if (strcmp(long_options[option_index].name, "send_ip") == 0) {
|
||||
o.sendpref = PACKET_SEND_IP_STRONG;
|
||||
} else if (strcmp(long_options[option_index].name, "stylesheet") == 0) {
|
||||
o.setXSLStyleSheet(optarg);
|
||||
} else if (strcmp(long_options[option_index].name, "no-stylesheet") == 0) {
|
||||
|
|
@ -1085,16 +1091,16 @@ int nmap_main(int argc, char *argv[]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!*currenths->device)
|
||||
if (ipaddr2devname( currenths->device, currenths->v4sourceip()) != 0)
|
||||
fatal("Could not figure out what device to send the packet out on! You might possibly want to try -S (but this is probably a bigger problem). If you are trying to sp00f the source of a SYN/FIN scan with -S <fakeip>, then you must use -e eth0 (or other devicename) to tell us what interface to use.\n");
|
||||
if (!currenths->deviceName())
|
||||
fatal("Do not have appropriate device name for target");
|
||||
|
||||
/* Groups should generally use the same device as properties
|
||||
change quite a bit between devices. Plus dealing with a
|
||||
multi-device group can be a pain programmatically. So if
|
||||
this Target has a different device the rest, we give it
|
||||
back. */
|
||||
if (Targets.size() > 0 && strcmp(Targets[Targets.size() - 1]->device, currenths->device)) {
|
||||
if (Targets.size() > 0 &&
|
||||
strcmp(Targets[Targets.size() - 1]->deviceName(), currenths->deviceName())) {
|
||||
returnhost(hstate);
|
||||
numhosts_scanned--; numhosts_up--;
|
||||
break;
|
||||
|
|
@ -1183,6 +1189,7 @@ int nmap_main(int argc, char *argv[]) {
|
|||
printportoutput(currenths, ¤ths->ports);
|
||||
printmacinfo(currenths);
|
||||
printosscanoutput(currenths);
|
||||
printserviceinfooutput(currenths);
|
||||
}
|
||||
|
||||
if (o.debugging)
|
||||
|
|
|
|||
14
nmap.h
14
nmap.h
|
|
@ -218,15 +218,15 @@ void *realloc();
|
|||
#include <pwd.h>
|
||||
#endif
|
||||
|
||||
#ifndef NETINET_IN_SYSTEM_H /* why the HELL does OpenBSD not do this? */
|
||||
#ifndef NETINET_IN_SYSTEM_H /* why does OpenBSD not do this? */
|
||||
#include <netinet/in_systm.h> /* defines n_long needed for netinet/ip.h */
|
||||
#define NETINET_IN_SYSTEM_H
|
||||
#endif
|
||||
#ifndef NETINET_IP_H /* why the HELL does OpenBSD not do this? */
|
||||
#ifndef NETINET_IP_H /* why does OpenBSD not do this? */
|
||||
#include <netinet/ip.h>
|
||||
#define NETINET_IP_H
|
||||
#endif
|
||||
#include <netinet/ip_icmp.h>
|
||||
// #include <netinet/ip_icmp.h>
|
||||
|
||||
#if HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
|
|
@ -237,7 +237,7 @@ void *realloc();
|
|||
#ifndef __FAVOR_BSD
|
||||
#define __FAVOR_BSD
|
||||
#endif
|
||||
#ifndef NETINET_TCP_H /* why the HELL does OpenBSD not do this? */
|
||||
#ifndef NETINET_TCP_H /* why does OpenBSD not do this? */
|
||||
#include <netinet/tcp.h> /*#include <netinet/ip_tcp.h>*/
|
||||
#define NETINET_TCP_H
|
||||
#endif
|
||||
|
|
@ -314,6 +314,10 @@ void *realloc();
|
|||
#define MAX_UDP_SCAN_DELAY 1000
|
||||
#endif
|
||||
|
||||
/* Maximum number of extra hostnames, OSs, and devices, we
|
||||
consider when outputing the extra service info fields */
|
||||
#define MAX_SERVICE_INFO_FIELDS 5
|
||||
|
||||
/* We wait at least 100 ms for a response by default - while that
|
||||
seems aggressive, waiting too long can cause us to fail to detect
|
||||
drops until many probes later on extremely low-latency
|
||||
|
|
@ -431,8 +435,6 @@ void printusage(char *name, int rc);
|
|||
/* print Interactive usage information */
|
||||
void printinteractiveusage();
|
||||
|
||||
/* Scan helper functions */
|
||||
unsigned long calculate_sleep(struct in_addr target);
|
||||
int check_ident_port(struct in_addr target);
|
||||
|
||||
int ftp_anon_connect(struct ftpinfo *ftp);
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@
|
|||
extern void CloseLibs(void);
|
||||
#endif
|
||||
|
||||
void fatal(char *fmt, ...) {
|
||||
void fatal(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fflush(stdout);
|
||||
|
|
@ -119,7 +119,7 @@ va_end(ap);
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void error(char *fmt, ...) {
|
||||
void error(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
fflush(stdout);
|
||||
|
|
@ -130,7 +130,7 @@ va_end(ap);
|
|||
return;
|
||||
}
|
||||
|
||||
void pfatal(char *err, ...) {
|
||||
void pfatal(const char *err, ...) {
|
||||
#ifdef WIN32
|
||||
int lasterror =0;
|
||||
char *errstr = NULL;
|
||||
|
|
@ -152,7 +152,7 @@ void pfatal(char *err, ...) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
void gh_perror(char *err, ...) {
|
||||
void gh_perror(const char *err, ...) {
|
||||
va_list ap;va_start(ap, err);
|
||||
fflush(stdout);
|
||||
vfprintf(stderr, err, ap);
|
||||
|
|
|
|||
|
|
@ -126,13 +126,13 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
void fatal(char *fmt, ...)
|
||||
void fatal(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void error(char *fmt, ...)
|
||||
void error(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void pfatal(char *err, ...)
|
||||
void pfatal(const char *err, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
void gh_perror(char *err, ...)
|
||||
void gh_perror(const char *err, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
#endif /* NMAP_ERROR_H */
|
||||
|
||||
|
|
|
|||
58
osscan.cc
58
osscan.cc
|
|
@ -162,6 +162,8 @@ int seq_packets_sent = 0;
|
|||
int seq_response_num; /* response # for sequencing */
|
||||
double avg_ts_hz = 0.0; /* Avg. amount that timestamps incr. each second */
|
||||
struct link_header linkhdr;
|
||||
struct eth_nfo eth;
|
||||
struct eth_nfo *ethptr; // for passing to send_ functions
|
||||
|
||||
if (target->timedOut(NULL))
|
||||
return NULL;
|
||||
|
|
@ -175,14 +177,24 @@ si->lastboot = 0;
|
|||
/* Init our fingerprint tests to each be NULL */
|
||||
memset(FPtests, 0, sizeof(FPtests));
|
||||
get_random_bytes(&sequence_base, sizeof(unsigned int));
|
||||
/* Init our raw socket */
|
||||
if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket trobles in get_fingerprint");
|
||||
unblock_socket(rawsd);
|
||||
broadcast_socket(rawsd);
|
||||
if ((o.sendpref & PACKET_SEND_ETH) && target->ifType() == devt_ethernet) {
|
||||
memcpy(eth.srcmac, target->SrcMACAddress(), 6);
|
||||
memcpy(eth.dstmac, target->NextHopMACAddress(), 6);
|
||||
eth.ethsd = eth_open(target->deviceName());
|
||||
rawsd = -1;
|
||||
ethptr = ð
|
||||
} else {
|
||||
/* Init our raw socket */
|
||||
if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket trobles in get_fingerprint");
|
||||
unblock_socket(rawsd);
|
||||
broadcast_socket(rawsd);
|
||||
#ifndef WIN32
|
||||
sethdrinclude(rawsd);
|
||||
sethdrinclude(rawsd);
|
||||
#endif
|
||||
ethptr = NULL;
|
||||
eth.ethsd = NULL;
|
||||
}
|
||||
|
||||
/* Now for the pcap opening nonsense ... */
|
||||
/* Note that the snaplen is 152 = 64 byte max IPhdr + 24 byte max link_layer
|
||||
|
|
@ -192,7 +204,7 @@ get_random_bytes(&sequence_base, sizeof(unsigned int));
|
|||
ossofttimeout = MAX(200000, target->to.timeout);
|
||||
oshardtimeout = MAX(500000, 5 * target->to.timeout);
|
||||
|
||||
pd = my_pcap_open_live(target->device, /*650*/ 8192, (o.spoofsource)? 1 : 0, (ossofttimeout + 500)/ 1000);
|
||||
pd = my_pcap_open_live(target->deviceName(), /*650*/ 8192, (o.spoofsource)? 1 : 0, (ossofttimeout + 500)/ 1000);
|
||||
|
||||
if (o.debugging > 1)
|
||||
log_write(LOG_STDOUT, "Wait time is %dms\n", (ossofttimeout +500)/1000);
|
||||
|
|
@ -202,7 +214,7 @@ if (o.debugging > 1)
|
|||
|
||||
snprintf(filter, sizeof(filter), "dst host %s and (icmp or (tcp and src host %s))", inet_ntoa(target->v4source()), target->targetipstr());
|
||||
|
||||
set_pcap_filter(target, pd, flt_icmptcp, filter);
|
||||
set_pcap_filter(target->deviceName(), pd, flt_icmptcp, filter);
|
||||
target->osscan_performed = 1; /* Let Nmap know that we did try an OS scan */
|
||||
|
||||
/* Lets find an open port to use */
|
||||
|
|
@ -241,28 +253,31 @@ if (o.verbose && openport != (unsigned long) -1)
|
|||
/* Test 1 */
|
||||
if (!FPtests[1]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port,
|
||||
openport, sequence_base, 0,TH_ECE|TH_SYN, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port, openport, sequence_base, 0,
|
||||
TH_ECE|TH_SYN, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
/* Test 2 */
|
||||
if (!FPtests[2]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +1,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port +1,
|
||||
openport, sequence_base, 0,0, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
/* Test 3 */
|
||||
if (!FPtests[3]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +2,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, current_port +2,
|
||||
openport, sequence_base, 0,TH_SYN|TH_FIN|TH_URG|TH_PUSH, 0,(u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
/* Test 4 */
|
||||
if (!FPtests[4]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +3,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port +3,
|
||||
openport, sequence_base, 0,TH_ACK, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -270,21 +285,24 @@ if (o.verbose && openport != (unsigned long) -1)
|
|||
/* Test 5 */
|
||||
if (!FPtests[5]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +4,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port +4,
|
||||
closedport, sequence_base, 0,TH_SYN, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
/* Test 6 */
|
||||
if (!FPtests[6]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +5,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port +5,
|
||||
closedport, sequence_base, 0,TH_ACK, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
/* Test 7 */
|
||||
if (!FPtests[7]) {
|
||||
if (o.scan_delay) enforce_scan_delay(NULL);
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl, current_port +6,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
current_port +6,
|
||||
closedport, sequence_base, 0,TH_FIN|TH_PUSH|TH_URG, 0, (u8 *) "\003\003\012\001\002\004\001\011\010\012\077\077\077\077\000\000\000\000\000\000" , 20, NULL, 0);
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +388,7 @@ if (o.verbose && openport != (unsigned long) -1)
|
|||
usleep(remaining_us);
|
||||
}
|
||||
}
|
||||
send_tcp_raw_decoys(rawsd, target->v4hostip(), o.ttl,
|
||||
send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
|
||||
o.magic_port + seq_packets_sent + 1,
|
||||
openport,
|
||||
sequence_base + seq_packets_sent + 1, 0,
|
||||
|
|
@ -738,7 +756,11 @@ for(i=0; i < 9; i++) {
|
|||
osscan_timedout:
|
||||
if (target->timedOut(NULL))
|
||||
FP = NULL;
|
||||
close(rawsd);
|
||||
if (rawsd >= 0)
|
||||
close(rawsd);
|
||||
if (ethptr) {
|
||||
eth_close(ethptr->ethsd);
|
||||
}
|
||||
pcap_close(pd);
|
||||
return FP;
|
||||
}
|
||||
|
|
|
|||
157
output.cc
157
output.cc
|
|
@ -127,6 +127,7 @@ static int getServiceXMLBuf(struct serviceDeductions *sd, char *xmlbuf,
|
|||
string versionxmlstring;
|
||||
char rpcbuf[128];
|
||||
char *xml_product = NULL, *xml_version = NULL, *xml_extrainfo = NULL;
|
||||
char *xml_hostname = NULL, *xml_ostype = NULL, *xml_devicetype = NULL;
|
||||
|
||||
if (xmlbuflen < 1) return -1;
|
||||
xmlbuf[0] = '\0';
|
||||
|
|
@ -156,6 +157,30 @@ static int getServiceXMLBuf(struct serviceDeductions *sd, char *xmlbuf,
|
|||
versionxmlstring += '\"';
|
||||
}
|
||||
|
||||
if (sd->hostname) {
|
||||
xml_hostname = xml_convert(sd->hostname);
|
||||
versionxmlstring += " hostname=\"";
|
||||
versionxmlstring += xml_hostname;
|
||||
free(xml_hostname); xml_hostname = NULL;
|
||||
versionxmlstring += '\"';
|
||||
}
|
||||
|
||||
if (sd->ostype) {
|
||||
xml_ostype = xml_convert(sd->ostype);
|
||||
versionxmlstring += " ostype=\"";
|
||||
versionxmlstring += xml_ostype;
|
||||
free(xml_ostype); xml_ostype = NULL;
|
||||
versionxmlstring += '\"';
|
||||
}
|
||||
|
||||
if (sd->devicetype) {
|
||||
xml_devicetype = xml_convert(sd->devicetype);
|
||||
versionxmlstring += " devicetype=\"";
|
||||
versionxmlstring += xml_devicetype;
|
||||
free(xml_devicetype); xml_devicetype = NULL;
|
||||
versionxmlstring += '\"';
|
||||
}
|
||||
|
||||
if (o.rpcscan && sd->rpc_status == RPC_STATUS_GOOD_PROG) {
|
||||
snprintf(rpcbuf, sizeof(rpcbuf),
|
||||
" rpcnum=\"%li\" lowver=\"%i\" highver=\"%i\" proto=\"rpc\"",
|
||||
|
|
@ -234,8 +259,7 @@ void printportoutput(Target *currenths, PortList *plist) {
|
|||
struct protoent *proto;
|
||||
Port *current;
|
||||
int numignoredports;
|
||||
int portno, protocount;
|
||||
map<u16, Port*> protoarrays[2];
|
||||
int portno;
|
||||
char hostname[1200];
|
||||
int istate = plist->getIgnoredPortState();
|
||||
numignoredports = plist->state_counts[istate];
|
||||
|
|
@ -318,14 +342,12 @@ void printportoutput(Target *currenths, PortList *plist) {
|
|||
|
||||
log_write(LOG_MACHINE,"\t%s: ", (o.ipprotscan)? "Protocols" : "Ports" );
|
||||
|
||||
protoarrays[0] = plist->tcp_ports;
|
||||
protoarrays[1] = plist->udp_ports;
|
||||
current = NULL;
|
||||
rowno = 1;
|
||||
if (o.ipprotscan) {
|
||||
for (portno = 0; portno < 256; portno++) {
|
||||
if (!plist->ip_ports[portno]) continue;
|
||||
current = plist->ip_ports[portno];
|
||||
if (!plist->ip_prots[portno]) continue;
|
||||
current = plist->ip_prots[portno];
|
||||
if (current->state != istate) {
|
||||
if (!first) log_write(LOG_MACHINE,", ");
|
||||
else first = 0;
|
||||
|
|
@ -346,10 +368,20 @@ void printportoutput(Target *currenths, PortList *plist) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for(protocount = 0; protocount < 2; protocount++) {
|
||||
for(map<u16,Port*>::iterator iter = protoarrays[protocount].begin(); iter != protoarrays[protocount].end(); iter++) {
|
||||
current = (*iter).second;
|
||||
|
||||
map<u16,Port*>::iterator tcpIter = plist->tcp_ports.begin();
|
||||
map<u16,Port*>::iterator udpIter = plist->udp_ports.begin();
|
||||
|
||||
while (tcpIter != plist->tcp_ports.end() || udpIter != plist->udp_ports.end()) {
|
||||
|
||||
// If the udp iterator is at the end, then we always read from tcp and vica-versa
|
||||
if (tcpIter != plist->tcp_ports.end() && (udpIter == plist->udp_ports.end() || tcpIter->first <= udpIter->first)) {
|
||||
current = tcpIter->second;
|
||||
tcpIter++;
|
||||
} else {
|
||||
current = udpIter->second;
|
||||
udpIter++;
|
||||
}
|
||||
|
||||
if (current->state != istate) {
|
||||
if (!first) log_write(LOG_MACHINE,", ");
|
||||
else first = 0;
|
||||
|
|
@ -449,7 +481,7 @@ void printportoutput(Target *currenths, PortList *plist) {
|
|||
rowno++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/* log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"\n"); */
|
||||
if (plist->state_counts[istate] > 0)
|
||||
|
|
@ -1089,7 +1121,7 @@ void printosscanoutput(Target *currenths) {
|
|||
}
|
||||
} else { assert(0); }
|
||||
|
||||
if (o.debugging || o.verbose > 1) {
|
||||
if (o.debugging || o.verbose) {
|
||||
|
||||
log_write(LOG_XML,"<osfingerprint fingerprint=\"\n%s\" />\n",
|
||||
mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs,
|
||||
|
|
@ -1159,6 +1191,107 @@ void printosscanoutput(Target *currenths) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* An auxillary function for printserviceinfooutput(). Returns
|
||||
non-zero if a and b are considered the same hostnames. */
|
||||
static int hostcmp(const char *a, const char *b) {
|
||||
return strcasestr(a, b)? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
/* Prints the alternate hostname/OS/device information we got from the
|
||||
* service scan (if it was performed) */
|
||||
void printserviceinfooutput(Target *currenths) {
|
||||
|
||||
Port *p = NULL;
|
||||
struct serviceDeductions sd;
|
||||
int i, numhostnames=0, numostypes=0, numdevicetypes=0;
|
||||
char hostname_tbl[MAX_SERVICE_INFO_FIELDS][MAXHOSTNAMELEN];
|
||||
char ostype_tbl[MAX_SERVICE_INFO_FIELDS][64];
|
||||
char devicetype_tbl[MAX_SERVICE_INFO_FIELDS][64];
|
||||
|
||||
for (i=0; i<MAX_SERVICE_INFO_FIELDS; i++)
|
||||
hostname_tbl[i][0] = ostype_tbl[i][0] = devicetype_tbl[i][0] = '\0';
|
||||
|
||||
while ((p = currenths->ports.nextPort(p, 0, PORT_OPEN, false))) {
|
||||
// The following 2 lines (from portlist.h) tell us that we don't
|
||||
// need to worry about free()ing anything in the serviceDeductions struct.
|
||||
// pass in an allocated struct serviceDeductions (don't wory about initializing, and
|
||||
// you don't have to free any internal ptrs.
|
||||
p->getServiceDeductions(&sd);
|
||||
|
||||
if (sd.hostname && !hostcmp(currenths->HostName(), sd.hostname)) {
|
||||
for (i=0; i<MAX_SERVICE_INFO_FIELDS; i++) {
|
||||
if (hostname_tbl[i][0] && hostcmp(&hostname_tbl[i][0], sd.hostname))
|
||||
break;
|
||||
|
||||
if (!hostname_tbl[i][0]) {
|
||||
numhostnames++;
|
||||
strncpy(&hostname_tbl[i][0], sd.hostname, sizeof(hostname_tbl[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sd.ostype) {
|
||||
for (i=0; i<MAX_SERVICE_INFO_FIELDS; i++) {
|
||||
if (ostype_tbl[i][0] && !strcmp(&ostype_tbl[i][0], sd.ostype))
|
||||
break;
|
||||
|
||||
if (!ostype_tbl[i][0]) {
|
||||
numostypes++;
|
||||
strncpy(&ostype_tbl[i][0], sd.ostype, sizeof(ostype_tbl[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sd.devicetype) {
|
||||
for (i=0; i<MAX_SERVICE_INFO_FIELDS; i++) {
|
||||
if (devicetype_tbl[i][0] && !strcmp(&devicetype_tbl[i][0], sd.devicetype))
|
||||
break;
|
||||
|
||||
if (!devicetype_tbl[i][0]) {
|
||||
numdevicetypes++;
|
||||
strncpy(&devicetype_tbl[i][0], sd.devicetype, sizeof(devicetype_tbl[i]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!numhostnames && !numostypes && !numdevicetypes) return;
|
||||
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "Service Info:");
|
||||
|
||||
if (numhostnames) {
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, " Host%s: %s", numhostnames==1? "" : "s", &hostname_tbl[0][0]);
|
||||
for (i=1; i<MAX_SERVICE_INFO_FIELDS; i++)
|
||||
if (hostname_tbl[i][0])
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, ", %s", &hostname_tbl[i][0]);
|
||||
}
|
||||
|
||||
if (numostypes) {
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, " OS%s: %s", numostypes==1? "" : "s", &ostype_tbl[0][0]);
|
||||
for (i=1; i<MAX_SERVICE_INFO_FIELDS; i++)
|
||||
if (ostype_tbl[i][0])
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, ", %s", &ostype_tbl[i][0]);
|
||||
}
|
||||
|
||||
if (numdevicetypes) {
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, " Device%s: %s", numdevicetypes==1? "" : "s", &devicetype_tbl[0][0]);
|
||||
for (i=1; i<MAX_SERVICE_INFO_FIELDS; i++)
|
||||
if (devicetype_tbl[i][0])
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, ", %s", &devicetype_tbl[i][0]);
|
||||
}
|
||||
|
||||
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Prints the statistics and other information that goes at the very end
|
||||
of an Nmap run */
|
||||
void printfinaloutput(int numhosts_scanned, int numhosts_up,
|
||||
|
|
|
|||
4
output.h
4
output.h
|
|
@ -191,6 +191,10 @@ void write_host_status(Target *currenths, int resolve_all);
|
|||
if an OS Scan was performed */
|
||||
void printosscanoutput(Target *currenths);
|
||||
|
||||
/* Prints the alternate hostname/OS/device information we got from the
|
||||
service scan (if it was performed) */
|
||||
void printserviceinfooutput(Target *currenths);
|
||||
|
||||
/* Prints the statistics and other information that goes at the very end
|
||||
of an Nmap run */
|
||||
void printfinaloutput(int numhosts_scanned, int numhosts_up,
|
||||
|
|
|
|||
101
portlist.cc
101
portlist.cc
|
|
@ -173,24 +173,6 @@ static void populateFullVersionString(struct serviceDeductions *sd) {
|
|||
spaceleft -= strlen(sd->extrainfo) + 3;
|
||||
}
|
||||
|
||||
if (sd->hostname && spaceleft >= (strlen(sd->hostname) + 7)) {
|
||||
strncat(dst, " Host: ", spaceleft);
|
||||
strncat(dst, sd->hostname, spaceleft);
|
||||
spaceleft -= strlen(sd->hostname) + 7;
|
||||
}
|
||||
|
||||
if (sd->ostype && spaceleft >= (strlen(sd->ostype) + 5)) {
|
||||
strncat(dst, " OS: ", spaceleft);
|
||||
strncat(dst, sd->ostype, spaceleft);
|
||||
spaceleft -= strlen(sd->ostype) + 5;
|
||||
}
|
||||
|
||||
if (sd->devicetype && spaceleft >= (strlen(sd->devicetype) + 9)) {
|
||||
strncat(dst, " Device: ", spaceleft);
|
||||
strncat(dst, sd->devicetype, spaceleft);
|
||||
spaceleft -= strlen(sd->devicetype) + 9;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -425,18 +407,18 @@ PortList::~PortList() {
|
|||
|
||||
for(map<u16,Port*>::iterator iter = tcp_ports.begin(); iter != tcp_ports.end(); iter++)
|
||||
{
|
||||
delete (*iter).second;
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
|
||||
for(map<u16,Port*>::iterator iter = udp_ports.begin(); iter != udp_ports.end(); iter++)
|
||||
{
|
||||
delete (*iter).second;
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
for(map<u16,Port*>::iterator iter = ip_ports.begin(); iter != ip_ports.end(); iter++)
|
||||
for(map<u16,Port*>::iterator iter = ip_prots.begin(); iter != ip_prots.end(); iter++)
|
||||
{
|
||||
delete (*iter).second;
|
||||
delete iter->second;
|
||||
}
|
||||
|
||||
if (idstr) {
|
||||
|
|
@ -478,10 +460,10 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
|
|||
portarray = &udp_ports;
|
||||
} else if (protocol == IPPROTO_IP) {
|
||||
assert(portno < 256);
|
||||
portarray = &ip_ports;
|
||||
portarray = &ip_prots;
|
||||
} else fatal("addPort: attempted port insertion with invalid protocol");
|
||||
|
||||
if ((*portarray)[portno]) {
|
||||
if (portarray->find(portno) == portarray->end()) {
|
||||
/* We must discount our statistics from the old values. Also warn
|
||||
if a complete duplicate */
|
||||
current = (*portarray)[portno];
|
||||
|
|
@ -496,8 +478,8 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
|
|||
} else
|
||||
state_counts_ip[current->state]--;
|
||||
} else {
|
||||
(*portarray)[portno] = new Port();
|
||||
current = (*portarray)[portno];
|
||||
current = new Port();
|
||||
(*portarray)[portno] = current;
|
||||
numports++;
|
||||
current->portno = portno;
|
||||
}
|
||||
|
|
@ -517,10 +499,13 @@ int PortList::addPort(u16 portno, u8 protocol, char *owner, int state) {
|
|||
free(current->owner);
|
||||
current->owner = strdup(owner);
|
||||
}
|
||||
|
||||
/* printf("\nCurrent Port List\n");
|
||||
|
||||
/*
|
||||
printf("\nCurrent Port List\n");
|
||||
|
||||
for(map<u16,Port*>::iterator iter = (*portarray).begin(); iter != (*portarray).end(); iter++)
|
||||
printf("%d %d\n", (*iter).first, (*iter).second);
|
||||
printf("(%d %d) ", iter->first, iter->second->portno);
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -541,8 +526,8 @@ int PortList::removePort(u16 portno, u8 protocol) {
|
|||
answer = udp_ports[portno];
|
||||
udp_ports.erase(portno);
|
||||
} else if (protocol == IPPROTO_IP) {
|
||||
answer = ip_ports[portno];
|
||||
ip_ports.erase(portno);
|
||||
answer = ip_prots[portno];
|
||||
ip_prots.erase(portno);
|
||||
}
|
||||
|
||||
if (!answer)
|
||||
|
|
@ -582,7 +567,7 @@ Port *PortList::lookupPort(u16 portno, u8 protocol) {
|
|||
return udp_ports[portno];
|
||||
|
||||
if (protocol == IPPROTO_IP)
|
||||
return ip_ports[portno];
|
||||
return ip_prots[portno];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -620,40 +605,52 @@ int PortList::getIgnoredPortState() {
|
|||
Port *PortList::nextPort(Port *afterthisport,
|
||||
u8 allowed_protocol, int allowed_state,
|
||||
bool allow_portzero) {
|
||||
|
||||
|
||||
/* These two are chosen because they come right "before" port 1/tcp */
|
||||
unsigned int current_portno = 0;
|
||||
unsigned int current_proto = IPPROTO_TCP;
|
||||
unsigned int current_proto = IPPROTO_TCP;
|
||||
map<u16,Port*>::iterator iter = tcp_ports.begin();
|
||||
|
||||
if (afterthisport) {
|
||||
current_portno = afterthisport->portno;
|
||||
current_proto = afterthisport->proto; /* (afterthisport->proto == IPPROTO_TCP)? IPPROTO_TCP : IPPROTO_UDP; */
|
||||
current_portno++; /* Start on the port after the one we were given */
|
||||
current_proto = afterthisport->proto;
|
||||
|
||||
// This will advacne to one after the current
|
||||
while (iter != tcp_ports.end() && iter->second->portno <= afterthisport->portno) {
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!allow_portzero && current_portno == 0) current_portno++;
|
||||
/* if (afterthisport)
|
||||
printf("Next Port After %d, %d\n", afterthisport->portno, iter->second->portno); fflush(0);
|
||||
*/
|
||||
|
||||
if (!allow_portzero && iter->second->portno == 0) iter++;
|
||||
|
||||
|
||||
/* First we look for TCP ports ... */
|
||||
if (current_proto == IPPROTO_TCP) {
|
||||
if ((allowed_protocol == 0 || allowed_protocol == IPPROTO_TCP) &&
|
||||
current_proto == IPPROTO_TCP)
|
||||
for(; current_portno < 65536; current_portno++) {
|
||||
if (tcp_ports[current_portno] &&
|
||||
(!allowed_state || tcp_ports[current_portno]->state == allowed_state))
|
||||
return tcp_ports[current_portno];
|
||||
}
|
||||
|
||||
if ((allowed_protocol == 0 || allowed_protocol == IPPROTO_TCP) &&
|
||||
current_proto == IPPROTO_TCP)
|
||||
while (iter != tcp_ports.end()) {
|
||||
if (!allowed_state || iter->second->state == allowed_state) {
|
||||
//printf("Returning %d\n", iter->second->portno);
|
||||
return iter->second;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
/* Uh-oh. We have tried all tcp ports, lets move to udp */
|
||||
current_portno = 0;
|
||||
current_proto = IPPROTO_UDP;
|
||||
iter = udp_ports.begin();
|
||||
}
|
||||
|
||||
if ((allowed_protocol == 0 || allowed_protocol == IPPROTO_UDP) &&
|
||||
current_proto == IPPROTO_UDP) {
|
||||
for(; current_portno < 65536; current_portno++) {
|
||||
if (udp_ports[current_portno] &&
|
||||
(!allowed_state || udp_ports[current_portno]->state == allowed_state))
|
||||
return udp_ports[current_portno];
|
||||
while (iter != udp_ports.end()) {
|
||||
if (!allowed_state || iter->second->state == allowed_state) {
|
||||
//printf("Returning %d\n", iter->second->portno);
|
||||
return iter->second;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ class Port {
|
|||
~Port();
|
||||
|
||||
// pass in an allocated struct serviceDeductions (don't wory about initializing, and
|
||||
// you don't have to free any inernal ptrs. See the serviceDeductions definition for
|
||||
// you don't have to free any internal ptrs. See the serviceDeductions definition for
|
||||
// the fields that are populated. Returns 0 if at least a name is available.
|
||||
int getServiceDeductions(struct serviceDeductions *sd);
|
||||
|
||||
|
|
@ -279,7 +279,7 @@ class PortList {
|
|||
Port *lookupPort(u16 portno, u8 protocol);
|
||||
map < u16, Port* > udp_ports;
|
||||
map < u16, Port* > tcp_ports;
|
||||
map < u16, Port* > ip_ports;
|
||||
map < u16, Port* > ip_prots;
|
||||
|
||||
int state_counts[PORT_HIGHEST_STATE]; /* How many ports in list are in each
|
||||
state */
|
||||
|
|
|
|||
|
|
@ -1061,24 +1061,30 @@ void UltraScanInfo::Init(vector<Target *> &Targets, struct scan_lists *pts, styp
|
|||
rawsd = -1;
|
||||
ethsd = NULL;
|
||||
|
||||
if ((tcp_scan || udp_scan || prot_scan) && scantype != CONNECT_SCAN) {
|
||||
/* Initialize a raw socket */
|
||||
if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket troubles in UltraScanInfo::Init");
|
||||
/* We do not wan't to unblock the socket since we want to wait
|
||||
if kernel send buffers fill up rather than get ENOBUF, and
|
||||
we won't be receiving on the socket anyway
|
||||
unblock_socket(rawsd);*/
|
||||
broadcast_socket(rawsd);
|
||||
if ((tcp_scan || udp_scan || prot_scan || ping_scan_arp) &&
|
||||
scantype != CONNECT_SCAN) {
|
||||
if (ping_scan_arp || ((o.sendpref & PACKET_SEND_ETH) &&
|
||||
Targets[0]->ifType() == devt_ethernet)) {
|
||||
/* We'll send ethernet packets with dnet */
|
||||
ethsd = eth_open(Targets[0]->deviceName());
|
||||
if (ethsd == NULL)
|
||||
fatal("dnet: Failed to open device %s", Targets[0]->deviceName());
|
||||
rawsd = -1;
|
||||
} else {
|
||||
/* Initialize a raw socket */
|
||||
if ((rawsd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0 )
|
||||
pfatal("socket troubles in UltraScanInfo::Init");
|
||||
/* We do not wan't to unblock the socket since we want to wait
|
||||
if kernel send buffers fill up rather than get ENOBUF, and
|
||||
we won't be receiving on the socket anyway
|
||||
unblock_socket(rawsd);*/
|
||||
broadcast_socket(rawsd);
|
||||
#ifndef WIN32
|
||||
sethdrinclude(rawsd);
|
||||
sethdrinclude(rawsd);
|
||||
#endif
|
||||
} else if (ping_scan_arp) {
|
||||
ethsd = eth_open(Targets[0]->device);
|
||||
if (ethsd == NULL)
|
||||
fatal("dnet: Failed to open device %s", o.device);
|
||||
}
|
||||
|
||||
ethsd = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Consults with the group stats, and the hstats for every
|
||||
|
|
@ -1918,7 +1924,16 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||
u32 ack = 0;
|
||||
u16 sport;
|
||||
u16 ipid = get_random_u16();
|
||||
struct eth_nfo eth;
|
||||
struct eth_nfo *ethptr = NULL;
|
||||
|
||||
if (USI->ethsd) {
|
||||
memcpy(eth.srcmac, hss->target->SrcMACAddress(), 6);
|
||||
memcpy(eth.dstmac, hss->target->MACAddress(), 6);
|
||||
eth.ethsd = USI->ethsd;
|
||||
eth.devname[0] = '\0';
|
||||
ethptr = ð
|
||||
}
|
||||
if (pingseq > 0) {
|
||||
if (tryno > 0) assert(0); /* tryno + pingseq not currently supported */
|
||||
sport = o.magic_port_set? o.magic_port : o.magic_port + USI->perf.tryno_cap + pingseq;
|
||||
|
|
@ -1946,7 +1961,7 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||
probe->setIP(packet, packetlen, pspec);
|
||||
hss->lastprobe_sent = probe->sent = USI->now;
|
||||
}
|
||||
send_ip_packet(USI->rawsd, packet, packetlen);
|
||||
send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
|
||||
free(packet);
|
||||
}
|
||||
} else if (USI->udp_scan) {
|
||||
|
|
@ -1959,7 +1974,7 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||
probe->setIP(packet, packetlen, pspec);
|
||||
hss->lastprobe_sent = probe->sent = USI->now;
|
||||
}
|
||||
send_ip_packet(USI->rawsd, packet, packetlen);
|
||||
send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
|
||||
free(packet);
|
||||
}
|
||||
} else if (USI->prot_scan) {
|
||||
|
|
@ -1996,7 +2011,7 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
|
|||
probe->setIP(packet, packetlen, pspec);
|
||||
hss->lastprobe_sent = probe->sent = USI->now;
|
||||
}
|
||||
send_ip_packet(USI->rawsd, packet, packetlen);
|
||||
send_ip_packet(USI->rawsd, ethptr, packet, packetlen);
|
||||
free(packet);
|
||||
}
|
||||
|
||||
|
|
@ -2942,7 +2957,7 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
|
|||
}
|
||||
filterlen = 0;
|
||||
|
||||
USI->pd = my_pcap_open_live(Targets[0]->device, 100, (o.spoofsource)? 1 : 0, 2);
|
||||
USI->pd = my_pcap_open_live(Targets[0]->deviceName(), 100, (o.spoofsource)? 1 : 0, 2);
|
||||
/* Windows nonsense */
|
||||
flt_srchost = Targets[0]->v4host().s_addr;
|
||||
flt_dsthost = Targets[0]->v4source().s_addr;
|
||||
|
|
@ -2982,7 +2997,7 @@ static void begin_sniffer(UltraScanInfo *USI, vector<Target *> &Targets) {
|
|||
filterlen = len;
|
||||
} else assert(0); /* Other scan types? */
|
||||
if (o.debugging > 2) printf("Pcap filter: %s\n", pcap_filter);
|
||||
set_pcap_filter(Targets[0], USI->pd, flt_all, pcap_filter);
|
||||
set_pcap_filter(Targets[0]->deviceName(), USI->pd, flt_all, pcap_filter);
|
||||
/* pcap_setnonblock(USI->pd, 1, NULL); */
|
||||
|
||||
return;
|
||||
|
|
|
|||
123
targets.cc
123
targets.cc
|
|
@ -260,13 +260,14 @@ static void arpping(Target *hostbatch[], int num_hosts,
|
|||
if (islocal) {
|
||||
log_write(LOG_STDOUT|LOG_NORMAL,
|
||||
"ARP ping: Considering %s UP because it is a local IP, despite no MAC address for device %s\n",
|
||||
hostbatch[targetno]->NameIP(), hostbatch[targetno]->device);
|
||||
hostbatch[targetno]->NameIP(), hostbatch[targetno]->deviceName());
|
||||
hostbatch[targetno]->flags &= ~(HOST_DOWN|HOST_FIREWALLED);
|
||||
hostbatch[targetno]->flags |= HOST_UP;
|
||||
} else {
|
||||
log_write(LOG_STDOUT|LOG_NORMAL,
|
||||
"ARP ping: Considering %s DOWN because no MAC address found for device %s.\n",
|
||||
hostbatch[targetno]->NameIP(), hostbatch[targetno]->device);
|
||||
hostbatch[targetno]->NameIP(),
|
||||
hostbatch[targetno]->deviceName());
|
||||
hostbatch[targetno]->flags &= ~HOST_FIREWALLED;
|
||||
hostbatch[targetno]->flags |= HOST_DOWN;
|
||||
}
|
||||
|
|
@ -294,11 +295,16 @@ void returnhost(HostGroupState *hs) {
|
|||
Target *nexthost(HostGroupState *hs, TargetGroup *exclude_group,
|
||||
struct scan_lists *ports, int *pingtype) {
|
||||
int hidx;
|
||||
char *device;
|
||||
int i;
|
||||
struct sockaddr_storage ss;
|
||||
size_t sslen;
|
||||
struct intf_entry *ifentry;
|
||||
u32 ifbuf[200] ;
|
||||
struct route_nfo rnfo;
|
||||
bool arpping_done = false;
|
||||
|
||||
ifentry = (struct intf_entry *) ifbuf;
|
||||
ifentry->intf_len = sizeof(ifbuf); // TODO: May want to use a larger buffer if interface aliases prove important.
|
||||
if (hs->next_batch_no < hs->current_batch_sz) {
|
||||
/* Woop! This is easy -- we just pass back the next host struct */
|
||||
return hs->hostbatch[hs->next_batch_no++];
|
||||
|
|
@ -323,7 +329,7 @@ do {
|
|||
if (o.spoofsource) {
|
||||
o.SourceSockAddr(&ss, &sslen);
|
||||
hs->hostbatch[hidx]->setSourceSockAddr(&ss, sslen);
|
||||
Strncpy(hs->hostbatch[hidx]->device, o.device, 64);
|
||||
hs->hostbatch[hidx]->setDeviceNames(o.device, o.device);
|
||||
} else {
|
||||
/* We figure out the source IP/device IFF
|
||||
1) We are r00t AND
|
||||
|
|
@ -336,44 +342,38 @@ do {
|
|||
|| (*pingtype & (PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS))
|
||||
#endif // WIN32
|
||||
)) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
|
||||
sslen = sizeof(*sin);
|
||||
sin->sin_family = AF_INET;
|
||||
#if HAVE_SOCKADDR_SA_LEN
|
||||
sin->sin_len = sslen;
|
||||
#endif
|
||||
device = routethrough(hs->hostbatch[hidx]->v4hostip(),
|
||||
&(sin->sin_addr));
|
||||
hs->hostbatch[hidx]->setSourceSockAddr(&ss, sslen);
|
||||
hs->hostbatch[hidx]->TargetSockAddr(&ss, &sslen);
|
||||
if (!route_dst(&ss, &rnfo)) {
|
||||
fatal("%s: failed to determine route to %s", __FUNCTION__, hs->hostbatch[hidx]->NameIP());
|
||||
}
|
||||
if (rnfo.direct_connect) {
|
||||
hs->hostbatch[hidx]->setDirectlyConnected(true);
|
||||
} else {
|
||||
hs->hostbatch[hidx]->setDirectlyConnected(false);
|
||||
hs->hostbatch[hidx]->setNextHop(&rnfo.nexthop,
|
||||
sizeof(rnfo.nexthop));
|
||||
}
|
||||
hs->hostbatch[hidx]->setIfType(rnfo.ii.device_type);
|
||||
if (rnfo.ii.device_type == devt_ethernet) {
|
||||
hs->hostbatch[hidx]->setSrcMACAddress(rnfo.ii.mac);
|
||||
}
|
||||
hs->hostbatch[hidx]->setSourceSockAddr(&rnfo.srcaddr, sizeof(rnfo.srcaddr));
|
||||
if (hidx == 0) /* Because later ones can have different src addy and be cut off group */
|
||||
o.decoys[o.decoyturn] = hs->hostbatch[hidx]->v4source();
|
||||
if (!device) {
|
||||
if (*pingtype == PINGTYPE_NONE) {
|
||||
fatal("Could not determine what interface to route packets through, run again with -e <device>");
|
||||
} else {
|
||||
#if WIN32
|
||||
fatal("Unable to determine what interface to route packets through to %s", hs->hostbatch[hidx]->targetipstr());
|
||||
#endif
|
||||
error("WARNING: Could not determine what interface to route packets through to %s, changing ping scantype to ICMP ping only", hs->hostbatch[hidx]->targetipstr());
|
||||
*pingtype = PINGTYPE_ICMP_PING;
|
||||
}
|
||||
} else {
|
||||
Strncpy(hs->hostbatch[hidx]->device, device, 64);
|
||||
}
|
||||
hs->hostbatch[hidx]->setDeviceNames(rnfo.ii.devname, rnfo.ii.devfullname);
|
||||
// printf("Target %s %s directly connected, goes through local iface %s, which %s ethernet\n", hs->hostbatch[hidx]->NameIP(), hs->hostbatch[hidx]->directlyConnected()? "IS" : "IS NOT", hs->hostbatch[hidx]->deviceName(), (hs->hostbatch[hidx]->ifType() == devt_ethernet)? "IS" : "IS NOT");
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is an ARP scan, we must determine the device's MAC address */
|
||||
if (*pingtype & PINGTYPE_ARP) {
|
||||
setTargetSrcMACAddressFromDevName(hs->hostbatch[hidx]);
|
||||
}
|
||||
|
||||
/* In some cases, we can only allow hosts that use the same device
|
||||
in a group. */
|
||||
/* In some cases, we can only allow hosts that use the same
|
||||
device in a group. Similarly, we don't mix
|
||||
directly-connected boxes with those that aren't */
|
||||
if (o.af() == AF_INET && o.isr00t && hidx > 0 &&
|
||||
*hs->hostbatch[hidx]->device &&
|
||||
hs->hostbatch[hidx]->deviceName() &&
|
||||
(hs->hostbatch[hidx]->v4source().s_addr != hs->hostbatch[0]->v4source().s_addr ||
|
||||
strcmp(hs->hostbatch[0]->device, hs->hostbatch[hidx]->device) != 0)) {
|
||||
strcmp(hs->hostbatch[0]->deviceName(),
|
||||
hs->hostbatch[hidx]->deviceName()) != 0)
|
||||
|| hs->hostbatch[hidx]->directlyConnected() != hs->hostbatch[0]->directlyConnected()) {
|
||||
/* Cancel everything! This guy must go in the next group and we are
|
||||
outtof here */
|
||||
hs->current_expression.return_last_host();
|
||||
|
|
@ -403,23 +403,34 @@ if (hs->randomize) {
|
|||
hoststructfry(hs->hostbatch, hs->current_batch_sz);
|
||||
}
|
||||
|
||||
/* First I'll do the ARP ping if necessary */
|
||||
if (*pingtype & PINGTYPE_ARP) {
|
||||
/* First I'll do the ARP ping if all of the machines in the group are
|
||||
directly connected over ethernet. I may need the MAC addresses
|
||||
later anyway. */
|
||||
if (hs->hostbatch[0]->ifType() == devt_ethernet &&
|
||||
hs->hostbatch[0]->directlyConnected() &&
|
||||
o.sendpref != PACKET_SEND_IP_STRONG) {
|
||||
arpping(hs->hostbatch, hs->current_batch_sz, ports);
|
||||
}
|
||||
/* TODO: For efficiency, at some point it might be nice to usually do ARP
|
||||
ping before mass ping (and so get rid of else below) */
|
||||
/* Then we do the mass ping (if required - IP-level pings) */
|
||||
else if ((*pingtype &
|
||||
(PINGTYPE_ICMP_PING|PINGTYPE_ICMP_MASK|PINGTYPE_ICMP_TS) ) ||
|
||||
((!o.isr00t || o.af() == AF_INET6 || hs->hostbatch[0]->v4host().s_addr) &&
|
||||
(*pingtype != PINGTYPE_NONE)))
|
||||
massping(hs->hostbatch, hs->current_batch_sz, ports, *pingtype);
|
||||
/* Otherwise -P0 so we just consider every host up */
|
||||
else for(i=0; i < hs->current_batch_sz; i++) {
|
||||
initialize_timeout_info(&hs->hostbatch[i]->to);
|
||||
hs->hostbatch[i]->flags |= HOST_UP; /*hostbatch[i].up = 1;*/
|
||||
arpping_done = true;
|
||||
}
|
||||
|
||||
if ((o.sendpref & PACKET_SEND_ETH) &&
|
||||
hs->hostbatch[0]->ifType() == devt_ethernet) {
|
||||
if (!setTargetNextHopMAC(hs->hostbatch[hidx]))
|
||||
fatal("%s: Failed to determine dst MAC address for target %s",
|
||||
__FUNCTION__, hs->hostbatch[hidx]->NameIP());
|
||||
}
|
||||
|
||||
/* TODO: Maybe I should allow real ping scan of directly connected
|
||||
ethernet hosts? */
|
||||
/* Then we do the mass ping (if required - IP-level pings) */
|
||||
if (*pingtype == PINGTYPE_NONE) {
|
||||
for(i=0; i < hs->current_batch_sz; i++) {
|
||||
initialize_timeout_info(&hs->hostbatch[i]->to);
|
||||
hs->hostbatch[i]->flags |= HOST_UP; /*hostbatch[i].up = 1;*/
|
||||
}
|
||||
} else if (!arpping_done)
|
||||
massping(hs->hostbatch, hs->current_batch_sz, ports, *pingtype);
|
||||
|
||||
return hs->hostbatch[hs->next_batch_no++];
|
||||
}
|
||||
|
||||
|
|
@ -595,7 +606,7 @@ if (ptech.rawicmpscan || ptech.rawtcpscan || ptech.rawudpscan) {
|
|||
16 bytes of the TCP header
|
||||
---
|
||||
= 104 byte snaplen */
|
||||
pd = my_pcap_open_live(hostbatch[0]->device, 104, o.spoofsource, 20);
|
||||
pd = my_pcap_open_live(hostbatch[0]->deviceName(), 104, o.spoofsource, 20);
|
||||
|
||||
flt_dsthost = hostbatch[0]->v4source().s_addr;
|
||||
flt_baseport = sportbase;
|
||||
|
|
@ -606,7 +617,7 @@ if (ptech.rawicmpscan || ptech.rawtcpscan || ptech.rawudpscan) {
|
|||
sportbase , sportbase + 1, sportbase + 2, sportbase + 3,
|
||||
sportbase + 4);
|
||||
|
||||
set_pcap_filter(hostbatch[0], pd, flt_icmptcp_5port, filter);
|
||||
set_pcap_filter(hostbatch[0]->deviceName(), pd, flt_icmptcp_5port, filter);
|
||||
}
|
||||
|
||||
blockinc = (int) (0.9999 + 8.0 / probes_per_host);
|
||||
|
|
@ -840,7 +851,7 @@ else {
|
|||
|
||||
o.decoys[o.decoyturn].s_addr = target->v4source().s_addr;
|
||||
|
||||
send_udp_raw_decoys( rawsd, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, seq, o.extra_payload, o.extra_payload_length);
|
||||
send_udp_raw_decoys( rawsd, NULL, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, seq, o.extra_payload, o.extra_payload_length);
|
||||
|
||||
|
||||
return 0;
|
||||
|
|
@ -864,10 +875,10 @@ else {
|
|||
o.decoys[o.decoyturn].s_addr = target->v4source().s_addr;
|
||||
|
||||
if (pingtype & PINGTYPE_TCP_USE_SYN) {
|
||||
send_tcp_raw_decoys( rawsd, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_SYN, 0, NULL, 0, o.extra_payload,
|
||||
send_tcp_raw_decoys( rawsd, NULL, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_SYN, 0, NULL, 0, o.extra_payload,
|
||||
o.extra_payload_length);
|
||||
} else {
|
||||
send_tcp_raw_decoys( rawsd, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_ACK, 0, NULL, 0, o.extra_payload,
|
||||
send_tcp_raw_decoys( rawsd, NULL, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_ACK, 0, NULL, 0, o.extra_payload,
|
||||
o.extra_payload_length);
|
||||
}
|
||||
|
||||
|
|
@ -976,7 +987,7 @@ if (ptech.icmpscan) {
|
|||
fprintf(stderr, "sendto: %s\n", strerror(sock_err));
|
||||
}
|
||||
} else {
|
||||
send_ip_raw( rawsd, &o.decoys[decoy], target->v4hostip(), o.ttl, IPPROTO_ICMP, ping, icmplen);
|
||||
send_ip_raw( rawsd, NULL, &o.decoys[decoy], target->v4hostip(), o.ttl, IPPROTO_ICMP, ping, icmplen);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
152
tcpip.h
152
tcpip.h
|
|
@ -241,12 +241,17 @@ extern "C" {
|
|||
#include <setjmp.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <dnet.h>
|
||||
#include <netinet/ip_icmp.h>
|
||||
|
||||
typedef enum { devt_ethernet, devt_loopback, devt_p2p, devt_other } devtype;
|
||||
|
||||
#include "nmap_error.h"
|
||||
#include "utils.h"
|
||||
#include "nmap.h"
|
||||
#include "global_structures.h"
|
||||
|
||||
|
||||
#ifndef DEBUGGING
|
||||
#define DEBUGGING 0
|
||||
#endif
|
||||
|
|
@ -323,10 +328,46 @@ struct link_header {
|
|||
u8 header[MAX_LINK_HEADERSZ];
|
||||
};
|
||||
|
||||
/* Relevant (to Nmap) information about an interface */
|
||||
struct interface_info {
|
||||
char name[64];
|
||||
struct in_addr addr;
|
||||
struct in_addr netmask;
|
||||
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
|
||||
|
|
@ -522,26 +563,41 @@ int resolve(char *hostname, struct sockaddr_storage *ss, size_t *sslen,
|
|||
result in ip . returns 0 if hostname cannot
|
||||
be resolved */
|
||||
int resolve(char *hostname, struct in_addr *ip);
|
||||
/* An awesome function to determine what interface a packet to a given
|
||||
destination should be routed through. It returns NULL if no appropriate
|
||||
interface is found, oterwise it returns the device name and fills in the
|
||||
source parameter */
|
||||
char *routethrough(const struct in_addr * const dest, struct in_addr *source);
|
||||
|
||||
/* Takes a destination address (dst) and tries to determine the
|
||||
source address and interface necessary to route to this address.
|
||||
If no route is found, false is returned and rnfo is undefined. If
|
||||
a route is found, true is returned and rnfo is filled in with all
|
||||
of the routing details */
|
||||
bool 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
|
||||
any) for ethernet routing. If direct_connect is passed in, it will
|
||||
be set to 1 if dst is directly connected on the ifentry network and
|
||||
0 if it requires routing. If nexthop_ip is not NULL, and routing
|
||||
is required, the next hop is filled into nexthop_ip. This function
|
||||
returns false if no apporpiate interface or route was found and
|
||||
true if it succeeds. */
|
||||
bool routethrough(const struct sockaddr_storage * const dest,
|
||||
struct intf_entry *ifentry,
|
||||
int *direct_connect, struct sockaddr_storage *nexthop_ip);
|
||||
|
||||
unsigned short in_cksum(u16 *ptr,int nbytes);
|
||||
|
||||
/* Build and send a raw tcp packet. If TTL is -1, a partially random
|
||||
(but likely large enough) one is chosen */
|
||||
int send_tcp_raw( int sd, const struct in_addr *source,
|
||||
int send_tcp_raw( int sd, struct eth_nfo *eth, const struct in_addr *source,
|
||||
const struct in_addr *victim, int ttl,
|
||||
u16 sport, u16 dport, u32 seq, u32 ack, u8 flags,
|
||||
u16 window, u8 *options, int optlen, char *data,
|
||||
u16 datalen);
|
||||
int send_udp_raw( int sd, struct in_addr *source, const struct in_addr *victim,
|
||||
int ttl, u16 sport, u16 dport, u16 ipid, char *data,
|
||||
u16 datalen);
|
||||
int send_udp_raw( int sd, struct eth_nfo *eth, struct in_addr *source,
|
||||
const struct in_addr *victim, int ttl, u16 sport,
|
||||
u16 dport, u16 ipid, char *data, u16 datalen);
|
||||
|
||||
int send_ip_raw( int sd, struct in_addr *source, const struct in_addr *victim,
|
||||
int ttl, u8 proto, char *data, u16 datalen);
|
||||
int send_ip_raw( int sd, struct eth_nfo *eth, struct in_addr *source,
|
||||
const struct in_addr *victim, int ttl, u8 proto,
|
||||
char *data, u16 datalen);
|
||||
|
||||
/* Builds a TCP packet (including an IP header) by packing the fields
|
||||
with the given information. It allocates a new buffer to store the
|
||||
|
|
@ -586,26 +642,31 @@ u8 *build_ip_raw(const struct in_addr *source, const struct in_addr *victim,
|
|||
u32 *packetlen);
|
||||
|
||||
/* Send a pre-built IPv4 packet */
|
||||
int send_ip_packet(int sd, u8 *packet, unsigned int packetlen);
|
||||
int send_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
|
||||
unsigned int packetlen);
|
||||
|
||||
/* Create and send all fragments of the pre-built packet */
|
||||
/* mtu = MTU - ipv4_headerlen */
|
||||
int send_frag_ip_packet(int sd, u8 *packet, unsigned int packetlen, unsigned int mtu);
|
||||
int send_frag_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
|
||||
unsigned int packetlen, unsigned int mtu);
|
||||
|
||||
/* Decoy versions of the raw packet sending functions ... */
|
||||
int send_tcp_raw_decoys( int sd, const struct in_addr *victim, int ttl,
|
||||
int send_tcp_raw_decoys( int sd, struct eth_nfo *eth,
|
||||
const struct in_addr *victim, int ttl,
|
||||
u16 sport, u16 dport, u32 seq, u32 ack, u8 flags,
|
||||
u16 window, u8 *options, int optlen, char *data,
|
||||
u16 datalen);
|
||||
|
||||
int send_udp_raw_decoys( int sd, const struct in_addr *victim, int ttl,
|
||||
int send_udp_raw_decoys( int sd, struct eth_nfo *eth,
|
||||
const struct in_addr *victim, int ttl,
|
||||
u16 sport, u16 dport, u16 ipid, 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(char *device, int snaplen, int promisc, int to_ms);
|
||||
pcap_t *my_pcap_open_live(const char *device, int snaplen, int promisc,
|
||||
int to_ms);
|
||||
// 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.
|
||||
|
|
@ -633,13 +694,7 @@ struct interface_info *getinterfaces(int *howmany);
|
|||
/* Check whether an IP address appears to be directly connected to an
|
||||
interface on the computer (e.g. on the same ethernet network rather
|
||||
than having to route). Returns 1 if yes, -1 if maybe, 0 if not. */
|
||||
int IPisDirectlyConnected(struct sockaddr_storage *ss, size_t ss_len);
|
||||
void sethdrinclude(int sd);
|
||||
int getsourceip(struct in_addr *src, const struct in_addr * const dst);
|
||||
/* Get the source IP and interface name that a packet
|
||||
to dst should be sent to. Interface name is dynamically
|
||||
assigned and thus should be freed */
|
||||
char *getsourceif(struct in_addr *src, struct in_addr *dst);
|
||||
|
||||
/* Fill buf (up to buflen -- truncate if necessary but always
|
||||
terminate) with a short representation of the packet stats.
|
||||
|
|
@ -663,13 +718,14 @@ char *getFinalPacketStats(char *buf, int buflen);
|
|||
int setTargetMACIfAvailable(Target *target, struct link_header *linkhdr,
|
||||
struct ip *ip, int overwrite);
|
||||
|
||||
/* Finds MAC address of target->device and sets into target. Caches
|
||||
the results so that it will be really quick if you have many targets
|
||||
that send out with the same device, and you pass them roughly in
|
||||
order (only caches one). Returns -1 if cannot find the MAC address
|
||||
(often meaning this is localhost, or some other non-ethernet device.
|
||||
Returns 0 upon success. */
|
||||
int setTargetSrcMACAddressFromDevName(Target *target);
|
||||
/* This function ensures that the next hop MAC address for a target is
|
||||
filled in. This address is the target's own MAC if it is directly
|
||||
connected, and the next hop mac otherwise. Returns true if the
|
||||
address is set when the function ends, false if not. This function
|
||||
firt checks if it is already set, if not it tries the arp cache,
|
||||
and if that fails it sends an ARP request itself. This should be called
|
||||
after an ARP scan if many directly connected machines are involved. */
|
||||
bool setTargetNextHopMAC(Target *target);
|
||||
|
||||
int islocalhost(const struct in_addr * const addr);
|
||||
int unblock_socket(int sd);
|
||||
|
|
@ -690,6 +746,20 @@ int get_link_offset(char *device);
|
|||
lnkinfo->header will be filled with the appropriate values. */
|
||||
char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec,
|
||||
struct timeval *rcvdtime, struct link_header *linknfo);
|
||||
|
||||
/* A trivial functon that maintains a cache of IP to MAC Address
|
||||
entries. If the command is ARPCACHE_GEt, this func 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. If the command is ARPCACHE_SET, the function 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. true is always
|
||||
returned for the set command. */
|
||||
#define ARPCACHE_GET 1
|
||||
#define ARPCACHE_SET 2
|
||||
bool NmapArpCache(int command, struct sockaddr_storage *ss, u8 *mac);
|
||||
|
||||
|
||||
/* 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)
|
||||
|
|
@ -700,6 +770,15 @@ char *readip_pcap(pcap_t *pd, unsigned int *len, long to_usec,
|
|||
int read_arp_reply_pcap(pcap_t *pd, u8 *sendermac, struct in_addr *senderIP,
|
||||
long to_usec, struct timeval *rcvdtime);
|
||||
|
||||
/* 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. */
|
||||
bool doArp(const char *dev, u8 *srcmac, struct sockaddr_storage *srcip,
|
||||
struct sockaddr_storage *targetip, u8 *targetmac);
|
||||
|
||||
#ifndef HAVE_INET_ATON
|
||||
int inet_aton(register const char *, struct in_addr *);
|
||||
#endif
|
||||
|
|
@ -737,17 +816,10 @@ void broadcast_socket(int sd);
|
|||
did). */
|
||||
int recvtime(int sd, char *buf, int len, int seconds, int *timedout);
|
||||
|
||||
/* This attempts to calculate the round trip time (rtt) to a host by timing a
|
||||
connect() to a port which isn't listening. A better approach is to time a
|
||||
ping (since it is more likely to get through firewalls (note, this isn't
|
||||
always true nowadays --fyodor). This is now
|
||||
implemented in isup() for users who are root. */
|
||||
unsigned long calculate_sleep(struct in_addr target);
|
||||
|
||||
/* Sets a pcap filter function -- makes SOCK_RAW reads easier */
|
||||
#ifndef WINIP_H
|
||||
typedef int (*PFILTERFN)(const char *packet, unsigned int len); /* 1 to keep */
|
||||
void set_pcap_filter(Target *target, pcap_t *pd, PFILTERFN filter, char *bpf, ...);
|
||||
void set_pcap_filter(const char *device, pcap_t *pd, PFILTERFN filter, char *bpf, ...);
|
||||
#endif
|
||||
|
||||
/* Just accept everything ... TODO: Need a better approach than this flt_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue