diff options
author | Phil Sutter <phil@nwl.cc> | 2020-11-03 12:08:39 +0100 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2020-12-03 00:27:46 +0100 |
commit | 1bdb5535f561a4e065d766f0f4f41067e31c7281 (patch) | |
tree | d0cb281c247581e071de14d8528e1e6e1ade1a33 /libxtables/xtables.c | |
parent | 21873c24159053ce0a6bbd7e93091ceb0b73f90b (diff) |
libxtables: Extend MAC address printing/parsing support
Adding a parser which supports common names for special MAC/mask
combinations and a print routine detecting those special addresses and
printing the respective name allows to consolidate all the various
duplicated implementations.
The side-effects of this change are manageable:
* arptables now accepts "BGA" as alias for the bridge group address
* "mac" match now prints MAC addresses in lower-case which is consistent
with the remaining code at least
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'libxtables/xtables.c')
-rw-r--r-- | libxtables/xtables.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 7152c657..bc42ba82 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -2137,6 +2137,79 @@ void xtables_print_num(uint64_t number, unsigned int format) printf(FMT("%4lluT ","%lluT "), (unsigned long long)number); } +#include <netinet/ether.h> + +static const unsigned char mac_type_unicast[ETH_ALEN] = {}; +static const unsigned char msk_type_unicast[ETH_ALEN] = {1}; +static const unsigned char mac_type_multicast[ETH_ALEN] = {1}; +static const unsigned char msk_type_multicast[ETH_ALEN] = {1}; +#define ALL_ONE_MAC {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} +static const unsigned char mac_type_broadcast[ETH_ALEN] = ALL_ONE_MAC; +static const unsigned char msk_type_broadcast[ETH_ALEN] = ALL_ONE_MAC; +static const unsigned char mac_type_bridge_group[ETH_ALEN] = {0x01, 0x80, 0xc2}; +static const unsigned char msk_type_bridge_group[ETH_ALEN] = ALL_ONE_MAC; +#undef ALL_ONE_MAC + +int xtables_parse_mac_and_mask(const char *from, void *to, void *mask) +{ + char *p; + int i; + struct ether_addr *addr = NULL; + + if (strcasecmp(from, "Unicast") == 0) { + memcpy(to, mac_type_unicast, ETH_ALEN); + memcpy(mask, msk_type_unicast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "Multicast") == 0) { + memcpy(to, mac_type_multicast, ETH_ALEN); + memcpy(mask, msk_type_multicast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "Broadcast") == 0) { + memcpy(to, mac_type_broadcast, ETH_ALEN); + memcpy(mask, msk_type_broadcast, ETH_ALEN); + return 0; + } + if (strcasecmp(from, "BGA") == 0) { + memcpy(to, mac_type_bridge_group, ETH_ALEN); + memcpy(mask, msk_type_bridge_group, ETH_ALEN); + return 0; + } + if ( (p = strrchr(from, '/')) != NULL) { + *p = '\0'; + if (!(addr = ether_aton(p + 1))) + return -1; + memcpy(mask, addr, ETH_ALEN); + } else + memset(mask, 0xff, ETH_ALEN); + if (!(addr = ether_aton(from))) + return -1; + memcpy(to, addr, ETH_ALEN); + for (i = 0; i < ETH_ALEN; i++) + ((char *)to)[i] &= ((char *)mask)[i]; + return 0; +} + +int xtables_print_well_known_mac_and_mask(const void *mac, const void *mask) +{ + if (!memcmp(mac, mac_type_unicast, ETH_ALEN) && + !memcmp(mask, msk_type_unicast, ETH_ALEN)) + printf("Unicast"); + else if (!memcmp(mac, mac_type_multicast, ETH_ALEN) && + !memcmp(mask, msk_type_multicast, ETH_ALEN)) + printf("Multicast"); + else if (!memcmp(mac, mac_type_broadcast, ETH_ALEN) && + !memcmp(mask, msk_type_broadcast, ETH_ALEN)) + printf("Broadcast"); + else if (!memcmp(mac, mac_type_bridge_group, ETH_ALEN) && + !memcmp(mask, msk_type_bridge_group, ETH_ALEN)) + printf("BGA"); + else + return -1; + return 0; +} + void xtables_print_mac(const unsigned char *macaddress) { unsigned int i; |