|
|
05e71a |
From 5ba6bb92b9ec3545d86d598f07643c399a47c7ad Mon Sep 17 00:00:00 2001
|
|
|
05e71a |
From: Phil Sutter <phil@nwl.cc>
|
|
|
05e71a |
Date: Tue, 12 Feb 2019 22:51:34 +0100
|
|
|
05e71a |
Subject: [PATCH] Print IPv6 prefixes in CIDR notation
|
|
|
05e71a |
|
|
|
05e71a |
According to RFC4291, IPv6 prefixes are represented in CIDR notation.
|
|
|
05e71a |
While the use of a "netmask" notation is not explicitly denied, its
|
|
|
05e71a |
existence merely stems from applying IPv4 standards to IPv6. This is not
|
|
|
05e71a |
necessarily correct.
|
|
|
05e71a |
|
|
|
05e71a |
Therefore change printing of IPv6 prefixes to use CIDR notation as long
|
|
|
05e71a |
as the address mask's bits are left contiguous.
|
|
|
05e71a |
|
|
|
05e71a |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
05e71a |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
05e71a |
Signed-off-by: Phil Sutter <psutter@redhat.com>
|
|
|
05e71a |
---
|
|
|
05e71a |
useful_functions.c | 35 ++++++++++++++++++++++++++++++-----
|
|
|
05e71a |
1 file changed, 30 insertions(+), 5 deletions(-)
|
|
|
05e71a |
|
|
|
05e71a |
diff --git a/useful_functions.c b/useful_functions.c
|
|
|
05e71a |
index 8a34f820f230b..bf4393712fa44 100644
|
|
|
05e71a |
--- a/useful_functions.c
|
|
|
05e71a |
+++ b/useful_functions.c
|
|
|
05e71a |
@@ -416,16 +416,41 @@ char *ebt_ip6_to_numeric(const struct in6_addr *addrp)
|
|
|
05e71a |
return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf));
|
|
|
05e71a |
}
|
|
|
05e71a |
|
|
|
05e71a |
+int ebt_ip6mask_to_cidr(const struct in6_addr *k)
|
|
|
05e71a |
+{
|
|
|
05e71a |
+ unsigned int bits = 0;
|
|
|
05e71a |
+ uint32_t a, b, c, d;
|
|
|
05e71a |
+
|
|
|
05e71a |
+ a = ntohl(k->s6_addr32[0]);
|
|
|
05e71a |
+ b = ntohl(k->s6_addr32[1]);
|
|
|
05e71a |
+ c = ntohl(k->s6_addr32[2]);
|
|
|
05e71a |
+ d = ntohl(k->s6_addr32[3]);
|
|
|
05e71a |
+ while (a & 0x80000000U) {
|
|
|
05e71a |
+ ++bits;
|
|
|
05e71a |
+ a <<= 1;
|
|
|
05e71a |
+ a |= (b >> 31) & 1;
|
|
|
05e71a |
+ b <<= 1;
|
|
|
05e71a |
+ b |= (c >> 31) & 1;
|
|
|
05e71a |
+ c <<= 1;
|
|
|
05e71a |
+ c |= (d >> 31) & 1;
|
|
|
05e71a |
+ d <<= 1;
|
|
|
05e71a |
+ }
|
|
|
05e71a |
+ if (a != 0 || b != 0 || c != 0 || d != 0)
|
|
|
05e71a |
+ return -1;
|
|
|
05e71a |
+ return bits;
|
|
|
05e71a |
+}
|
|
|
05e71a |
+
|
|
|
05e71a |
char *ebt_ip6_mask_to_string(const struct in6_addr *msk)
|
|
|
05e71a |
{
|
|
|
05e71a |
- /* /0000:0000:0000:0000:0000:000.000.000.000
|
|
|
05e71a |
- * /0000:0000:0000:0000:0000:0000:0000:0000 */
|
|
|
05e71a |
+ int l = ebt_ip6mask_to_cidr(msk);
|
|
|
05e71a |
static char buf[51+1];
|
|
|
05e71a |
- if (msk->s6_addr32[0] == 0xFFFFFFFFL && msk->s6_addr32[1] == 0xFFFFFFFFL &&
|
|
|
05e71a |
- msk->s6_addr32[2] == 0xFFFFFFFFL && msk->s6_addr32[3] == 0xFFFFFFFFL)
|
|
|
05e71a |
+
|
|
|
05e71a |
+ if (l == 127)
|
|
|
05e71a |
*buf = '\0';
|
|
|
05e71a |
- else
|
|
|
05e71a |
+ else if (l == -1)
|
|
|
05e71a |
sprintf(buf, "/%s", ebt_ip6_to_numeric(msk));
|
|
|
05e71a |
+ else
|
|
|
05e71a |
+ sprintf(buf, "/%d", l);
|
|
|
05e71a |
return buf;
|
|
|
05e71a |
}
|
|
|
05e71a |
|
|
|
05e71a |
--
|
|
|
05e71a |
2.21.0
|
|
|
05e71a |
|