diff --git a/CHANGELOG b/CHANGELOG index e7ed48845..9a7884f89 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -68,6 +68,10 @@ o Fixed host discovery probe matching when looking at the returned TCP discarded responses and the debugging error message: "Bogus trynum or sequence number in ICMP error message" [Kris] +o Added IPProto Ping (-PO) support to Traceroute, and fixed support for + IPProto Scan (-sO) and the ICMP Pings (-PE, -PP, -PM) in Traceroute + as well. These would cause Nmap to hang during Traceroute. [Kris] + o Fixed a segmentation fault in Nsock which occurred when calling nsock_write() with a data length of -1 (which means the data is a NULL-terminated string and Nsock should take the length itself) and diff --git a/traceroute.cc b/traceroute.cc index bcd9d201b..39e8f9171 100644 --- a/traceroute.cc +++ b/traceroute.cc @@ -231,6 +231,7 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists scaninfo.open_response = 0; scaninfo.open_state = PORT_OPEN; scaninfo.closed_state = PORT_CLOSED; + scaninfo.ipproto = false; /* Set up which protocols, tcp flags and responsive * states to use with the current scan type. @@ -272,6 +273,9 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists o.ackscan || o.windowscan || o.maimonscan) scaninfo.initial_proto = IPPROTO_TCP; + if (o.ipprotscan) + scaninfo.ipproto = true; + if(o.pingscan) { scaninfo.open_state = HOST_UP; if (o.pingtype & PINGTYPE_TCP_USE_SYN) { @@ -295,6 +299,8 @@ Traceroute::Traceroute (const char *device_name, devtype type, const scan_lists } else if(o.pingtype & PINGTYPE_ICMP_MASK) { scaninfo.initial_proto = IPPROTO_ICMP; scaninfo.icmp_type = ICMP_ADDRESS; + } else if (o.pingtype & PINGTYPE_PROTO) { + scaninfo.ipproto = true; } } @@ -338,7 +344,11 @@ Traceroute::getTracePort (u8 proto, Target * t) { return scanlists->ack_ping_ports[0]; else if (o.pingtype & PINGTYPE_UDP) return scanlists->udp_ping_ports[0]; - else + else if (o.pingtype & PINGTYPE_PROTO) { + // Initialize protocol header information + port = scanlists->proto_ping_ports[0]; + goto ipproto; + } else return 0; } @@ -367,7 +377,7 @@ Traceroute::getTracePort (u8 proto, Target * t) { state = PORT_FILTERED; if (o.verbose) log_write (LOG_PLAIN, "%s: only filtered %s available, results may be incorrect\n", - t->targetipstr (), o.ipprotscan ? "protocols" : "ports"); + t->targetipstr (), scaninfo.ipproto ? "protocols" : "ports"); } if (state == -1) @@ -379,7 +389,8 @@ Traceroute::getTracePort (u8 proto, Target * t) { port = np->portno; - /* If this is a protocol scan traceroute and we are using +ipproto: + /* If this is a protocol scan/ping traceroute and we are using * one of the major protocols, set up the required information * so we include the correct protocol headers */ if (proto == IPPROTO_IP) { @@ -421,17 +432,19 @@ Traceroute::readTraceResponses () { if (ip == NULL) return finished (); - if ((unsigned) ip->ip_hl * 4 + 20 > bytes) - return finished (); switch (ip->ip_p) { case IPPROTO_ICMP: + if ((unsigned) ip->ip_hl * 4 + 8 > bytes) + break; icmp = (struct icmp *) ((char *) ip + 4 * ip->ip_hl); ipaddr = ip->ip_src.s_addr; sport = ntohs(icmp->icmp_id); /* Process ICMP replies that encapsulate our original probe */ if (icmp->icmp_type == ICMP_DEST_UNREACH || icmp->icmp_type == ICMP_TIME_EXCEEDED) { + if ((unsigned) ip->ip_hl * 4 + 28 > bytes) + break; ip2 = (struct ip *) (((char *) ip) + 4 * ip->ip_hl + 8); if (ip2->ip_p == IPPROTO_TCP) { tcp = (struct tcp_hdr *) ((u8 *) ip2 + ip2->ip_hl * 4); @@ -664,14 +677,14 @@ Traceroute::sendTTLProbes (vector < Target * >&Targets, vector < Target * >&vali if (dport == -1) { if (o.verbose > 1) log_write (LOG_STDOUT, "%s: no responsive %s\n", - t->targetipstr (), o.ipprotscan ? "protocols" : "ports"); + t->targetipstr (), scaninfo.ipproto ? "protocols" : "ports"); continue; } - /* If this is a protocol scan getTracePort() returns - * a protocol number for so we need a random destination + /* If this is a protocol scan/ping, getTracePort() returns + * a protocol number so we need a random destination * port */ - if (o.ipprotscan) { + if (scaninfo.ipproto) { proto = dport; dport = get_random_u16 (); scaninfo.initial_proto = IPPROTO_IP; diff --git a/traceroute.h b/traceroute.h index a775e0dcc..40f692173 100644 --- a/traceroute.h +++ b/traceroute.h @@ -183,6 +183,7 @@ struct scan_info { u8 open_state; u8 closed_response; u8 closed_state; + bool ipproto; }; /* Keeps track of each probes timing state */