diff options
author | Martin Mathieson <martin.mathieson@keysight.com> | 2020-10-24 20:38:00 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2020-11-02 15:52:13 +0000 |
commit | 24d7ff72bbfdcd662bb10a2fe646a1d1d123b5c0 (patch) | |
tree | 46aed19973bb594cf82111bf1757c909fe6a3fdd /epan/addr_resolv.c | |
parent | 63d045e7eb39fec8f918ac89f39f07d0ce47e405 (diff) |
Speed up ethernet entry (manuf and wka) parsing.
This saves around 3% time (profiling a small capture file) at startup.
parse_ether_address_fast() was returning FALSE in some cases
where it shouldn't have, i.e.
- the test for the having hex chars incorrectly discarded any case where the
msb of any address octet is set, i.e. any value from 80 to f0.
- it now allows ':' and '-' as a separator (so that many of the wka entries
also match).
Diffstat (limited to 'epan/addr_resolv.c')
-rw-r--r-- | epan/addr_resolv.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/epan/addr_resolv.c b/epan/addr_resolv.c index d792d87b30..478b328bf9 100644 --- a/epan/addr_resolv.c +++ b/epan/addr_resolv.c @@ -1205,7 +1205,8 @@ host_lookup6(const ws_in6_addr *addr) */ /* - * Converts Ethernet addresses of the form aa:bb:cc or aa:bb:cc:dd:ee:ff/28. The + * Converts Ethernet addresses of the form aa:bb:cc or aa:bb:cc:dd:ee:ff/28. + * '-' is also supported as a separator. The * octets must be exactly two hexadecimal characters and the mask must be either * 28 or 36. Pre-condition: cp MUST be at least 21 bytes. */ @@ -1235,43 +1236,48 @@ parse_ether_address_fast(const guchar *cp, ether_t *eth, unsigned int *mask, }; const guint8 *str_to_nibble_usg = (const guint8 *)str_to_nibble; - if (cp[2] != ':' || cp[5] != ':') { + guchar sep = cp[2]; + if ((sep != ':' && sep != '-') || cp[5] != sep) { /* Unexpected separators. */ return FALSE; } - guint8 num0 = (str_to_nibble_usg[cp[0]] << 4) | str_to_nibble_usg[cp[1]]; - guint8 num1 = (str_to_nibble_usg[cp[3]] << 4) | str_to_nibble_usg[cp[4]]; - guint8 num2 = (str_to_nibble_usg[cp[6]] << 4) | str_to_nibble_usg[cp[7]]; - if (((num0 | num1 | num2) & 0x80)) { + /* N.B. store octet values in an int to detect invalid (-1) entries */ + int num0 = (str_to_nibble_usg[cp[0]] << 4) | (gint8)str_to_nibble_usg[cp[1]]; + int num1 = (str_to_nibble_usg[cp[3]] << 4) | (gint8)str_to_nibble_usg[cp[4]]; + int num2 = (str_to_nibble_usg[cp[6]] << 4) | (gint8)str_to_nibble_usg[cp[7]]; + + if ((num0 | num1 | num2) & 0x100) { /* Not hexadecimal numbers. */ return FALSE; } - eth->addr[0] = num0; - eth->addr[1] = num1; - eth->addr[2] = num2; + eth->addr[0] = (guint8)num0; + eth->addr[1] = (guint8)num1; + eth->addr[2] = (guint8)num2; if (cp[8] == '\0' && accept_mask) { /* Indicate that this is a manufacturer ID (0 is not allowed as a mask). */ *mask = 0; return TRUE; - } else if (cp[8] != ':' || !accept_mask) { + } else if (cp[8] != sep || !accept_mask) { /* Format not handled by this fast path. */ return FALSE; } - guint8 num3 = (str_to_nibble_usg[cp[9]] << 4) | str_to_nibble_usg[cp[10]]; - guint8 num4 = (str_to_nibble_usg[cp[12]] << 4) | str_to_nibble_usg[cp[13]]; - guint8 num5 = (str_to_nibble_usg[cp[15]] << 4) | str_to_nibble_usg[cp[16]]; - if (((num3 | num4 | num5) & 0x80) || cp[11] != ':' || cp[14] != ':') { + /* N.B. store octet values in an int to detect invalid (-1) entries */ + int num3 = (str_to_nibble_usg[cp[9]] << 4) | (gint8)str_to_nibble_usg[cp[10]]; + int num4 = (str_to_nibble_usg[cp[12]] << 4) | (gint8)str_to_nibble_usg[cp[13]]; + int num5 = (str_to_nibble_usg[cp[15]] << 4) | (gint8)str_to_nibble_usg[cp[16]]; + + if (((num3 | num4 | num5) & 0x100) || cp[11] != sep || cp[14] != sep) { /* Not hexadecimal numbers or invalid separators. */ return FALSE; } - eth->addr[3] = num3; - eth->addr[4] = num4; - eth->addr[5] = num5; + eth->addr[3] = (guint8)num3; + eth->addr[4] = (guint8)num4; + eth->addr[5] = (guint8)num5; if (cp[17] == '\0') { /* We got 6 bytes, so this is a MAC address (48 is not allowed as a mask). */ *mask = 48; |