diff --git a/MACLookup.cc b/MACLookup.cc index 9a67d5cbf..dcaf3eda2 100644 --- a/MACLookup.cc +++ b/MACLookup.cc @@ -91,6 +91,7 @@ /* $Id$ */ +#include /* Character pool memory allocation */ #include "MACLookup.h" @@ -101,28 +102,12 @@ extern NmapOps o; -struct MAC_entry { - int prefix; /* -1 means none set */ - char *vendor; -}; - -struct MAC_hash_table { - int table_capacity; /* How many members the table can hold */ - int table_members; /* How many members it has now */ - struct MAC_entry **table; -} MacTable; +std::map MacTable; static inline int MacCharPrefix2Key(const u8 *prefix) { return (prefix[0] << 16) + (prefix[1] << 8) + prefix[2]; } -/* Hashes the prefix into a position from 0 to table_capacity - 1. Does not - check if the position is free or anything */ -static inline int MACTableHash(int prefix, int table_capacity) { - // Maybe I should think about changing this sometime. - return prefix % table_capacity; -} - static void mac_prefix_init() { static int initialized = 0; if (initialized) return; @@ -130,14 +115,9 @@ static void mac_prefix_init() { char filename[256]; FILE *fp; char line[128]; - int pfx, pos; - char *endptr, *p; + int pfx; + char *endptr, *vendor; int lineno = 0; - struct MAC_entry *ME; - - MacTable.table_capacity = 19037; - MacTable.table_members = 0; - MacTable.table = (struct MAC_entry **) safe_zalloc(MacTable.table_capacity * sizeof(struct MAC_entry *)); /* Now it is time to read in all of the entries ... */ if (nmap_fetchfile(filename, sizeof(filename), "nmap-mac-prefixes") != 1){ @@ -169,26 +149,17 @@ static void mac_prefix_init() { /* Now grab the vendor */ while(*endptr && isspace((int) (unsigned char) *endptr)) endptr++; assert(*endptr); - p = endptr; + vendor = endptr; while(*endptr && *endptr != '\n' && *endptr != '\r') endptr++; *endptr = '\0'; - // Create the new MAC_entry - ME = (struct MAC_entry *) cp_alloc(sizeof(struct MAC_entry)); - ME->prefix = pfx; - ME->vendor = cp_strdup(p); + if (MacTable.find(pfx) == MacTable.end()) { + MacTable[pfx] = cp_strdup(vendor); + } else { + if (o.debugging > 1) + error("MAC prefix %06X is duplicated in %s; ignoring duplicates.", pfx, filename); + } - if (MacTable.table_members > MacTable.table_capacity * 0.8) - error("WARNING: nmap-mac-prefixes has grown to more than 80%% of our hash table size. MacTable.table_capacity should be increased"); - - // Now insert it into the table - if (MacTable.table_members >= MacTable.table_capacity) - fatal("No space for further MAC prefixes from nmap-mac-prefixes. Increase MacTable.table_capacity"); - - pos = MACTableHash(pfx, MacTable.table_capacity); - while (MacTable.table[pos]) pos = (pos + 1) % MacTable.table_capacity; - MacTable.table[pos] = ME; - MacTable.table_members++; } fclose(fp); @@ -196,16 +167,14 @@ static void mac_prefix_init() { } -static struct MAC_entry *findMACEntry(int prefix) { - int pos = MACTableHash(prefix, MacTable.table_capacity); +static const char *findMACEntry(int prefix) { + std::map::iterator i; - while (MacTable.table[pos]) { - if (MacTable.table[pos]->prefix == prefix) - return MacTable.table[pos]; - pos = (pos + 1) % MacTable.table_capacity; - } + i = MacTable.find(prefix); + if (i == MacTable.end()) + return NULL; - return NULL; + return i->second; } /* Takes a three byte MAC address prefix (passing the whole MAC is OK @@ -213,13 +182,10 @@ static struct MAC_entry *findMACEntry(int prefix) { NULL is returned if no vendor is found for the given prefix or if there is some other error. */ const char *MACPrefix2Corp(const u8 *prefix) { - struct MAC_entry *ent; - if (!prefix) fatal("%s called with a NULL prefix", __func__); mac_prefix_init(); - ent = findMACEntry(MacCharPrefix2Key(prefix)); - return (ent)? ent->vendor : NULL; + return findMACEntry(MacCharPrefix2Key(prefix)); } /* Takes a string and looks through the table for a vendor name which @@ -229,18 +195,19 @@ const char *MACPrefix2Corp(const u8 *prefix) { is not particularly efficient and so should be rewriteen if it is called often */ bool MACCorp2Prefix(const char *vendorstr, u8 *mac_data) { + std::map::iterator i; + if (!vendorstr) fatal("%s: vendorstr is NULL", __func__); if (!mac_data) fatal("%s: mac_data is NULL", __func__); mac_prefix_init(); - for(int i = 0; i < MacTable.table_capacity; i++ ) { - if (MacTable.table[i]) - if (strcasestr(MacTable.table[i]->vendor, vendorstr)) { - mac_data[0] = MacTable.table[i]->prefix >> 16; - mac_data[1] = (MacTable.table[i]->prefix >> 8) & 0xFF; - mac_data[2] = MacTable.table[i]->prefix & 0xFF; - return true; - } + for (i = MacTable.begin(); i != MacTable.end(); i++) { + if (strcasestr(i->second, vendorstr)) { + mac_data[0] = i->first >> 16; + mac_data[1] = (i->first >> 8) & 0xFF; + mac_data[2] = i->first & 0xFF; + return true; + } } return false; }