From 2ceb758ba4a845898fbff11bd4942751078b8ee7 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sat, 5 Oct 2019 05:12:33 +0200 Subject: add osmo_sockaddr_str_is_nonzero() Often, an IP address of 0.0.0.0 is considered an unset value (for clients requiring a server address; not for listening on "any"). osmo_sockaddr_str_is_set() does return false when the port is 0, but there is no simple way to tell whether the IP address is actually set to a server address. Add osmo_sockaddr_str_is_nonzero() to return false if: - the port is zero, or - the IP address is zero (0.0.0.0 or ::0), or - the IP address cannot be parsed. A practical use example: osmo-msc so far accepts an RTP IP address of 0.0.0.0 as valid. I noticed when trying to trigger error handling from a ttcn3 test. osmo-msc can use this function to reject invalid addresses from MGCP messages. Related: I53ddb19a70fda3deb906464e1b89c12d9b4c7cbd (osmo-msc) Change-Id: I73cbcab90cffcdc9a5f8d5281c57c1f87b2c3550 --- src/sockaddr_str.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src') diff --git a/src/sockaddr_str.c b/src/sockaddr_str.c index d683c7d2..f523050c 100644 --- a/src/sockaddr_str.c +++ b/src/sockaddr_str.c @@ -66,6 +66,35 @@ bool osmo_sockaddr_str_is_set(const struct osmo_sockaddr_str *sockaddr_str) && (sockaddr_str->af == AF_INET || sockaddr_str->af == AF_INET6); } +/*! Return true if IP and port are valid and nonzero. + * \param[in] sockaddr_str The instance to examine. + * \return True iff ip can be converted to a nonzero IP address, and port is not 0. + */ +bool osmo_sockaddr_str_is_nonzero(const struct osmo_sockaddr_str *sockaddr_str) +{ + uint32_t ipv4; + struct in6_addr ipv6_zero = {}; + struct in6_addr ipv6; + + if (!osmo_sockaddr_str_is_set(sockaddr_str)) + return false; + + switch (sockaddr_str->af) { + case AF_INET: + if (osmo_sockaddr_str_to_32(sockaddr_str, &ipv4)) + return false; + return ipv4 != 0; + + case AF_INET6: + if (osmo_sockaddr_str_to_in6_addr(sockaddr_str, &ipv6)) + return false; + return memcmp(&ipv6, &ipv6_zero, sizeof(ipv6)) != 0; + + default: + return false; + } +} + /*! Distinguish between valid IPv4 and IPv6 strings. * This does not verify whether the string is a valid IP address; it assumes that the input is a valid IP address, and * on that premise returns whether it is an IPv4 or IPv6 string, by looking for '.' and ':' characters. It is safe to -- cgit v1.2.3