diff options
author | Phil Sutter <phil@nwl.cc> | 2021-06-02 14:04:43 +0200 |
---|---|---|
committer | Phil Sutter <phil@nwl.cc> | 2021-06-07 14:50:27 +0200 |
commit | ca840c20b7b754d36a1abe7e597fd730dea142d4 (patch) | |
tree | 7ef4a39166609a858e9c07d5106ddfa1cc4a14a6 /extensions | |
parent | 084671d5acaaf749648e828c2ed3b319de651764 (diff) |
extensions: libebt_ip6: Use xtables_ip6parse_any()
The code was almost identical and suffered from the same problem as
fixed in commit a76a5c997a235 ("libxtables: fix two off-by-one memory
corruption bugs").
The only functional change this involves is ebt_parse_ip6_address() will
now accept hostnames as well.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Diffstat (limited to 'extensions')
-rw-r--r-- | extensions/libebt_ip6.c | 74 |
1 files changed, 10 insertions, 64 deletions
diff --git a/extensions/libebt_ip6.c b/extensions/libebt_ip6.c index 301bed9a..3cc39271 100644 --- a/extensions/libebt_ip6.c +++ b/extensions/libebt_ip6.c @@ -247,73 +247,19 @@ static void brip6_init(struct xt_entry_match *match) memset(ipinfo->dmsk.s6_addr, 0, sizeof(ipinfo->dmsk.s6_addr)); } -static struct in6_addr *numeric_to_addr(const char *num) +/* wrap xtables_ip6parse_any(), ignoring any but the first returned address */ +static void ebt_parse_ip6_address(char *address, + struct in6_addr *addr, struct in6_addr *msk) { - static struct in6_addr ap; - - if (inet_pton(AF_INET6, num, &ap) == 1) - return ≈ - return (struct in6_addr *)NULL; -} - -static struct in6_addr *parse_ip6_mask(char *mask) -{ - static struct in6_addr maskaddr; struct in6_addr *addrp; - unsigned int bits; - - if (mask == NULL) { - /* no mask at all defaults to 128 bits */ - memset(&maskaddr, 0xff, sizeof maskaddr); - return &maskaddr; - } - if ((addrp = numeric_to_addr(mask)) != NULL) - return addrp; - if (!xtables_strtoui(mask, NULL, &bits, 0, 128)) - xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Mask '%s' specified", mask); - if (bits != 0) { - char *p = (char *)&maskaddr; - memset(p, 0xff, bits / 8); - memset(p + (bits / 8) + 1, 0, (128 - bits) / 8); - p[bits / 8] = 0xff << (8 - (bits & 7)); - return &maskaddr; - } + unsigned int naddrs; - memset(&maskaddr, 0, sizeof maskaddr); - return &maskaddr; -} - -/* Set the ipv6 mask and address. Callers should check ebt_errormsg[0]. - * The string pointed to by address can be altered. */ -static void ebt_parse_ip6_address(char *address, struct in6_addr *addr, struct in6_addr *msk) -{ - struct in6_addr *tmp_addr; - char buf[256]; - char *p; - int i; - - strncpy(buf, address, sizeof(buf) - 1); - /* first the mask */ - buf[sizeof(buf) - 1] = '\0'; - if ((p = strrchr(buf, '/')) != NULL) { - *p = '\0'; - tmp_addr = parse_ip6_mask(p + 1); - } else - tmp_addr = parse_ip6_mask(NULL); - - *msk = *tmp_addr; - - /* if a null mask is given, the name is ignored, like in "any/0" */ - if (!memcmp(msk, &in6addr_any, sizeof(in6addr_any))) - strcpy(buf, "::"); - - if (inet_pton(AF_INET6, buf, addr) < 1) { - xtables_error(PARAMETER_PROBLEM, "Invalid IPv6 Address '%s' specified", buf); - return; - } - - for (i = 0; i < 4; i++) - addr->s6_addr32[i] &= msk->s6_addr32[i]; + xtables_ip6parse_any(address, &addrp, msk, &naddrs); + if (naddrs != 1) + xtables_error(PARAMETER_PROBLEM, + "Invalid IPv6 Address '%s' specified", address); + memcpy(addr, addrp, sizeof(*addr)); + free(addrp); } #define OPT_SOURCE 0x01 |