From b2a1ff8e54aaefb70a52e9b3d20adb4f228f8ea3 Mon Sep 17 00:00:00 2001 From: david Date: Tue, 25 Sep 2012 05:08:09 +0000 Subject: [PATCH] Fix broken protocol lookup. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For some reason (probably by imitation of nmap_getservbyport), protocol numbers, which are byte values 0–255, had htons called on them after being read from nmap-protocols. On little-endian platforms, this turned them into integers 0x0100, 0x0200, 0x0300, etc. protocol_table is supposed to be an array of 256 linked lists, linking all the protocol names of the same number. Because of the above htons conversion, all protocols mapped to bucket 0 on lookup instead. Perhaps in an attempt to work around this broken lookup, all protocols were inserted into bucket 0 on init; all other buckets were empty. This worked on little-endian platforms, but on big-endian platforms where htons is a no-op, all protocol numbers but 0 mapped to an empty linked list. Remove all the htons stuff and just look things up by integers. Use the same mapping on initial insertion and on lookup, so that the buckets are acutally populated. This was noticed by hejianet. http://seclists.org/nmap-dev/2012/q3/1005 --- nmap.cc | 2 +- nping/common_modified.cc | 2 +- output.cc | 6 +++--- protocols.cc | 5 ++--- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/nmap.cc b/nmap.cc index b3ac53520..94c496829 100644 --- a/nmap.cc +++ b/nmap.cc @@ -2673,7 +2673,7 @@ static void getpts_aux(const char *origexpr, int nested, u8 *porttbl, int range_ porttbl[rangestart] |= SCAN_SCTP_PORT; } if ((range_type & SCAN_PROTOCOLS) && - nmap_getprotbynum(htons(rangestart))) { + nmap_getprotbynum(rangestart)) { porttbl[rangestart] |= SCAN_PROTOCOLS; } } else { diff --git a/nping/common_modified.cc b/nping/common_modified.cc index cf4ce19e6..8fa2b3f76 100644 --- a/nping/common_modified.cc +++ b/nping/common_modified.cc @@ -719,7 +719,7 @@ void getpts_aux(const char *origexpr, int nested, u8 *porttbl, int *portwarning) //porttbl[rangestart] |= SCAN_SCTP_PORT; //} //if ((range_type & SCAN_PROTOCOLS) && - //nmap_getprotbynum(htons(rangestart))) { + //nmap_getprotbynum(rangestart)) { //porttbl[rangestart] |= SCAN_PROTOCOLS; //} //} else { diff --git a/output.cc b/output.cc index 31fbc5de9..55f787580 100644 --- a/output.cc +++ b/output.cc @@ -666,7 +666,7 @@ void printportoutput(Target *currenths, PortList *plist) { if (o.reason) Tbl->addItem(rowno, reasoncol, true, port_reason_str(current->reason)); state = statenum2str(current->state); - proto = nmap_getprotbynum(htons(current->portno)); + proto = nmap_getprotbynum(current->portno); Snprintf(portinfo, sizeof(portinfo), "%s", proto ? proto->p_name : "unknown"); Tbl->addItemFormatted(rowno, portcol, false, "%d", current->portno); Tbl->addItem(rowno, statecol, true, state); @@ -2244,7 +2244,7 @@ static void printtraceroute_normal(Target *currenths) { log_write(LOG_PLAIN, "TRACEROUTE (using port %d/%s)\n", probe.pd.sctp.dport, proto2ascii_lowercase(probe.proto)); } else if (probe.type == PS_ICMP || probe.type == PS_ICMPV6 || probe.type == PS_PROTO) { - struct protoent *proto = nmap_getprotbynum(htons(probe.proto)); + struct protoent *proto = nmap_getprotbynum(probe.proto); log_write(LOG_PLAIN, "TRACEROUTE (using proto %d/%s)\n", probe.proto, proto ? proto->p_name : "unknown"); } else if (probe.type == PS_NONE) { @@ -2351,7 +2351,7 @@ static void printtraceroute_xml(Target *currenths) { xml_attribute("port", "%d", probe.pd.sctp.dport); xml_attribute("proto", "%s", proto2ascii_lowercase(probe.proto)); } else if (probe.type == PS_ICMP || probe.type == PS_PROTO) { - struct protoent *proto = nmap_getprotbynum(htons(probe.proto)); + struct protoent *proto = nmap_getprotbynum(probe.proto); if (proto == NULL) xml_attribute("proto", "%d", probe.proto); else diff --git a/protocols.cc b/protocols.cc index f6537f38c..897c9f077 100644 --- a/protocols.cc +++ b/protocols.cc @@ -142,10 +142,9 @@ static int nmap_protocols_init() { res = sscanf(line, "%127s %hu", protocolname, &protno); if (res !=2) continue; - protno = htons(protno); /* Now we make sure our protocols don't have duplicates */ - for(current = protocol_table[0], previous = NULL; + for(current = protocol_table[protno % PROTOCOL_TABLE_SIZE], previous = NULL; current; current = current->next) { if (protno == current->protoent->p_proto) { if (o.debugging) { @@ -164,7 +163,7 @@ static int nmap_protocols_init() { current->protoent = (struct protoent *) cp_alloc(sizeof(struct protoent)); current->next = NULL; if (previous == NULL) { - protocol_table[protno] = current; + protocol_table[protno % PROTOCOL_TABLE_SIZE] = current; } else { previous->next = current; }