mirror of
https://github.com/nmap/nmap.git
synced 2025-12-06 04:31:29 +00:00
Support MA-S, MA-M, and MA-L reg lookups for OUI/MAC/EUI-48
This commit is contained in:
106
MACLookup.cc
106
MACLookup.cc
@@ -75,10 +75,10 @@
|
||||
|
||||
extern NmapOps o;
|
||||
|
||||
std::map<int, char *> MacTable;
|
||||
std::map<u64, char *> MacTable;
|
||||
|
||||
static inline int MacCharPrefix2Key(const u8 *prefix) {
|
||||
return (prefix[0] << 16) + (prefix[1] << 8) + prefix[2];
|
||||
static inline u64 nibble(char hex) {
|
||||
return (hex & 0xf) + ((hex & 0x40) ? 9 : 0);
|
||||
}
|
||||
|
||||
static void mac_prefix_init() {
|
||||
@@ -88,7 +88,7 @@ static void mac_prefix_init() {
|
||||
char filename[256];
|
||||
FILE *fp;
|
||||
char line[128];
|
||||
int pfx;
|
||||
u64 pfx;
|
||||
char *endptr, *vendor;
|
||||
int lineno = 0;
|
||||
|
||||
@@ -114,7 +114,38 @@ static void mac_prefix_init() {
|
||||
break;
|
||||
}
|
||||
/* First grab the prefix */
|
||||
pfx = strtol(line, &endptr, 16);
|
||||
endptr = line;
|
||||
while(*endptr && isxdigit((int) (unsigned char) *endptr)) endptr++;
|
||||
switch (endptr - line) {
|
||||
case 6:
|
||||
/* MA-L: 24 bits */
|
||||
pfx = (nibble(line[0]) << 20) + (nibble(line[1]) << 16)
|
||||
+ (nibble(line[2]) << 12) + (nibble(line[3]) << 8)
|
||||
+ (nibble(line[4]) << 4) + nibble(line[5])
|
||||
+ ((u64)6 << 36);
|
||||
break;
|
||||
case 7:
|
||||
/* MA-M: 28 bits */
|
||||
pfx = (nibble(line[0]) << 24) + (nibble(line[1]) << 20)
|
||||
+ (nibble(line[2]) << 16) + (nibble(line[3]) << 12)
|
||||
+ (nibble(line[4]) << 8) + (nibble(line[5]) << 4)
|
||||
+ nibble(line[6])
|
||||
+ ((u64)7 << 36);
|
||||
break;
|
||||
case 9:
|
||||
/* MA-S: 36 bits */
|
||||
pfx = (nibble(line[0]) << 32) + (nibble(line[1]) << 28)
|
||||
+ (nibble(line[2]) << 24) + (nibble(line[3]) << 20)
|
||||
+ (nibble(line[4]) << 16) + (nibble(line[5]) << 12)
|
||||
+ (nibble(line[6]) << 8) + (nibble(line[7]) << 4)
|
||||
+ nibble(line[8])
|
||||
+ ((u64)9 << 36);
|
||||
break;
|
||||
default:
|
||||
error("Parse error on line #%d of %s. Giving up parsing.", lineno, filename);
|
||||
endptr = NULL; // force failure below
|
||||
break;
|
||||
}
|
||||
if (!endptr || !isspace((int) (unsigned char) *endptr)) {
|
||||
error("Parse error on line #%d of %s. Giving up parsing.", lineno, filename);
|
||||
break;
|
||||
@@ -130,7 +161,7 @@ static void mac_prefix_init() {
|
||||
MacTable[pfx] = cp_strdup(vendor);
|
||||
} else {
|
||||
if (o.debugging > 1)
|
||||
error("MAC prefix %06X is duplicated in %s; ignoring duplicates.", pfx, filename);
|
||||
error("MAC prefix %09lX is duplicated in %s; ignoring duplicates.", pfx, filename);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -140,8 +171,8 @@ static void mac_prefix_init() {
|
||||
}
|
||||
|
||||
|
||||
static const char *findMACEntry(int prefix) {
|
||||
std::map<int, char *>::iterator i;
|
||||
static const char *findMACEntry(u64 prefix) {
|
||||
std::map<u64, char *>::iterator i;
|
||||
|
||||
i = MacTable.find(prefix);
|
||||
if (i == MacTable.end())
|
||||
@@ -150,25 +181,43 @@ static const char *findMACEntry(int prefix) {
|
||||
return i->second;
|
||||
}
|
||||
|
||||
/* Takes a three byte MAC address prefix (passing the whole MAC is OK
|
||||
too) and returns the company which has registered the prefix.
|
||||
/* Takes 6-byte MAC address and returns the company which has registered the 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) {
|
||||
u64 key = 0;
|
||||
const char *corp = NULL;
|
||||
|
||||
if (!prefix) fatal("%s called with a NULL prefix", __func__);
|
||||
mac_prefix_init();
|
||||
|
||||
return findMACEntry(MacCharPrefix2Key(prefix));
|
||||
/* MA-S: 36 bits (9 nibbles)*/
|
||||
key = ((u64)prefix[0] << 28) + (prefix[1] << 20) + (prefix[2] << 12) + (prefix[3] << 4) + (prefix[4] >> 4);
|
||||
corp = findMACEntry(((u64)9 << 36) + key);
|
||||
if (corp)
|
||||
return corp;
|
||||
|
||||
/* MA-M: 28 bits (7 nibbles) */
|
||||
key = key >> 8;
|
||||
corp = findMACEntry(((u64)7 << 36) + key);
|
||||
if (corp)
|
||||
return corp;
|
||||
|
||||
/* MA-L: 24 bits (6 nibbles)*/
|
||||
key = key >> 4;
|
||||
corp = findMACEntry(((u64)6 << 36) + key);
|
||||
|
||||
return corp;
|
||||
}
|
||||
|
||||
/* Takes a string and looks through the table for a vendor name which
|
||||
contains that string. Sets the first three bytes in mac_data and
|
||||
returns true for the first matching entry found. If no entries
|
||||
match, leaves mac_data untouched and returns false. Note that this
|
||||
contains that string. Sets the initial bytes in mac_data and returns the
|
||||
number of nibbles (half-bytes) set for the first matching entry found. If no
|
||||
entries match, leaves mac_data untouched and returns false. Note that this
|
||||
is not particularly efficient and so should be rewritten if it is
|
||||
called often */
|
||||
bool MACCorp2Prefix(const char *vendorstr, u8 *mac_data) {
|
||||
std::map<int, char *>::iterator i;
|
||||
int MACCorp2Prefix(const char *vendorstr, u8 *mac_data) {
|
||||
std::map<u64, char *>::iterator i;
|
||||
|
||||
if (!vendorstr) fatal("%s: vendorstr is NULL", __func__);
|
||||
if (!mac_data) fatal("%s: mac_data is NULL", __func__);
|
||||
@@ -176,11 +225,26 @@ bool MACCorp2Prefix(const char *vendorstr, u8 *mac_data) {
|
||||
|
||||
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;
|
||||
int len = i->first >> 36;
|
||||
int j = 0;
|
||||
u64 pfx = i->first;
|
||||
switch (len) {
|
||||
case 9:
|
||||
mac_data[j++] = (pfx >> 28) & 0xff;
|
||||
case 7:
|
||||
mac_data[j++] = (pfx >> 20) & 0xff;
|
||||
pfx = pfx << 4;
|
||||
case 6:
|
||||
mac_data[j++] = (pfx >> 16) & 0xff;
|
||||
mac_data[j++] = (pfx >> 8) & 0xff;
|
||||
mac_data[j++] = (pfx) & 0xff;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
assert(j == (len + 1) / 2);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user