diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2014-02-26 14:40:03 +0100 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2014-02-26 14:40:03 +0100 |
commit | a37101161784cb6904f001e3236afd1ad567efb7 (patch) | |
tree | 844b286e9d57d8e94f5105875b2c02bd8dc26dfd /proto_ethernet.c | |
parent | 35400b74a777675ba9f5ffd85b68feb705cd934b (diff) |
dissectors: ethernet: Handle multicast/broadcast addresses properly
Until now, we just looked up the vendor string based on the OUI for each
MAC address. Thus, multicast and broadcast addresses were just printed
as "Unknown" which is a bit misleading.
Improve this situation by checking bit 0 of the 1st octet of the address
and by checking for the broadcast address if it is set. If a
multicast/broadcast address is found, the respective string is returned.
In all other cases, the existing OUI lookup is done.
In the future we might extend this mechanism to look up well-known
multicast addresses.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
Diffstat (limited to 'proto_ethernet.c')
-rw-r--r-- | proto_ethernet.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/proto_ethernet.c b/proto_ethernet.c index 1d5d684..3b3a9e6 100644 --- a/proto_ethernet.c +++ b/proto_ethernet.c @@ -1,6 +1,7 @@ /* * netsniff-ng - the packet sniffing beast * Copyright 2009, 2010 Daniel Borkmann. + * Copyright 2014 Tobias Klauser * Subject to the GPL, version 2. */ @@ -14,6 +15,29 @@ #include "pkt_buff.h" #include "oui.h" +static inline bool is_multicast_ether_addr(const uint8_t *mac) +{ + return mac[0] & 0x01; +} + +static inline bool is_broadcast_ether_addr(const uint8_t *mac) +{ + return (mac[0] & mac[1] & mac[2] & mac[3] & mac[4] & mac[5]) == 0xff; +} + +static const char *ether_lookup_addr(uint8_t *mac) +{ + if (is_multicast_ether_addr(mac)) { + if (is_broadcast_ether_addr(mac)) + return "Broadcast"; + else + return "Multicast"; + } + + /* found no matching address, so look up the vendor from OUI */ + return lookup_vendor_str((mac[0] << 16) | (mac[1] << 8) | mac[2]); +} + static void ethernet(struct pkt_buff *pkt) { char *type; @@ -41,11 +65,7 @@ static void ethernet(struct pkt_buff *pkt) tprintf(") ]\n"); tprintf(" [ Vendor "); - tprintf("(%s => %s)", - lookup_vendor_str((src_mac[0] << 16) | (src_mac[1] << 8) | - src_mac[2]), - lookup_vendor_str((dst_mac[0] << 16) | (dst_mac[1] << 8) | - dst_mac[2])); + tprintf("(%s => %s)", ether_lookup_addr(src_mac), ether_lookup_addr(dst_mac)); tprintf(" ]\n"); pkt_set_proto(pkt, ð_lay2, ntohs(eth->h_proto)); |