summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-02-12 22:51:34 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2019-02-14 16:56:10 +0100
commita88e4b4ac1a1b111299f333604d3421bd6e89575 (patch)
tree87b3716608102fc57adc59c7bbff67c652829f4c
parentb43f3ff0a61804f95e6cb3f1dee02f1de1a3a699 (diff)
Print IPv6 prefixes in CIDR notation
According to RFC4291, IPv6 prefixes are represented in CIDR notation. While the use of a "netmask" notation is not explicitly denied, its existence merely stems from applying IPv4 standards to IPv6. This is not necessarily correct. Therefore change printing of IPv6 prefixes to use CIDR notation as long as the address mask's bits are left contiguous. Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--useful_functions.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/useful_functions.c b/useful_functions.c
index 8a34f82..bf43937 100644
--- a/useful_functions.c
+++ b/useful_functions.c
@@ -416,16 +416,41 @@ char *ebt_ip6_to_numeric(const struct in6_addr *addrp)
return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf));
}
+int ebt_ip6mask_to_cidr(const struct in6_addr *k)
+{
+ unsigned int bits = 0;
+ uint32_t a, b, c, d;
+
+ a = ntohl(k->s6_addr32[0]);
+ b = ntohl(k->s6_addr32[1]);
+ c = ntohl(k->s6_addr32[2]);
+ d = ntohl(k->s6_addr32[3]);
+ while (a & 0x80000000U) {
+ ++bits;
+ a <<= 1;
+ a |= (b >> 31) & 1;
+ b <<= 1;
+ b |= (c >> 31) & 1;
+ c <<= 1;
+ c |= (d >> 31) & 1;
+ d <<= 1;
+ }
+ if (a != 0 || b != 0 || c != 0 || d != 0)
+ return -1;
+ return bits;
+}
+
char *ebt_ip6_mask_to_string(const struct in6_addr *msk)
{
- /* /0000:0000:0000:0000:0000:000.000.000.000
- * /0000:0000:0000:0000:0000:0000:0000:0000 */
+ int l = ebt_ip6mask_to_cidr(msk);
static char buf[51+1];
- if (msk->s6_addr32[0] == 0xFFFFFFFFL && msk->s6_addr32[1] == 0xFFFFFFFFL &&
- msk->s6_addr32[2] == 0xFFFFFFFFL && msk->s6_addr32[3] == 0xFFFFFFFFL)
+
+ if (l == 127)
*buf = '\0';
- else
+ else if (l == -1)
sprintf(buf, "/%s", ebt_ip6_to_numeric(msk));
+ else
+ sprintf(buf, "/%d", l);
return buf;
}