From: Martin Schwenke Date: Thu, 28 Jun 2018 10:24:10 +0000 (+1000) Subject: ctdb-common: Move parse_ip_mask() to system_socket.[ch] X-Git-Tag: tevent-0.9.37~182 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f0a4d20954bdcd5a6e8ea5c11224f5a2d4fe3d9;p=thirdparty%2Fsamba.git ctdb-common: Move parse_ip_mask() to system_socket.[ch] This uses ctdb_sock_addr so belongs here. Signed-off-by: Martin Schwenke Reviewed-by: Amitay Isaacs --- diff --git a/ctdb/common/system.c b/ctdb/common/system.c index f1e9763c52a..53480dd0d6c 100644 --- a/ctdb/common/system.c +++ b/ctdb/common/system.c @@ -116,137 +116,6 @@ void reset_scheduler(void) #endif } -static bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin) -{ - sin->sin_family = AF_INET; - sin->sin_port = htons(port); - - if (inet_pton(AF_INET, s, &sin->sin_addr) != 1) { - DEBUG(DEBUG_ERR, (__location__ " Failed to translate %s into sin_addr\n", s)); - return false; - } - -#ifdef HAVE_SOCK_SIN_LEN - sin->sin_len = sizeof(*sin); -#endif - return true; -} - -static bool parse_ipv6(const char *s, const char *ifaces, unsigned port, ctdb_sock_addr *saddr) -{ - saddr->ip6.sin6_family = AF_INET6; - saddr->ip6.sin6_port = htons(port); - saddr->ip6.sin6_flowinfo = 0; - saddr->ip6.sin6_scope_id = 0; - - if (inet_pton(AF_INET6, s, &saddr->ip6.sin6_addr) != 1) { - DEBUG(DEBUG_ERR, (__location__ " Failed to translate %s into sin6_addr\n", s)); - return false; - } - - if (ifaces && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) { - if (strchr(ifaces, ',')) { - DEBUG(DEBUG_ERR, (__location__ " Link local address %s " - "is specified for multiple ifaces %s\n", - s, ifaces)); - return false; - } - saddr->ip6.sin6_scope_id = if_nametoindex(ifaces); - } - -#ifdef HAVE_SOCK_SIN6_LEN - saddr->ip6.sin6_len = sizeof(*saddr); -#endif - return true; -} - -/* - parse an ip - */ -static bool parse_ip(const char *addr, const char *ifaces, unsigned port, - ctdb_sock_addr *saddr) -{ - char *p; - bool ret; - - ZERO_STRUCTP(saddr); /* valgrind :-) */ - - /* 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; -} - -/* - parse a ip/mask pair - */ -bool parse_ip_mask(const char *str, const char *ifaces, ctdb_sock_addr *addr, unsigned *mask) -{ - char *p; - char s[64]; /* Much longer than INET6_ADDRSTRLEN */ - char *endp = NULL; - ssize_t len; - bool ret; - - ZERO_STRUCT(*addr); - - len = strlen(str); - if (len >= sizeof(s)) { - DEBUG(DEBUG_ERR, ("Address %s is unreasonably long\n", str)); - return false; - } - - strncpy(s, str, len+1); - - p = rindex(s, '/'); - if (p == NULL) { - DEBUG(DEBUG_ERR, (__location__ " This addr: %s does not contain a mask\n", s)); - return false; - } - - *mask = strtoul(p+1, &endp, 10); - if (endp == NULL || *endp != 0) { - /* trailing garbage */ - DEBUG(DEBUG_ERR, (__location__ " Trailing garbage after the mask in %s\n", s)); - return false; - } - *p = 0; - - - /* now is this a ipv4 or ipv6 address ?*/ - ret = parse_ip(s, ifaces, 0, addr); - - return ret; -} - /* we don't lock future pages here; it would increase the chance that * we'd fail to mmap later on. */ void lockdown_memory(bool valgrinding) diff --git a/ctdb/common/system.h b/ctdb/common/system.h index 6a3ef29104c..9fd8c225e6f 100644 --- a/ctdb/common/system.h +++ b/ctdb/common/system.h @@ -42,9 +42,6 @@ int ctdb_get_peer_pid(const int fd, pid_t *peer_pid); bool set_scheduler(void); void reset_scheduler(void); -bool parse_ip_mask(const char *str, const char *ifaces, ctdb_sock_addr *addr, - unsigned *mask); - void lockdown_memory(bool valgrinding); void mkdir_p_or_die(const char *dir, int mode); diff --git a/ctdb/common/system_socket.c b/ctdb/common/system_socket.c index b2af6582c97..0a9012c1b24 100644 --- a/ctdb/common/system_socket.c +++ b/ctdb/common/system_socket.c @@ -78,3 +78,140 @@ bool ctdb_sys_have_ip(ctdb_sock_addr *_addr) close(s); return ret == 0; } + +static bool parse_ipv4(const char *s, unsigned port, struct sockaddr_in *sin) +{ + sin->sin_family = AF_INET; + sin->sin_port = htons(port); + + if (inet_pton(AF_INET, s, &sin->sin_addr) != 1) { + DBG_ERR("Failed to translate %s into sin_addr\n", s); + return false; + } + +#ifdef HAVE_SOCK_SIN_LEN + sin->sin_len = sizeof(*sin); +#endif + return true; +} + +static bool parse_ipv6(const char *s, + const char *ifaces, + unsigned port, + ctdb_sock_addr *saddr) +{ + saddr->ip6.sin6_family = AF_INET6; + saddr->ip6.sin6_port = htons(port); + saddr->ip6.sin6_flowinfo = 0; + saddr->ip6.sin6_scope_id = 0; + + if (inet_pton(AF_INET6, s, &saddr->ip6.sin6_addr) != 1) { + DBG_ERR("Failed to translate %s into sin6_addr\n", s); + return false; + } + + if (ifaces && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) { + if (strchr(ifaces, ',')) { + DBG_ERR("Link local address %s " + "is specified for multiple ifaces %s\n", + s, ifaces); + return false; + } + saddr->ip6.sin6_scope_id = if_nametoindex(ifaces); + } + +#ifdef HAVE_SOCK_SIN6_LEN + saddr->ip6.sin6_len = sizeof(*saddr); +#endif + return true; +} + +static bool parse_ip(const char *addr, + const char *ifaces, + unsigned port, + ctdb_sock_addr *saddr) +{ + char *p; + bool ret; + + ZERO_STRUCTP(saddr); /* valgrind :-) */ + + /* + * 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; +} + +/* + * Parse an ip/mask pair + */ +bool parse_ip_mask(const char *str, + const char *ifaces, + ctdb_sock_addr *addr, + unsigned *mask) +{ + char *p; + char s[64]; /* Much longer than INET6_ADDRSTRLEN */ + char *endp = NULL; + ssize_t len; + bool ret; + + ZERO_STRUCT(*addr); + + len = strlen(str); + if (len >= sizeof(s)) { + DBG_ERR("Address %s is unreasonably long\n", str); + return false; + } + + strncpy(s, str, len+1); + + p = rindex(s, '/'); + if (p == NULL) { + DBG_ERR("Address %s does not contain a mask\n", s); + return false; + } + + *mask = strtoul(p+1, &endp, 10); + if (endp == NULL || *endp != 0) { + /* trailing garbage */ + DBG_ERR("Trailing garbage after the mask in %s\n", s); + return false; + } + *p = 0; + + + /* now is this a ipv4 or ipv6 address ?*/ + ret = parse_ip(s, ifaces, 0, addr); + + return ret; +} diff --git a/ctdb/common/system_socket.h b/ctdb/common/system_socket.h index aaa7f16e993..50593079148 100644 --- a/ctdb/common/system_socket.h +++ b/ctdb/common/system_socket.h @@ -25,4 +25,9 @@ uint32_t uint16_checksum(uint16_t *data, size_t n); bool ctdb_sys_have_ip(ctdb_sock_addr *addr); +bool parse_ip_mask(const char *str, + const char *ifaces, + ctdb_sock_addr *addr, + unsigned *mask); + #endif /* __CTDB_SYSTEM_SOCKET_H__ */