From a96166c24eaac1c91bed4815c09e91733409d888 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 14 Jul 2012 15:39:20 +0200 Subject: libxtables: add xtables_ip[6]mask_to_cidr This patch adds generic functions to return the mask in CIDR notation whenever is possible. This patch also simplifies xtables_ip[6]mask_to_numeric, that now use these new two functions. This patch also bumps libxtables_vcurrent and libxtables_vage since we added a couple new interfaces (thanks to Jan Engelhardt for his little reminder on this). Signed-off-by: Pablo Neira Ayuso --- configure.ac | 4 ++-- include/xtables.h.in | 2 ++ libxtables/xtables.c | 33 ++++++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/configure.ac b/configure.ac index 2909a987..989ffd73 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ AC_INIT([iptables], [1.4.14]) # See libtool.info "Libtool's versioning system" -libxtables_vcurrent=7 -libxtables_vage=0 +libxtables_vcurrent=8 +libxtables_vage=1 AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) diff --git a/include/xtables.h.in b/include/xtables.h.in index 28e29337..db69c03b 100644 --- a/include/xtables.h.in +++ b/include/xtables.h.in @@ -442,6 +442,7 @@ extern const char *xtables_ipaddr_to_anyname(const struct in_addr *); extern const char *xtables_ipmask_to_numeric(const struct in_addr *); extern struct in_addr *xtables_numeric_to_ipaddr(const char *); extern struct in_addr *xtables_numeric_to_ipmask(const char *); +extern int xtables_ipmask_to_cidr(const struct in_addr *); extern void xtables_ipparse_any(const char *, struct in_addr **, struct in_addr *, unsigned int *); extern void xtables_ipparse_multiple(const char *, struct in_addr **, @@ -451,6 +452,7 @@ extern struct in6_addr *xtables_numeric_to_ip6addr(const char *); extern const char *xtables_ip6addr_to_numeric(const struct in6_addr *); extern const char *xtables_ip6addr_to_anyname(const struct in6_addr *); extern const char *xtables_ip6mask_to_numeric(const struct in6_addr *); +extern int xtables_ip6mask_to_cidr(const struct in6_addr *); extern void xtables_ip6parse_any(const char *, struct in6_addr **, struct in6_addr *, unsigned int *); extern void xtables_ip6parse_multiple(const char *, struct in6_addr **, diff --git a/libxtables/xtables.c b/libxtables/xtables.c index 014e115b..d8185796 100644 --- a/libxtables/xtables.c +++ b/libxtables/xtables.c @@ -1133,28 +1133,43 @@ const char *xtables_ipaddr_to_anyname(const struct in_addr *addr) return xtables_ipaddr_to_numeric(addr); } -const char *xtables_ipmask_to_numeric(const struct in_addr *mask) +int xtables_ipmask_to_cidr(const struct in_addr *mask) { - static char buf[20]; uint32_t maskaddr, bits; int i; maskaddr = ntohl(mask->s_addr); - + /* shortcut for /32 networks */ if (maskaddr == 0xFFFFFFFFL) - /* we don't want to see "/32" */ - return ""; + return 32; i = 32; bits = 0xFFFFFFFEL; while (--i >= 0 && maskaddr != bits) bits <<= 1; if (i >= 0) - sprintf(buf, "/%d", i); - else + return i; + + /* this mask cannot be converted to CIDR notation */ + return -1; +} + +const char *xtables_ipmask_to_numeric(const struct in_addr *mask) +{ + static char buf[20]; + uint32_t cidr; + + cidr = xtables_ipmask_to_cidr(mask); + if (cidr < 0) { /* mask was not a decent combination of 1's and 0's */ sprintf(buf, "/%s", xtables_ipaddr_to_numeric(mask)); + return buf; + } else if (cidr == 32) { + /* we don't want to see "/32" */ + return ""; + } + sprintf(buf, "/%d", cidr); return buf; } @@ -1465,7 +1480,7 @@ const char *xtables_ip6addr_to_anyname(const struct in6_addr *addr) return xtables_ip6addr_to_numeric(addr); } -static int ip6addr_prefix_length(const struct in6_addr *k) +int xtables_ip6mask_to_cidr(const struct in6_addr *k) { unsigned int bits = 0; uint32_t a, b, c, d; @@ -1492,7 +1507,7 @@ static int ip6addr_prefix_length(const struct in6_addr *k) const char *xtables_ip6mask_to_numeric(const struct in6_addr *addrp) { static char buf[50+2]; - int l = ip6addr_prefix_length(addrp); + int l = xtables_ip6mask_to_cidr(addrp); if (l == -1) { strcpy(buf, "/"); -- cgit v1.2.3