Blob Blame History Raw
From 5ba6bb92b9ec3545d86d598f07643c399a47c7ad Mon Sep 17 00:00:00 2001
From: Phil Sutter <phil@nwl.cc>
Date: Tue, 12 Feb 2019 22:51:34 +0100
Subject: [PATCH] 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>
Signed-off-by: Phil Sutter <psutter@redhat.com>
---
 useful_functions.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/useful_functions.c b/useful_functions.c
index 8a34f820f230b..bf4393712fa44 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;
 }
 
-- 
2.21.0