diff --git a/CHANGELOG b/CHANGELOG
index b18760a3d..3d54b1a01 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,11 @@
# Nmap Changelog ($Id$); -*-text-*-
+Nmap 4.20SOC-ALPHA1
+
+o Integrated initial 2nd generation OS detection patch! The system is
+ documented at http://insecure.org/nmap/osdetect/ . Thanks to Zhao Lei
+ for helping with the coding and design.
+
o portlist.cc was refactored to remove some code duplication. Thanks
to Diman Todorov for the patch.
diff --git a/FingerPrintResults.cc b/FingerPrintResults.cc
index 000ded2bb..0be7b3e04 100644
--- a/FingerPrintResults.cc
+++ b/FingerPrintResults.cc
@@ -110,7 +110,8 @@ FingerPrintResults::FingerPrintResults() {
overall_results = OSSCAN_NOMATCHES;
memset(accuracy, 0, sizeof(accuracy));
isClassified = false;
- osscan_opentcpport = osscan_closedtcpport = -1;
+ osscan_opentcpport = osscan_closedtcpport = osscan_closedudpport = -1;
+ distance = -1;
memset(FPs, 0, sizeof(FPs));
numFPs = goodFP = 0;
}
@@ -139,7 +140,12 @@ bool FingerPrintResults::fingerprintSuitableForSubmission() {
if (o.scan_delay > 500) // This can screw up the sequence timing
return false;
- if (osscan_opentcpport < 0 || osscan_closedtcpport < 0 ) // then results won't be complete
+ if (osscan_opentcpport < 0 || osscan_closedtcpport < 0 || osscan_closedudpport < 0)
+ /* The results won't be complete */
+ return false;
+
+ if (distance > 5)
+ /* Too far away from us. */
return false;
return true;
diff --git a/FingerPrintResults.h b/FingerPrintResults.h
index e5db9866b..87897f574 100644
--- a/FingerPrintResults.h
+++ b/FingerPrintResults.h
@@ -137,10 +137,14 @@ class FingerPrintResults {
any perfect (accuracy 1.0) matches, only those will be returned */
const struct OS_Classification_Results *getOSClassification();
- int osscan_opentcpport; /* Open port used for scannig (if one found --
+ int osscan_opentcpport; /* Open TCP port used for scannig (if one found --
otherwise -1) */
- int osscan_closedtcpport; /* Closed port used for scannig (if one found --
+ int osscan_closedtcpport; /* Closed TCP port used for scannig (if one found --
otherwise -1) */
+ int osscan_closedudpport; /* Closed UDP port used for scannig (if one found --
+ otherwise -1) */
+ int distance; /* How "far" is this FP gotten from? */
+
FingerPrint *FPs[10]; /* Fingerprint data obtained from host */
int numFPs;
int goodFP;
diff --git a/Makefile.in b/Makefile.in
index 2bf650727..61da15b0b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1,4 +1,4 @@
-export NMAP_VERSION = 4.11
+export NMAP_VERSION = 4.20SOC-ALPHA1
NMAP_NAME= Nmap
NMAP_URL= http://www.insecure.org/nmap/
NMAP_PLATFORM=@host@
@@ -46,11 +46,11 @@ TARGET = nmap
TARGETNMAPFE=@TARGETNMAPFE@
INSTALLNMAPFE=@INSTALLNMAPFE@
-export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc output.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc @COMPAT_SRCS@
+export SRCS = main.cc nmap.cc targets.cc tcpip.cc nmap_error.cc utils.cc idle_scan.cc osscan.cc osscan2.cc output.cc scan_engine.cc timing.cc charpool.cc services.cc protocols.cc nmap_rpc.cc portlist.cc NmapOps.cc TargetGroup.cc Target.cc FingerPrintResults.cc service_scan.cc NmapOutputTable.cc MACLookup.cc nmap_tty.cc nmap_dns.cc @COMPAT_SRCS@
-export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h output.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h
+export HDRS = charpool.h FingerPrintResults.h global_structures.h idle_scan.h MACLookup.h nmap_amigaos.h nmap_dns.h nmap_error.h nmap.h NmapOps.h NmapOutputTable.h nmap_rpc.h nmap_tty.h nmap_winconfig.h osscan.h osscan2.h output.h portlist.h protocols.h scan_engine.h service_scan.h services.h TargetGroup.h Target.h targets.h tcpip.h timing.h utils.h
-OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o output.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o @COMPAT_OBJS@
+OBJS = main.o nmap.o targets.o tcpip.o nmap_error.o utils.o idle_scan.o osscan.o osscan2.o output.o scan_engine.o timing.o charpool.o services.o protocols.o nmap_rpc.o portlist.o NmapOps.o TargetGroup.o Target.o FingerPrintResults.o service_scan.o NmapOutputTable.o MACLookup.o nmap_tty.o nmap_dns.o @COMPAT_OBJS@
# %.o : %.cc -- nope this is a GNU extension
.cc.o:
diff --git a/NmapOps.cc b/NmapOps.cc
index 1708d7bf7..bc12f9d61 100644
--- a/NmapOps.cc
+++ b/NmapOps.cc
@@ -194,6 +194,7 @@ void NmapOps::Initialize() {
interactivemode = 0;
ping_group_sz = PING_GROUP_SZ;
generate_random_ips = 0;
+ reference_FPs1 = NULL;
reference_FPs = NULL;
magic_port = 33000 + (get_random_uint() % 31000);
magic_port_set = 0;
diff --git a/NmapOps.h b/NmapOps.h
index 1340c7cee..694ab0a9d 100644
--- a/NmapOps.h
+++ b/NmapOps.h
@@ -174,7 +174,8 @@ class NmapOps {
int interactivemode;
int ping_group_sz;
int generate_random_ips; /* -iR option */
- FingerPrint **reference_FPs;
+ FingerPrint **reference_FPs1; /* Used in the old OS scan system. */
+ FingerPrint **reference_FPs; /* Used in the new OS scan system. */
u16 magic_port;
unsigned short magic_port_set; /* Was this set by user? */
int num_ping_synprobes;
diff --git a/Target.cc b/Target.cc
index 23d6e7426..a934a540c 100644
--- a/Target.cc
+++ b/Target.cc
@@ -120,6 +120,8 @@ Target::Target() {
void Target::Initialize() {
hostname = NULL;
memset(&seq, 0, sizeof(seq));
+ distance = -1;
+ FPR1 = NULL;
FPR = NULL;
osscan_performed = 0;
wierd_responses = flags = 0;
@@ -161,8 +163,8 @@ void Target::FreeInternal() {
nameIPBuf = NULL;
}
+ if (FPR1) delete FPR1;
if (FPR) delete FPR;
-
}
/* Creates a "presentation" formatted string out of the IPv4/IPv6 address.
diff --git a/Target.h b/Target.h
index 668e236d5..e4eea2d0c 100644
--- a/Target.h
+++ b/Target.h
@@ -215,7 +215,9 @@ class Target {
const char *deviceFullName() { return *devfullname? devfullname : NULL; }
struct seq_info seq;
- FingerPrintResults *FPR;
+ int distance;
+ FingerPrintResults *FPR1; /* FP results get by the old OS scan system. */
+ FingerPrintResults *FPR; /* FP results get by the new OS scan system. */
int osscan_performed; /* nonzero if an osscan was performed */
PortList ports;
/*
diff --git a/docs/nmap.xsl b/docs/nmap.xsl
index d117dea65..93f61fddc 100644
--- a/docs/nmap.xsl
+++ b/docs/nmap.xsl
@@ -605,6 +605,16 @@
+
+
+
+network distance
+
+
+
+
diff --git a/global_structures.h b/global_structures.h
index 8fd28fece..751ba708c 100644
--- a/global_structures.h
+++ b/global_structures.h
@@ -216,6 +216,12 @@ struct seq_info {
time_t lastboot; /* 0 means unknown */
};
+/* Different kinds of Ipids. */
+struct ipid_info {
+ int tcp_ipids[NUM_SEQ_SAMPLES];
+ int icmp_ipids[NUM_SEQ_SAMPLES];
+};
+
/* The various kinds of port/protocol scans we can have
* Each element is to point to an array of port/protocol numbers
*/
diff --git a/idle_scan.cc b/idle_scan.cc
index e5b0a85a8..1b7b7a326 100644
--- a/idle_scan.cc
+++ b/idle_scan.cc
@@ -187,10 +187,10 @@ static int ipid_proxy_probe(struct idle_proxy_info *proxy, int *probes_sent,
/* Time to send the pr0be!*/
send_tcp_raw(proxy->rawsd, proxy->ethptr, proxy->host.v4sourceip(),
- proxy->host.v4hostip(), o.ttl, base_port + tries,
+ proxy->host.v4hostip(), o.ttl, false, base_port + tries,
proxy->probe_port,
- seq_base + (packet_send_count++ * 500) + 1, ack,
- TH_SYN|TH_ACK, 0,
+ seq_base + (packet_send_count++ * 500) + 1, ack, 0,
+ TH_SYN|TH_ACK, 0, 0,
(u8 *) "\x02\x04\x05\xb4", 4, NULL, 0);
sent++;
tries++;
@@ -417,10 +417,10 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
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->ethptr, proxy->host.v4sourceip(),
- proxy->host.v4hostip(), o.ttl,
+ proxy->host.v4hostip(), o.ttl, false,
o.magic_port + probes_sent + 1, proxy->probe_port,
- sequence_base + probes_sent + 1, ack, TH_SYN|TH_ACK,
- 0, (u8 *) "\x02\x04\x05\xb4", 4, NULL, 0);
+ sequence_base + probes_sent + 1, ack, 0, TH_SYN|TH_ACK,
+ 0, 0, (u8 *) "\x02\x04\x05\xb4", 4, NULL, 0);
gettimeofday(&probe_send_times[probes_sent], NULL);
probes_sent++;
@@ -525,9 +525,9 @@ static void initialize_idleproxy(struct idle_proxy_info *proxy, char *proxyName,
if (probes_sent) usleep(50000);
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, (u8 *) "\x02\x04\x05\xb4", 4, NULL, 0);
+ o.ttl, false,o.magic_port, proxy->probe_port,
+ sequence_base + probes_sent + 1, ack, 0, TH_SYN|TH_ACK,
+ 0, 0, (u8 *) "\x02\x04\x05\xb4", 4, NULL, 0);
}
@@ -682,7 +682,7 @@ static int idlescan_countopen2(struct idle_proxy_info *proxy,
about this more. */
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,
+ o.ttl, false, proxy->probe_port, ports[pr0be], seq, 0, 0, TH_SYN, 0, 0,
(u8 *) "\x02\x04\x05\xb4", 4, o.extra_payload, o.extra_payload_length);
}
gettimeofday(&end, NULL);
diff --git a/nmap.cc b/nmap.cc
index bf4fb85e5..16daad32b 100644
--- a/nmap.cc
+++ b/nmap.cc
@@ -102,6 +102,7 @@
#include "nmap.h"
#include "osscan.h"
+#include "osscan2.h"
#include "scan_engine.h"
#include "idle_scan.h"
#include "timing.h"
@@ -594,7 +595,7 @@ int nmap_main(int argc, char *argv[]) {
/* OK, lets parse these args! */
optind = 1; /* so it can be called multiple times */
- while((arg = getopt_long_only(argc,fakeargv,"6Ab:D:d::e:Ffg:hIi:M:m:nOo:P:p:qRrS:s:T:Vv", long_options, &option_index)) != EOF) {
+ while((arg = getopt_long_only(argc,fakeargv,"6Ab:D:d::e:Ffg:hIi:M:m:nO::o:P:p:qRrS:s:T:Vv", long_options, &option_index)) != EOF) {
switch(arg) {
case 0:
if (optcmp(long_options[option_index].name, "max-rtt-timeout") == 0) {
@@ -797,7 +798,7 @@ int nmap_main(int argc, char *argv[]) {
case 'A':
o.servicescan = true;
if (o.isr00t)
- o.osscan++;
+ o.osscan = OS_SCAN_DEFAULT;
break;
case 'b':
o.bouncescan++;
@@ -876,7 +877,15 @@ int nmap_main(int argc, char *argv[]) {
break;
case 'n': o.noresolve++; break;
case 'O':
- o.osscan++;
+ if (!optarg)
+ o.osscan = OS_SCAN_DEFAULT;
+ else if (*optarg == '1')
+ o.osscan = OS_SCAN_SYS_1_ONLY;
+ else if (*optarg == '2')
+ o.osscan = OS_SCAN_SYS_2_ONLY;
+ else {
+ fatal("Use -O for new osscan engine, -O1 for old osscan engine.");
+ }
break;
case 'o':
normalfilename = optarg;
@@ -1076,8 +1085,10 @@ int nmap_main(int argc, char *argv[]) {
if (pre_host_timeout != -1) o.host_timeout = pre_host_timeout;
- if (o.osscan)
- o.reference_FPs = parse_fingerprint_reference_file();
+ if (o.osscan == OS_SCAN_SYS_1_ONLY)
+ o.reference_FPs1 = parse_fingerprint_reference_file("nmap-os-fingerprints");
+ else
+ o.reference_FPs = parse_fingerprint_reference_file("nmap-os-db");
o.ValidateOptions();
@@ -1548,6 +1559,9 @@ int nmap_main(int argc, char *argv[]) {
service_scan(Targets);
}
+ if (o.osscan != OS_SCAN_SYS_1_ONLY)
+ os_scan_2(Targets);
+
for(targetno = 0; targetno < Targets.size(); targetno++) {
currenths = Targets[targetno];
@@ -1558,7 +1572,7 @@ int nmap_main(int argc, char *argv[]) {
if (o.servicescan || o.rpcscan) pos_scan(currenths, NULL, 0, RPC_SCAN);
// Should be host parallelized. Though rarely takes a huge amt. of time.
- if (o.osscan) {
+ if (o.osscan == OS_SCAN_SYS_1_ONLY) {
os_scan(currenths);
}
@@ -1980,6 +1994,10 @@ char *ipidclass2ascii(int seqclass) {
return "Random positive increments";
case IPID_SEQ_ZERO:
return "All zeros";
+ case IPID_SEQ_LINUX:
+ return "Linux way";
+ case IPID_SEQ_VBP:
+ return "Different counters by ";
case IPID_SEQ_UNKNOWN:
return "Busy server or unknown class";
default:
diff --git a/nmap.h b/nmap.h
index d1e23cd03..a39912049 100644
--- a/nmap.h
+++ b/nmap.h
@@ -275,8 +275,6 @@ void *realloc();
/* If reads of a UDP port keep returning EAGAIN (errno 13), do we want to
count the port as valid? */
#define RISKY_UDP_SCAN 0
-/* How many syn packets do we send to TCP sequence a host? */
-#define NUM_SEQ_SAMPLES 6
/* This ideally should be a port that isn't in use for any protocol on our machine or on the target */
#define MAGIC_PORT 49724
/* How many udp sends without a ICMP port unreachable error does it take before we consider the port open? */
@@ -366,6 +364,19 @@ void *realloc();
#define PINGTYPE_ARP 1024
#define DEFAULT_PING_TYPES PINGTYPE_TCP|PINGTYPE_TCP_USE_ACK|PINGTYPE_ICMP_PING
+
+/* OS scan */
+#define OS_SCAN_DEFAULT 9
+#define OS_SCAN_SYS_1_ONLY 1
+#define OS_SCAN_SYS_2_ONLY 2
+
+/* How many syn packets do we send to TCP sequence a host? */
+#define NUM_SEQ_SAMPLES 6
+
+/* The max length of each line of the subject fingerprint when
+ wrapped. */
+#define FP_RESULT_WRAP_LINE_LEN 74
+
/* TCP/IP ISN sequence prediction classes */
#define SEQ_UNKNOWN 0
#define SEQ_64K 1
@@ -381,7 +392,8 @@ void *realloc();
#define TS_SEQ_2HZ 2
#define TS_SEQ_100HZ 3
#define TS_SEQ_1000HZ 4
-#define TS_SEQ_UNSUPPORTED 5 /* System didn't send back a timestamp */
+#define TS_SEQ_OTHER_NUM 5
+#define TS_SEQ_UNSUPPORTED 6 /* System didn't send back a timestamp */
#define IPID_SEQ_UNKNOWN 0
#define IPID_SEQ_INCR 1 /* simple increment by one each time */
@@ -392,6 +404,14 @@ void *realloc();
#define IPID_SEQ_RD 4 /* Appears to select IPID using a "random" distributions (meaning it can go up or down) */
#define IPID_SEQ_CONSTANT 5 /* Contains 1 or more sequential duplicates */
#define IPID_SEQ_ZERO 6 /* Every packet that comes back has an IP.ID of 0 (eg Linux 2.4 does this) */
+#define IPID_SEQ_LINUX 7 /* Different IPID counter in different TCP
+ session but set zero in the TCP
+ negotiation process. And different IPID
+ counter in different protocol. Found in
+ linux 2.6. */
+#define IPID_SEQ_VBP 8 /* Different IPID counter for different triple. */
+
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
diff --git a/nmap_winconfig.h b/nmap_winconfig.h
index 785781ea3..d3f945d28 100644
--- a/nmap_winconfig.h
+++ b/nmap_winconfig.h
@@ -106,7 +106,7 @@
/* Without this, Windows will give us all sorts of crap about using functions
like strcpy() even if they are done safely */
#define _CRT_SECURE_NO_DEPRECATE 1
-#define NMAP_VERSION "4.11"
+#define NMAP_VERSION "4.20SOC-ALPHA1"
#define NMAP_NAME "Nmap"
#define NMAP_URL "http://www.insecure.org/nmap"
#define NMAP_PLATFORM "i686-pc-windows-windows"
diff --git a/osscan.cc b/osscan.cc
index 679c7fa0d..61c7245af 100644
--- a/osscan.cc
+++ b/osscan.cc
@@ -578,18 +578,19 @@ static FingerPrint *get_fingerprint(Target *target, struct seq_info *si) {
/* Lets find an open port to use */
openport = (unsigned long) -1;
- target->FPR->osscan_opentcpport = -1;
- target->FPR->osscan_closedtcpport = -1;
+ target->FPR1->osscan_opentcpport = -1;
+ target->FPR1->osscan_closedtcpport = -1;
+ target->FPR1->osscan_closedudpport = -1;
tport = NULL;
if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_OPEN))) {
openport = tport->portno;
- target->FPR->osscan_opentcpport = tport->portno;
+ target->FPR1->osscan_opentcpport = tport->portno;
}
/* Now we should find a closed port */
if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_CLOSED))) {
closedport = tport->portno;
- target->FPR->osscan_closedtcpport = tport->portno;
+ target->FPR1->osscan_closedtcpport = tport->portno;
} else if ((tport = target->ports.nextPort(NULL, IPPROTO_TCP, PORT_UNFILTERED))) {
/* Well, we will settle for unfiltered */
closedport = tport->portno;
@@ -612,57 +613,58 @@ static FingerPrint *get_fingerprint(Target *target, struct seq_info *si) {
/* Test 1 */
if (!FPtests[1]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port, openport, sequence_base, 0, 0,
+ TH_ECE|TH_SYN, 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 2 */
if (!FPtests[2]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +1, openport, sequence_base, 0, 0,
+ 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, 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +2, openport, sequence_base, 0, 0,
+ TH_SYN|TH_FIN|TH_URG|TH_PUSH, 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 4 */
if (!FPtests[4]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +3, openport, sequence_base, 0, 0,
+ TH_ACK, 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 5 */
if (!FPtests[5]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +4, closedport, sequence_base, 0, 0,
+ TH_SYN, 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 6 */
if (!FPtests[6]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +5, closedport, sequence_base, 0, 0,
+ TH_ACK, 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 7 */
if (!FPtests[7]) {
if (o.scan_delay) enforce_scan_delay(NULL);
- 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);
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
+ current_port +6, closedport, sequence_base, 0, 0,
+ TH_FIN|TH_PUSH|TH_URG, 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 8 */
@@ -747,11 +749,11 @@ static FingerPrint *get_fingerprint(Target *target, struct seq_info *si) {
usleep(remaining_us);
}
}
- send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl,
+ send_tcp_raw_decoys(rawsd, ethptr, target->v4hostip(), o.ttl, false,
o.magic_port + seq_packets_sent + 1,
openport,
- sequence_base + seq_packets_sent + 1, 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);
+ sequence_base + seq_packets_sent + 1, 0, 0,
+ TH_SYN, 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);
gettimeofday(&seq_send_times[seq_packets_sent], NULL);
t1 = seq_send_times[seq_packets_sent];
seq_packets_sent++;
@@ -1183,9 +1185,9 @@ static struct AVal *gettestbyname(FingerPrint *FP, const char *name) {
static int AVal_match(struct AVal *reference, struct AVal *fprint, unsigned long *num_subtests, unsigned long *num_subtests_succeeded, int shortcut) {
struct AVal *current_ref;
struct AVal *current_fp;
- unsigned int number;
+ unsigned int number, number1;
unsigned int val;
- char *p, *q; /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
+ char *p, *q, *q1; /* OHHHH YEEEAAAAAHHHH!#!@#$!% */
char valcpy[512];
char *endptr;
int andexp, orexp, expchar, numtrue;
@@ -1196,9 +1198,9 @@ static int AVal_match(struct AVal *reference, struct AVal *fprint, unsigned long
current_fp = getattrbyname(fprint, current_ref->attribute);
if (!current_fp) continue;
/* OK, we compare an attribute value in current_fp->value to a
- potentially large expression in current_ref->value. The syntax uses
- < (less than), > (greather than), + (non-zero), | (or), and & (and)
- No parenthesis are allowed and an expression cannot have | AND & */
+ potentially large expression in current_ref->value. The syntax
+ uses < (less than), > (greather than), + (non-zero), | (or), -
+ (range), and & (and). No parenthesis are allowed */
numtrue = andexp = orexp = 0; testfailed = 0;
Strncpy(valcpy, current_ref->value, sizeof(valcpy));
p = valcpy;
@@ -1229,8 +1231,17 @@ static int AVal_match(struct AVal *reference, struct AVal *fprint, unsigned long
val = strtol(current_fp->value, &endptr, 16);
if (val <= number || *endptr) { if (andexp) { testfailed=1; break; } }
else { numtrue++; if (orexp) break; }
+ } else if (((q1 = strchr(p, '-')) != NULL) && isxdigit((int) p[0]) && isxdigit((int) q1[1])) {
+ if (!*current_fp->value) { if (andexp) { testfailed=1; break; } }
+ *q1 = '\0'; number = strtol(p, NULL, 16);
+ number1 = strtol(q1 + 1, NULL, 16);
+ if(number1 < number && o.debugging) {
+ error("Range error in reference aval: %s=%s\n", current_ref->attribute, current_ref->value);
}
- else {
+ val = strtol(current_fp->value, &endptr, 16);
+ if (val < number || val > number1 || *endptr) { if (andexp) { testfailed=1; break; } }
+ else { numtrue++; if (orexp) break; }
+ } else {
if (strcmp(p, current_fp->value))
{ if (andexp) { testfailed=1; break; } }
else { numtrue++; if (orexp) break; }
@@ -1322,7 +1333,7 @@ void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
acc = compare_fingerprints(current_os, FP, 0);
- /* error("Comp to %s: %li/%li=%f", o.reference_FPs[i]->OS_name, num_subtests_succeeded, num_subtests, acc); */
+ /* error("Comp to %s: %li/%li=%f", o.reference_FPs1[i]->OS_name, num_subtests_succeeded, num_subtests, acc); */
if (acc >= FPR_entrance_requirement || acc == 1.0) {
state = 0;
@@ -1441,8 +1452,8 @@ o.current_scantype = OS_SCAN;
log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Initiating OS Detection against %s at %.3fs\n", target->targetipstr(), starttimems / 1000.0);
}
- if (target->FPR == NULL)
- target->FPR = new FingerPrintResults;
+ if (target->FPR1 == NULL)
+ target->FPR1 = new FingerPrintResults;
memset(si, 0, sizeof(si));
if (target->ports.getStateCounts(IPPROTO_TCP, PORT_OPEN) == 0 ||
@@ -1467,10 +1478,10 @@ o.current_scantype = OS_SCAN;
// Do nothing because the keyWasPressed Method prints out the basic status line
}
- target->FPR->FPs[itry] = get_fingerprint(target, &si[itry]);
+ target->FPR1->FPs[itry] = get_fingerprint(target, &si[itry]);
- match_fingerprint(target->FPR->FPs[itry], &FP_matches[itry],
- o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
+ match_fingerprint(target->FPR1->FPs[itry], &FP_matches[itry],
+ o.reference_FPs1, OSSCAN_GUESS_THRESHOLD);
if (FP_matches[itry].overall_results == OSSCAN_SUCCESS &&
FP_matches[itry].num_perfect_matches > 0)
break;
@@ -1478,13 +1489,13 @@ o.current_scantype = OS_SCAN;
sleep(2);
}
- target->FPR->numFPs = (itry == 3)? 3 : itry + 1;
- memcpy(&(target->seq), &si[target->FPR->numFPs - 1], sizeof(struct seq_info));
+ target->FPR1->numFPs = (itry == 3)? 3 : itry + 1;
+ memcpy(&(target->seq), &si[target->FPR1->numFPs - 1], sizeof(struct seq_info));
/* Now lets find the best match */
bestacc = 0;
bestaccidx = 0;
- for(itry=0; itry < target->FPR->numFPs; itry++) {
+ for(itry=0; itry < target->FPR1->numFPs; itry++) {
if (FP_matches[itry].overall_results == OSSCAN_SUCCESS &&
FP_matches[itry].num_matches > 0 &&
FP_matches[itry].accuracy[0] > bestacc) {
@@ -1496,27 +1507,27 @@ o.current_scantype = OS_SCAN;
}
- for(i=0; i < target->FPR->numFPs; i++) {
+ for(i=0; i < target->FPR1->numFPs; i++) {
if (i == bestaccidx)
continue;
if (o.debugging) {
- error("Failed exact match #%d (0-based):\n%s", i, fp2ascii(target->FPR->FPs[i]));
+ error("Failed exact match #%d (0-based):\n%s", i, fp2ascii(target->FPR1->FPs[i]));
}
}
- if (target->FPR->numFPs > 1 && target->FPR->overall_results == OSSCAN_SUCCESS &&
- target->FPR->accuracy[0] == 1.0) {
- if (o.verbose) error("WARNING: OS didn't match until the try #%d", target->FPR->numFPs);
+ if (target->FPR1->numFPs > 1 && target->FPR1->overall_results == OSSCAN_SUCCESS &&
+ target->FPR1->accuracy[0] == 1.0) {
+ if (o.verbose) error("WARNING: OS didn't match until the try #%d", target->FPR1->numFPs);
}
- target->FPR->goodFP = bestaccidx;
+ target->FPR1->goodFP = bestaccidx;
- // Now we redo the match, since target->FPR has various data (such as
- // target->FPR->numFPs) which is not in FP_matches[bestaccidx]. This is
+ // Now we redo the match, since target->FPR1 has various data (such as
+ // target->FPR1->numFPs) which is not in FP_matches[bestaccidx]. This is
// kinda ugly.
- if (target->FPR->goodFP >= 0)
- match_fingerprint(target->FPR->FPs[target->FPR->goodFP], target->FPR,
- o.reference_FPs, OSSCAN_GUESS_THRESHOLD);
+ if (target->FPR1->goodFP >= 0)
+ match_fingerprint(target->FPR1->FPs[target->FPR1->goodFP], target->FPR1,
+ o.reference_FPs1, OSSCAN_GUESS_THRESHOLD);
if (o.debugging > 2) {
log_write(LOG_STDOUT|LOG_NORMAL|LOG_SKID, "Completed OS Detection against %s at %.3fs (took %.3fs)\n", target->targetipstr(), o.TimeSinceStartMS() / 1000.0, (o.TimeSinceStartMS() - starttimems) / 1000.0);
@@ -1529,34 +1540,55 @@ o.current_scantype = OS_SCAN;
top of a fingerprint. Gives info which might be useful when the
FPrint is submitted (eg Nmap version, etc). Result is written (up
to ostrlen) to the ostr var passed in */
-static void WriteSInfo(char *ostr, int ostrlen, int openport, int closedport,
- const u8 *mac) {
+static void WriteSInfo(char *ostr, int ostrlen, bool isGoodFP,
+ const struct in_addr * const addr, int distance, const u8 *mac,
+ int openTcpPort, int closedTcpPort, int closedUdpPort) {
struct tm *ltime;
time_t timep;
+ char dsbuf[8], otbuf[8], ctbuf[8], cubuf[8];
char macbuf[16];
timep = time(NULL);
ltime = localtime(&timep);
+ otbuf[0] = '\0';
+ if(openTcpPort != -1)
+ snprintf(otbuf, sizeof(otbuf), "%d", openTcpPort);
+ ctbuf[0] = '\0';
+ if(closedTcpPort != -1)
+ snprintf(ctbuf, sizeof(ctbuf), "%d", closedTcpPort);
+ cubuf[0] = '\0';
+ if(closedUdpPort != -1)
+ snprintf(cubuf, sizeof(cubuf), "%d", closedUdpPort);
+
+ dsbuf[0] = '\0';
+ if(distance != -1) {
+ snprintf(dsbuf, sizeof(dsbuf), "%%DS=%d", distance);
+ }
+
macbuf[0] = '\0';
if (mac)
- snprintf(macbuf, sizeof(macbuf), "%%M=%02X%02X%02X", mac[0], mac[1],
- mac[2]);
+ snprintf(macbuf, sizeof(macbuf), "%%M=%02X%02X%02X", mac[0], mac[1], mac[2]);
- snprintf(ostr, ostrlen, "SInfo(V=%s%%P=%s%%D=%d/%d%%Tm=%X%%O=%d%%C=%d%s)\n",
- NMAP_VERSION, NMAP_PLATFORM, ltime->tm_mon + 1, ltime->tm_mday,
- (int) timep, openport, closedport, macbuf);
+ snprintf(ostr, ostrlen, "SCAN(V=%s%%D=%d/%d%%OT=%s%%CT=%s%%CU=%s%%PV=%c%s%%G=%c%s%%TM=%X%%P=%s)",
+ NMAP_VERSION, ltime->tm_mon + 1, ltime->tm_mday,
+ otbuf, ctbuf, cubuf, isipprivate(addr)?'Y':'N', dsbuf, isGoodFP?'Y':'N',
+ macbuf, (int) timep, NMAP_PLATFORM);
}
-char *mergeFPs(FingerPrint *FPs[], int numFPs, int openport, int closedport,
- const u8 *mac) {
+char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP,
+ const struct in_addr * const addr, int distance, const u8 *mac,
+ int openTcpPort, int closedTcpPort, int closedUdpPort, bool wrapit) {
static char str[10240];
+ static char wrapstr[10240];
+
struct AVal *AV;
FingerPrint *currentFPs[32];
char *p = str;
int i;
int changed;
char *end = str + sizeof(str) - 1; /* Last byte allowed to write into */
+
if (numFPs <=0) return "(None)";
if (numFPs > 32) return "(Too many)";
@@ -1568,9 +1600,10 @@ for(i=0; i < numFPs; i++) {
currentFPs[i] = FPs[i];
}
-/* Lets start by writing the fake "Info" test for submitting fingerprints */
- WriteSInfo(str, sizeof(str), openport, closedport, mac);
+ /* Lets start by writing the fake "SCAN" test for submitting fingerprints */
+ WriteSInfo(str, sizeof(str), isGoodFP, addr, distance, mac, openTcpPort, closedTcpPort, closedUdpPort);
p = p + strlen(str);
+ if (!wrapit) *p++ = '\n';
do {
changed = 0;
@@ -1599,6 +1632,8 @@ do {
if(*(p-1) != '(')
p--; /* Kill the final & */
*p++ = ')';
+
+ if(!wrapit)
*p++ = '\n';
}
/* Now prepare for the next one */
@@ -1608,9 +1643,34 @@ do {
} while(changed);
*p = '\0';
-return str;
-}
+ if(!wrapit) {
+return str;
+ } else {
+ /* Wrap the str. */
+ int len;
+ char *p1 = wrapstr;
+ end = wrapstr + sizeof(wrapstr) - 1;
+
+ p = str;
+
+ while(*p && end-p1 >= 3) {
+ len = 0;
+ strcpy(p1, "OS:"); p1 += 3; len +=3;
+ while(*p && len <= FP_RESULT_WRAP_LINE_LEN && end-p1 > 0) {
+ *p1++=*p++; len++;
+ }
+ if(end-p1<=0) {
+ fatal("Wrapped result too long!\n");
+ break;
+ }
+ *p1++ = '\n';
+}
+ *p1 = '\0';
+
+ return wrapstr;
+ }
+}
char *fp2ascii(FingerPrint *FP) {
static char str[2048];
@@ -1953,18 +2013,17 @@ while(fgets(line, sizeof(line), fp)) {
/* printf("Read in fingerprint:\n%s\n", fp2ascii(FPs[numrecords])); */
numrecords++;
if (numrecords >= max_records)
- fatal("Too many OS fingerprints -- 0verfl0w");
+ fatal("Too many OS fingerprints -- 0verflow");
}
fclose(fp);
FPs[numrecords] = NULL;
return FPs;
}
-FingerPrint **parse_fingerprint_reference_file() {
+FingerPrint **parse_fingerprint_reference_file(char *dbname) {
char filename[256];
-
-if (nmap_fetchfile(filename, sizeof(filename), "nmap-os-fingerprints") == -1){
- fatal("OS scan requested but I cannot find nmap-os-fingerprints file. It should be in %s, ~/.nmap/ or .", NMAPDATADIR);
+if (nmap_fetchfile(filename, sizeof(filename), dbname) == -1){
+ fatal("OS scan requested but I cannot find %s file. It should be in %s, ~/.nmap/ or .", dbname, NMAPDATADIR);
}
return parse_fingerprint_file(filename);
diff --git a/osscan.h b/osscan.h
index 06164e6a2..6c159a843 100644
--- a/osscan.h
+++ b/osscan.h
@@ -129,7 +129,7 @@ char *fp2ascii(FingerPrint *FP);
which some partial fingerpritns are OK. */
FingerPrint *parse_single_fingerprint(char *fprint_orig);
FingerPrint **parse_fingerprint_file(char *fname);
-FingerPrint **parse_fingerprint_reference_file();
+FingerPrint **parse_fingerprint_reference_file(char *dbname);
/* Compares 2 fingerprints -- a referenceFP (can have expression
attributes) with an observed fingerprint (no expressions). If
@@ -150,8 +150,7 @@ void match_fingerprint(FingerPrint *FP, FingerPrintResults *FPR,
/* Returns true if perfect match -- if num_subtests & num_subtests_succeeded are non_null it updates them. if shortcircuit is zero, it does all the tests, otherwise it returns when the first one fails */
void freeFingerPrint(FingerPrint *FP);
-char *mergeFPs(FingerPrint *FPs[], int numFPs, int openport, int closedport,
- const u8 *mac);
+char *mergeFPs(FingerPrint *FPs[], int numFPs, bool isGoodFP, const struct in_addr * const addr, int distance, const u8 *mac, int openTcpPort, int closedTcpPort, int closedUdpPort, bool wrapit);
/* This function takes an array of "numSamples" IP IDs and analyzes
them to determine their sequenceability classification. It returns
diff --git a/output.cc b/output.cc
index 73fc55c54..269ef0e7b 100644
--- a/output.cc
+++ b/output.cc
@@ -1208,120 +1208,184 @@ void printmacinfo(Target *currenths) {
+
/* Prints the formatted OS Scan output to stdout, logfiles, etc (but only
- if an OS Scan was performed */
+ if an OS Scan was performed).*/
void printosscanoutput(Target *currenths) {
int i;
char numlst[512]; /* For creating lists of numbers */
char *p; /* Used in manipulating numlst above */
+ FingerPrintResults *FPR;
+ int distance = -1;
+ bool wrapFP = true; /* Whether to wrap the fingerprint result. */
+
+ if (!currenths->osscan_performed)
+ return;
+
+ if (currenths->FPR == NULL && currenths->FPR1 == NULL) {
+ return;
+ } else if (currenths->FPR != NULL && currenths->FPR1 == NULL) {
+ FPR = currenths->FPR;
+ } else if (currenths->FPR == NULL && currenths->FPR1 != NULL) {
+ FPR = currenths->FPR1;
+ wrapFP = false;
+ }
+ else {
+ /* Neither is NULL. This happens when new OS scan system fails to
+ get a perfect match and falls back on the old OS scan
+ system. */
+ if (currenths->FPR->num_perfect_matches > 0) {
+ FPR = currenths->FPR; /* Just an ensurance. */
+ } else if (currenths->FPR1->num_perfect_matches > 0) {
+ FPR = currenths->FPR1;
+ wrapFP = false;
+ } else if (currenths->FPR->overall_results == OSSCAN_SUCCESS) {
+ FPR = currenths->FPR;
+ } else if (currenths->FPR1->overall_results == OSSCAN_SUCCESS) {
+ FPR = currenths->FPR1;
+ wrapFP = false;
+ } else {
+ /* Both fails. */
+ FPR = currenths->FPR;
+ }
+ }
+
+ if (islocalhost(currenths->v4hostip())) {
+ /* scanning localhost */
+ distance = 0;
+ } else if (currenths->MACAddress()) {
+ /* on the same network segment */
+ distance = 1;
+ } else if (currenths->distance!=-1) {
+ distance = currenths->distance;
+ }
- if (currenths->osscan_performed && currenths->FPR != NULL) {
log_write(LOG_XML, "");
- if (currenths->FPR->osscan_opentcpport > 0) {
+ if (FPR->osscan_opentcpport > 0) {
log_write(LOG_XML,
"\n",
- currenths->FPR->osscan_opentcpport);
+ FPR->osscan_opentcpport);
}
- if (currenths->FPR->osscan_closedtcpport > 0) {
+ if (FPR->osscan_closedtcpport > 0) {
log_write(LOG_XML,
"\n",
- currenths->FPR->osscan_closedtcpport);
+ FPR->osscan_closedtcpport);
+ }
+ if (FPR->osscan_closedudpport > 0) {
+ log_write(LOG_XML,
+ "\n",
+ FPR->osscan_closedudpport);
}
// If the FP can't be submitted anyway, might as well make a guess.
- printosclassificationoutput(currenths->FPR->getOSClassification(),
- o.osscan_guess || !currenths->FPR->fingerprintSuitableForSubmission());
+ printosclassificationoutput(FPR->getOSClassification(),
+ o.osscan_guess || !FPR->fingerprintSuitableForSubmission());
- if (currenths->FPR->overall_results == OSSCAN_SUCCESS && (currenths->FPR->num_perfect_matches <= 8 || o.debugging)) {
- if (currenths->FPR->num_perfect_matches > 0) {
+ if (FPR->overall_results == OSSCAN_SUCCESS && (FPR->num_perfect_matches <= 8 || o.debugging)) {
+ if (FPR->num_perfect_matches > 0) {
char *p;
- log_write(LOG_MACHINE,"\tOS: %s", currenths->FPR->prints[0]->OS_name);
+ log_write(LOG_MACHINE,"\tOS: %s", FPR->prints[0]->OS_name);
log_write(LOG_XML, "\n",
- p = xml_convert(currenths->FPR->prints[0]->OS_name),
- currenths->FPR->prints[0]->line);
+ p = xml_convert(FPR->prints[0]->OS_name),
+ FPR->prints[0]->line);
free(p);
i = 1;
- while(currenths->FPR->accuracy[i] == 1 ) {
- log_write(LOG_MACHINE,"|%s", currenths->FPR->prints[i]->OS_name);
+ while(FPR->accuracy[i] == 1 ) {
+ log_write(LOG_MACHINE,"|%s", FPR->prints[i]->OS_name);
log_write(LOG_XML, "\n",
- p = xml_convert(currenths->FPR->prints[i]->OS_name),
- currenths->FPR->prints[i]->line);
+ p = xml_convert(FPR->prints[i]->OS_name),
+ FPR->prints[i]->line);
free(p);
i++;
}
-
- if (currenths->FPR->num_perfect_matches == 1)
+ if (FPR->num_perfect_matches == 1)
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,
"OS details: %s",
- currenths->FPR->prints[0]->OS_name);
+ FPR->prints[0]->OS_name);
else {
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,
"OS details: %s",
- currenths->FPR->prints[0]->OS_name);
+ FPR->prints[0]->OS_name);
i = 1;
- while(currenths->FPR->accuracy[i] == 1) {
+ while(FPR->accuracy[i] == 1) {
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,", %s",
- currenths->FPR->prints[i]->OS_name);
+ FPR->prints[i]->OS_name);
i++;
}
}
} else {
- if ((o.osscan_guess || !currenths->FPR->fingerprintSuitableForSubmission()) &&
- currenths->FPR->num_matches > 0) {
+ if ((o.osscan_guess || !FPR->fingerprintSuitableForSubmission()) && FPR->num_matches > 0) {
/* Print the best guesses available */
- log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Aggressive OS guesses: %s (%d%%)", currenths->FPR->prints[0]->OS_name, (int) (currenths->FPR->accuracy[0] * 100));
- for(i=1; i < 10 && currenths->FPR->num_matches > i &&
- currenths->FPR->accuracy[i] >
- currenths->FPR->accuracy[0] - 0.10; i++) {
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Aggressive OS guesses: %s (%d%%)", FPR->prints[0]->OS_name, (int) (FPR->accuracy[0] * 100));
+ for(i=1; i < 10 && FPR->num_matches > i && FPR->accuracy[i] > FPR->accuracy[0] - 0.10; i++) {
char *p;
- log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,", %s (%d%%)", currenths->FPR->prints[i]->OS_name, (int) (currenths->FPR->accuracy[i] * 100));
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,", %s (%d%%)", FPR->prints[i]->OS_name, (int) (FPR->accuracy[i] * 100));
log_write(LOG_XML, "\n",
- p = xml_convert(currenths->FPR->prints[i]->OS_name),
- (int) (currenths->FPR->accuracy[i] * 100),
- currenths->FPR->prints[i]->line);
+ p = xml_convert(FPR->prints[i]->OS_name),
+ (int) (FPR->accuracy[i] * 100),
+ FPR->prints[i]->line);
free(p);
}
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "\n");
}
- if (currenths->FPR->fingerprintSuitableForSubmission()) {
- log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n", mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs, currenths->FPR->osscan_opentcpport, currenths->FPR->osscan_closedtcpport, currenths->MACAddress()));
+ if (FPR->fingerprintSuitableForSubmission()) {
+ log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
+ mergeFPs(FPR->FPs, FPR->numFPs, true,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ wrapFP));
+
} else {
log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No exact OS matches for host (test conditions non-ideal).");
if (o.verbose > 1)
- log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint:\n%s", mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs, currenths->FPR->osscan_opentcpport, currenths->FPR->osscan_closedtcpport, currenths->MACAddress()));
+ log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint:\n%s",
+ mergeFPs(FPR->FPs, FPR->numFPs, false,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ false));
}
}
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"\n");
- if (currenths->FPR->goodFP >= 0 && (o.debugging || o.verbose > 1) && currenths->FPR->num_perfect_matches > 0 ) {
- log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"OS Fingerprint:\n%s\n", fp2ascii(currenths->FPR->FPs[currenths->FPR->goodFP]));
+ if (FPR->goodFP >= 0 && (o.debugging || o.verbose > 1) && FPR->num_perfect_matches > 0 ) {
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"OS Fingerprint:\n%s\n", fp2ascii(FPR->FPs[FPR->goodFP]));
}
- } else if (currenths->FPR->overall_results == OSSCAN_NOMATCHES) {
- if (o.scan_delay < 500 && currenths->FPR->osscan_opentcpport > 0 &&
- currenths->FPR->osscan_closedtcpport > 0 ) {
- log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n", mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs, currenths->FPR->osscan_opentcpport, currenths->FPR->osscan_closedtcpport, currenths->MACAddress()));
+ } else if (FPR->overall_results == OSSCAN_NOMATCHES) {
+ if (FPR->fingerprintSuitableForSubmission()) {
+ log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (If you know what OS is running on it, see http://www.insecure.org/cgi-bin/nmap-submit.cgi).\nTCP/IP fingerprint:\n%s\n",
+ mergeFPs(FPR->FPs, FPR->numFPs, true,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ wrapFP));
} else {
- log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (test conditions non-ideal).\nTCP/IP fingerprint:\n%s\n", mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs, currenths->FPR->osscan_opentcpport, currenths->FPR->osscan_closedtcpport, currenths->MACAddress()));
+ log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT,"No OS matches for host (test conditions non-ideal).\n");
+ if (o.verbose > 1)
+ log_write(LOG_NORMAL|LOG_SKID_NOXLT|LOG_STDOUT, "\nTCP/IP fingerprint:\n%s",
+ mergeFPs(FPR->FPs, FPR->numFPs, false,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ false));
}
- } else if (currenths->FPR->overall_results == OSSCAN_TOOMANYMATCHES || (currenths->FPR->num_perfect_matches > 8 && !o.debugging))
- {
+ } else if (FPR->overall_results == OSSCAN_TOOMANYMATCHES || (FPR->num_perfect_matches > 8 && !o.debugging)) {
log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Too many fingerprints match this host to give specific OS details\n");
if (o.debugging || o.verbose) {
- log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"TCP/IP fingerprint:\n%s", mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs, currenths->FPR->osscan_opentcpport, currenths->FPR->osscan_closedtcpport, currenths->MACAddress()));
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"TCP/IP fingerprint:\n%s",
+ mergeFPs(FPR->FPs, FPR->numFPs, false,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ false));
}
} else { assert(0); }
if (o.debugging || o.verbose) {
-
log_write(LOG_XML,"\n",
- mergeFPs(currenths->FPR->FPs, currenths->FPR->numFPs,
- currenths->FPR->osscan_opentcpport,
- currenths->FPR->osscan_closedtcpport,
- currenths->MACAddress()));
+ mergeFPs(FPR->FPs, FPR->numFPs, false,
+ currenths->v4hostip(), distance, currenths->MACAddress(),
+ FPR->osscan_opentcpport, FPR->osscan_closedtcpport, FPR->osscan_closedudpport,
+ false));
}
-
log_write(LOG_XML, "\n");
if (currenths->seq.lastboot) {
@@ -1330,10 +1394,15 @@ void printosscanoutput(Target *currenths) {
gettimeofday(&tv, NULL);
strncpy(tmbuf, ctime(&(currenths->seq.lastboot)), sizeof(tmbuf));
chomp(tmbuf);
- log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Uptime %.3f days (since %s)\n", (double) (tv.tv_sec - currenths->seq.lastboot) / 86400, tmbuf);
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT,"Uptime: %.3f days (since %s)\n", (double) (tv.tv_sec - currenths->seq.lastboot) / 86400, tmbuf);
log_write(LOG_XML, "\n", tv.tv_sec - currenths->seq.lastboot, tmbuf);
}
+ if (distance!=-1) {
+ log_write(LOG_NORMAL|LOG_SKID|LOG_STDOUT, "Network Distance: %d hops\n", distance);
+ log_write(LOG_XML, "\n", distance);
+ }
+
if (currenths->seq.responses > 3) {
p=numlst;
for(i=0; i < currenths->seq.responses; i++) {
@@ -1379,12 +1448,9 @@ void printosscanoutput(Target *currenths) {
}
log_write(LOG_XML, " />\n");
}
- }
log_flush_all();
}
-
-
/* 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) {
diff --git a/scan_engine.cc b/scan_engine.cc
index 5672fd294..4af9c5bf8 100644
--- a/scan_engine.cc
+++ b/scan_engine.cc
@@ -2136,9 +2136,9 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
}
for(decoy = 0; decoy < o.numdecoys; decoy++) {
- packet = build_tcp_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl,
- ipid, sport, pspec->pd.tcp.dport, seq, ack,
- pspec->pd.tcp.flags, 0, tcpops, tcpopslen,
+ packet = build_tcp_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl, false,
+ ipid, sport, pspec->pd.tcp.dport, seq, ack, 0,
+ pspec->pd.tcp.flags, 0, 0, tcpops, tcpopslen,
o.extra_payload, o.extra_payload_length,
&packetlen);
if (decoy == o.decoyturn) {
@@ -2166,15 +2166,15 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
switch(pspec->proto) {
case IPPROTO_TCP:
- packet = build_tcp_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl,
+ packet = build_tcp_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl, false,
ipid, sport, o.magic_port, get_random_u32(),
- get_random_u32(), TH_ACK, 0, NULL,
+ get_random_u32(), 0, TH_ACK, 0, 0, NULL,
0, o.extra_payload, o.extra_payload_length,
&packetlen);
break;
case IPPROTO_ICMP:
packet = build_icmp_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl,
- ipid, 0, 0, 8, 0, o.extra_payload,
+ ipid, 0, false, 0, 0, 8, 0, o.extra_payload,
o.extra_payload_length, &packetlen);
break;
case IPPROTO_UDP:
@@ -2186,7 +2186,7 @@ static UltraProbe *sendIPScanProbe(UltraScanInfo *USI, HostScanStats *hss,
break;
default:
packet = build_ip_raw(&o.decoys[decoy], hss->target->v4hostip(), o.ttl,
- pspec->proto, ipid,
+ pspec->proto, ipid, 0, false,
o.extra_payload, o.extra_payload_length,
&packetlen);
break;
diff --git a/scripts/Makefile b/scripts/Makefile
index d8c36b739..d630ee83f 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -3,7 +3,7 @@ CC=gcc
CPP=g++
INCLUDE_FLAGS= -I.. -I../nbase -I../libpcap
LINK_FLAGS=-L.. -L../nbase -L../libpcap
-NMAP_OBJS=../osscan.o ../nmap_error.o ../utils.o ../tcpip.o ../output.o ../nmap.o ../scan_engine.o ../portlist.o ../timing.o ../nmap_rpc.o ../charpool.o ../services.o ../targets.o ../idle_scan.o ../MACLookup.o ../protocols.o ../FingerPrintResults.o ../NmapOps.o ../TargetGroup.o ../Target.o ../NmapOutputTable.o ../service_scan.o ../nmap_tty.o ../nmap_dns.o ../nsock/src/libnsock.a
+NMAP_OBJS=../osscan.o ../osscan2.o ../nmap_error.o ../utils.o ../tcpip.o ../output.o ../nmap.o ../scan_engine.o ../portlist.o ../timing.o ../nmap_rpc.o ../charpool.o ../services.o ../targets.o ../idle_scan.o ../MACLookup.o ../protocols.o ../FingerPrintResults.o ../NmapOps.o ../TargetGroup.o ../Target.o ../NmapOutputTable.o ../service_scan.o ../nmap_tty.o ../nmap_dns.o ../nsock/src/libnsock.a
DEFINES=-DHAVE_CONFIG_H=1
DATAFILES = nmap-os-fingerprints nmap-service-probes nmap-services nmap-rpc nmap-protocols nmap-mac-prefixes
SHTOOL = ../shtool
diff --git a/targets.cc b/targets.cc
index eb5918246..d3dbd3651 100644
--- a/targets.cc
+++ b/targets.cc
@@ -925,10 +925,10 @@ else {
o.decoys[o.decoyturn].s_addr = target->v4source().s_addr;
if (pingtype & PINGTYPE_TCP_USE_SYN) {
- send_tcp_raw_decoys( rawsd, eth, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_SYN, 0, (u8 *) "\x02\x04\x05\xb4", 4, o.extra_payload,
+ send_tcp_raw_decoys( rawsd, eth, target->v4hostip(), o.ttl, false, sportbase + trynum, probe_port, myseq, myack, 0, TH_SYN, 0, 0, (u8 *) "\x02\x04\x05\xb4", 4, o.extra_payload,
o.extra_payload_length);
} else {
- send_tcp_raw_decoys( rawsd, eth, target->v4hostip(), o.ttl, sportbase + trynum, probe_port, myseq, myack, TH_ACK, 0, NULL, 0, o.extra_payload,
+ send_tcp_raw_decoys( rawsd, eth, target->v4hostip(), o.ttl, false, sportbase + trynum, probe_port, myseq, myack, 0, TH_ACK, 0, 0, NULL, 0, o.extra_payload,
o.extra_payload_length);
}
diff --git a/tcpip.cc b/tcpip.cc
index 94d5f346e..7887d585b 100644
--- a/tcpip.cc
+++ b/tcpip.cc
@@ -645,6 +645,31 @@ char dev[128];
return 0;
}
+int isipprivate(const struct in_addr * const addr) {
+ char *ipc;
+ unsigned char i1, i2;
+
+ if(!addr) return 0;
+
+ ipc = (char *) &(addr->s_addr);
+ i1 = ipc[0];
+ i2 = ipc[1];
+
+ /* 10.0.0.0/8 */
+ if (i1 == 10)
+ return 1;
+
+ /* 172.16.0.0/12 */
+ if (i1 == 172 && i2 >= 16 && i2 <= 31)
+ return 1;
+
+ /* 192.168.0.0/16 */
+ if (i1 == 192 && i2 == 168)
+ return 1;
+
+ return 0;
+}
+
#ifdef WIN32
/* Convert a dnet interface name into the long pcap style. This also caches the data
to speed things up. Fills out pcapdev (up to pcapdevlen) and returns true if it finds anything.
@@ -830,16 +855,16 @@ void eth_close_cached() {
}
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,
+ const struct in_addr *victim, int ttl, bool df,
+ u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved, u8 flags,
+ u16 window, u16 urp, u8 *options, int optlen, char *data,
u16 datalen)
{
int decoy;
for(decoy = 0; decoy < o.numdecoys; decoy++)
- if (send_tcp_raw(sd, eth, &o.decoys[decoy], victim, ttl, sport, dport,
- seq, ack, flags, window, options, optlen, data,
+ if (send_tcp_raw(sd, eth, &o.decoys[decoy], victim, ttl, df, sport, dport,
+ seq, ack, reserved, flags, window, urp, options, optlen, data,
datalen) == -1)
return -1;
@@ -853,9 +878,9 @@ int send_tcp_raw_decoys( int sd, struct eth_nfo *eth,
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
u8 *build_tcp_raw(const struct in_addr *source,
- const struct in_addr *victim, int ttl,
- u16 ipid, u16 sport, u16 dport, u32 seq, u32 ack, u8 flags,
- u16 window, u8 *options, int optlen, char *data,
+ const struct in_addr *victim, int ttl, u16 ipid, bool df,
+ u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved, u8 flags,
+ u16 window, u16 urp, u8 *options, int optlen, char *data,
u16 datalen, u32 *packetlen) {
struct pseudo_header {
@@ -907,6 +932,8 @@ if (ack)
/*else if (flags & TH_ACK)
tcp->th_ack = rand() + rand();*/
+if (reserved)
+ tcp->th_x2 = reserved & 0x0F;
tcp->th_off = 5 + (optlen /4) /*words*/;
tcp->th_flags = flags;
@@ -914,6 +941,10 @@ if (window)
tcp->th_win = htons(window);
else tcp->th_win = htons(1024 * (myttl % 4 + 1)); /* Who cares */
+/* Urgend pointer */
+if (urp)
+ tcp->th_urp = htons(urp);
+
/* We should probably copy the data over too */
if (data && datalen)
memcpy(packet + sizeof(struct ip) + sizeof(struct tcphdr) + optlen, data, datalen);
@@ -941,6 +972,7 @@ get_random_bytes(&(ip->ip_id), 2);
ip->ip_ttl = myttl;
ip->ip_p = IPPROTO_TCP;
ip->ip_id = ipid;
+if(df) ip->ip_off |= htons(IP_DF);
ip->ip_src.s_addr = source->s_addr;
#ifdef WIN32
// I'm not sure why this is --Fyodor
@@ -959,16 +991,16 @@ ip->ip_sum = in_cksum((unsigned short *)ip, sizeof(struct ip));
/* You need to call sethdrinclude(sd) on the sending sd before calling this */
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,
+ const struct in_addr *victim, int ttl, bool df,
+ u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved, u8 flags,
+ u16 window, u16 urp, u8 *options, int optlen, char *data,
u16 datalen)
{
unsigned int packetlen;
int res = -1;
- u8 *packet = build_tcp_raw(source, victim, ttl, get_random_u16(), sport,
- dport, seq, ack, flags, window, options, optlen,
+ u8 *packet = build_tcp_raw(source, victim, ttl, get_random_u16(), df, sport,
+ dport, seq, ack, reserved, flags, window, urp, options, optlen,
data, datalen, &packetlen);
if (!packet) return -1;
res = send_ip_packet(sd, eth, packet, packetlen);
@@ -1134,7 +1166,7 @@ int send_ip_packet(int sd, struct eth_nfo *eth, u8 *packet, unsigned int packetl
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
u8 *build_icmp_raw(const struct in_addr *source, const struct in_addr *victim,
- int ttl, u16 ipid, u16 seq, unsigned short id, u8 ptype,
+ int ttl, u16 ipid, u8 tos, bool df, u16 seq, unsigned short id, u8 ptype,
u8 pcode, char *data, u16 datalen, u32 *packetlen) {
struct ppkt {
@@ -1153,7 +1185,7 @@ char *ping = (char *) &pingpkt;
pingpkt.type = ptype;
pingpkt.code = pcode;
- if (ptype == 8 && pcode == 0) /* echo request */ {
+ if (ptype == 8) /* echo request */ {
icmplen = 8;
} else if (ptype == 13 && pcode == 0) /* ICMP timestamp req */ {
icmplen = 20;
@@ -1173,7 +1205,6 @@ char *ping = (char *) &pingpkt;
}
/* Fill out the ping packet */
-pingpkt.code = 0;
pingpkt.id = id;
pingpkt.seq = seq;
pingpkt.checksum = 0;
@@ -1182,7 +1213,7 @@ pingpkt.checksum = in_cksum((unsigned short *)ping, icmplen);
if ( o.badsum )
--pingpkt.checksum;
-return build_ip_raw(source, victim, o.ttl, IPPROTO_ICMP, get_random_u16(),
+return build_ip_raw(source, victim, o.ttl, IPPROTO_ICMP, get_random_u16(), tos, df,
ping, icmplen, packetlen);
}
@@ -1420,7 +1451,7 @@ int send_udp_raw( int sd, struct eth_nfo *eth, struct in_addr *source,
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
u8 *build_ip_raw(const struct in_addr *source, const struct in_addr *victim,
- int ttl, u8 proto, u16 ipid, char *data, u16 datalen,
+ int ttl, u8 proto, u16 ipid, u8 tos, bool df, char *data, u16 datalen,
u32 *packetlen)
{
@@ -1448,8 +1479,10 @@ memset((char *) packet, 0, sizeof(struct ip));
ip->ip_v = 4;
ip->ip_hl = 5;
+ip->ip_tos = tos;
ip->ip_len = htons(sizeof(struct ip) + datalen);
ip->ip_id = htons(ipid);
+if(df) ip->ip_off |= htons(IP_DF);
ip->ip_ttl = myttl;
ip->ip_p = proto;
ip->ip_src.s_addr = source->s_addr;
@@ -1480,7 +1513,7 @@ int send_ip_raw( int sd, struct eth_nfo *eth, struct in_addr *source,
int res = -1;
u8 *packet = build_ip_raw(source, victim, ttl, proto, get_random_u16(),
- data, datalen, &packetlen);
+ IP_TOS_DEFAULT, false, data, datalen, &packetlen);
if (!packet) return -1;
res = send_ip_packet(sd, eth, packet, packetlen);
diff --git a/tcpip.h b/tcpip.h
index a9f969ba5..c76e77cba 100644
--- a/tcpip.h
+++ b/tcpip.h
@@ -570,9 +570,9 @@ 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, 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,
+ const struct in_addr *victim, int ttl, bool df,
+ u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved, u8 flags,
+ u16 window, u16 urp, u8 *options, int optlen, 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,
@@ -588,11 +588,10 @@ int send_ip_raw( int sd, struct eth_nfo *eth, struct in_addr *source,
actually sent by this function. Caller must delete the buffer when
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
-u8 *build_tcp_raw(const struct in_addr *source,
- const struct in_addr *victim, int ttl,
- u16 ipid, u16 sport, u16 dport, u32 seq, u32 ack, u8 flags,
- u16 window, u8 *options, int optlen, char *data,
- u16 datalen, u32 *packetlen);
+u8 *build_tcp_raw(const struct in_addr *source, const struct in_addr *victim,
+ int ttl, u16 ipid, bool df, u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved,
+ u8 flags, u16 window, u16 urp, u8 *options, int optlen, char *data, u16 datalen,
+ u32 *packetlen);
/* Builds a UDP packet (including an IP header) by packing the fields
with the given information. It allocates a new buffer to store the
@@ -611,7 +610,7 @@ u8 *build_udp_raw(struct in_addr *source, const struct in_addr *victim,
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
u8 *build_icmp_raw(const struct in_addr *source, const struct in_addr *victim,
- int ttl, u16 ipid, u16 seq, unsigned short id, u8 ptype,
+ int ttl, u16 ipid, u8 tos, bool df, u16 seq, unsigned short id, u8 ptype,
u8 pcode, char *data, u16 datalen, u32 *packetlen);
/* Builds an IP packet (including an IP header) by packing the fields
@@ -621,7 +620,7 @@ u8 *build_icmp_raw(const struct in_addr *source, const struct in_addr *victim,
finished with the packet. The packet length is returned in
packetlen, which must be a valid int pointer. */
u8 *build_ip_raw(const struct in_addr *source, const struct in_addr *victim,
- int ttl, u8 proto, u16 ipid, char *data, u16 datalen,
+ int ttl, u8 proto, u16 ipid, u8 tos, bool df, char *data, u16 datalen,
u32 *packetlen);
/* Send a pre-built IPv4 packet */
@@ -630,9 +629,9 @@ int send_ip_packet(int sd, struct eth_nfo *eth, u8 *packet,
/* Decoy versions of the raw packet sending functions ... */
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,
+ const struct in_addr *victim, int ttl, bool df,
+ u16 sport, u16 dport, u32 seq, u32 ack, u8 reserved, u8 flags,
+ u16 window, u16 urp, u8 *options, int optlen, char *data,
u16 datalen);
int send_udp_raw_decoys( int sd, struct eth_nfo *eth,
@@ -723,6 +722,7 @@ int setTargetMACIfAvailable(Target *target, struct link_header *linkhdr,
bool setTargetNextHopMAC(Target *target);
int islocalhost(const struct in_addr * const addr);
+int isipprivate(const struct in_addr * const addr);
int unblock_socket(int sd);
// Takes a protocol number like IPPROTO_TCP, IPPROTO_UDP, or