diff options
author | Martin Schwenke <martin@meltin.net> | 2017-03-01 17:22:22 +1100 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-09-01 04:06:32 +0200 |
commit | 15c91774d943fba1985f33d10e24030264ce64c8 (patch) | |
tree | 800ce3b7f28aaa75be1c3f2c978bdaa075013673 /ctdb/common | |
parent | e78d2cbff2e30dbea4a7d05bab8f8a5fedfebd79 (diff) | |
download | samba-15c91774d943fba1985f33d10e24030264ce64c8.tar.gz |
ctdb-common: Parse IPv4-mapped IPv6 addresses into IPv4 addresses
Tools like ctdb_killtcp can't route packets to IPv4-mapped IPv6
addresses so this works around that.
Add a test case to confirm that this works.
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
Autobuild-User(master): Martin Schwenke <martins@samba.org>
Autobuild-Date(master): Fri Sep 1 04:06:32 CEST 2017 on sn-devel-144
Diffstat (limited to 'ctdb/common')
-rw-r--r-- | ctdb/common/system_util.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/ctdb/common/system_util.c b/ctdb/common/system_util.c index 57452aa6a1a..96ea71dafaf 100644 --- a/ctdb/common/system_util.c +++ b/ctdb/common/system_util.c @@ -168,12 +168,35 @@ bool parse_ip(const char *addr, const char *ifaces, unsigned port, ctdb_sock_add ZERO_STRUCTP(saddr); /* valgrind :-) */ - /* now is this a ipv4 or ipv6 address ?*/ - p = index(addr, ':'); + /* IPv4 or IPv6 address? + * + * Use rindex() because we need the right-most ':' below for + * IPv4-mapped IPv6 addresses anyway... + */ + p = rindex(addr, ':'); if (p == NULL) { ret = parse_ipv4(addr, port, &saddr->ip); } else { + uint8_t ipv4_mapped_prefix[12] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff + }; + ret = parse_ipv6(addr, ifaces, port, saddr); + if (! ret) { + return ret; + } + + /* + * Check for IPv4-mapped IPv6 address + * (e.g. ::ffff:192.0.2.128) - reparse as IPv4 if + * necessary + */ + if (memcmp(&saddr->ip6.sin6_addr.s6_addr[0], + ipv4_mapped_prefix, + sizeof(ipv4_mapped_prefix)) == 0) { + /* Reparse as IPv4 */ + ret = parse_ipv4(p+1, port, &saddr->ip); + } } return ret; |