From b0ad27f3ad975ae35dc2cae76271f62079087c12 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Wed, 22 Jun 2016 18:17:07 -0700 Subject: [PATCH] packets: Introduce xor and is_zero functions on IPv6 addresses. These will have callers later. This also rewrites ipv6_addr_bitand() to use newly defined macros. Co-authored-by: Ben Pfaff Signed-off-by: Justin Pettit Acked-by: Ben Pfaff --- lib/packets.c | 46 +++++++++++++++++++++++++++++++++------------- lib/packets.h | 3 +++ 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/lib/packets.c b/lib/packets.c index a27264c93..b9c179e2e 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -674,23 +674,43 @@ ipv6_string_mapped(char *addr_str, const struct in6_addr *addr) } } -struct in6_addr ipv6_addr_bitand(const struct in6_addr *a, - const struct in6_addr *b) -{ - int i; - struct in6_addr dst; - #ifdef s6_addr32 - for (i=0; i<4; i++) { - dst.s6_addr32[i] = a->s6_addr32[i] & b->s6_addr32[i]; - } +#define s6_addrX s6_addr32 +#define IPV6_FOR_EACH(VAR) for (int VAR = 0; VAR < 4; VAR++) #else - for (i=0; i<16; i++) { - dst.s6_addr[i] = a->s6_addr[i] & b->s6_addr[i]; - } +#define s6_addrX s6_addr +#define IPV6_FOR_EACH(VAR) for (int VAR = 0; VAR < 16; VAR++) #endif - return dst; +struct in6_addr +ipv6_addr_bitand(const struct in6_addr *a, const struct in6_addr *b) +{ + struct in6_addr dst; + IPV6_FOR_EACH (i) { + dst.s6_addrX[i] = a->s6_addrX[i] & b->s6_addrX[i]; + } + return dst; +} + +struct in6_addr +ipv6_addr_bitxor(const struct in6_addr *a, const struct in6_addr *b) +{ + struct in6_addr dst; + IPV6_FOR_EACH (i) { + dst.s6_addrX[i] = a->s6_addrX[i] ^ b->s6_addrX[i]; + } + return dst; +} + +bool +ipv6_is_zero(const struct in6_addr *a) +{ + IPV6_FOR_EACH (i) { + if (a->s6_addrX[i]) { + return false; + } + } + return true; } /* Returns an in6_addr consisting of 'mask' high-order 1-bits and 128-N diff --git a/lib/packets.h b/lib/packets.h index 077ccfafa..819366eb4 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -1027,6 +1027,9 @@ void ipv6_format_masked(const struct in6_addr *addr, const char * ipv6_string_mapped(char *addr_str, const struct in6_addr *addr); struct in6_addr ipv6_addr_bitand(const struct in6_addr *src, const struct in6_addr *mask); +struct in6_addr ipv6_addr_bitxor(const struct in6_addr *a, + const struct in6_addr *b); +bool ipv6_is_zero(const struct in6_addr *a); struct in6_addr ipv6_create_mask(int mask); int ipv6_count_cidr_bits(const struct in6_addr *netmask); bool ipv6_is_cidr(const struct in6_addr *netmask); -- 2.20.1