<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/13123">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Neels Hofmeyr: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_sockaddr_str API<br><br>For handling RTP IP addresses and ports, osmo-mgw, osmo-bsc and osmo-msc<br>so far have their own separate shims and code duplication around<br>inet_ntoa(), htons(), sockaddr conversions etc. Unify and standardize<br>with this common API.<br><br>In the MGW endpoint FSM that was introduced in osmo-bsc and which I<br>would like to re-use for osmo-msc (upcoming patch moving that to<br>osmo-mgw), it has turned out that using char* IP address and uint16_t<br>port number types are a convenient common denominator for logging,<br>MGCP message composition and GSM48. Ongoing osmo-msc work also uses this<br>for MNCC.<br><br>This is of course potentially useful for any other IP+port combinations<br>besides RTP stream handling.<br><br>Needless to say that most current implementations will probably stay<br>with their current own conversion code for a long time; for current<br>osmo-{bsc,msc,mgw} work (MGW endpoint FSM) though, I would like to move<br>to this API here.<br><br>Change-Id: Id617265337f09dfb6ddfe111ef5e578cd3dc9f63<br>---<br>M configure.ac<br>M include/Makefile.am<br>A include/osmocom/core/sockaddr_str.h<br>M src/Makefile.am<br>A src/sockaddr_str.c<br>M tests/Makefile.am<br>A tests/sockaddr_str/sockaddr_str_test.c<br>A tests/sockaddr_str/sockaddr_str_test.ok<br>M tests/testsuite.at<br>9 files changed, 1,008 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 4a00e69..d717a0b 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -57,7 +57,7 @@</span><br><span> </span><br><span> dnl checks for header files</span><br><span> AC_HEADER_STDC</span><br><span style="color: hsl(0, 100%, 40%);">-AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h sys/timerfd.h syslog.h ctype.h netinet/tcp.h)</span><br><span style="color: hsl(120, 100%, 40%);">+AC_CHECK_HEADERS(execinfo.h sys/select.h sys/socket.h sys/timerfd.h syslog.h ctype.h netinet/tcp.h netinet/in.h)</span><br><span> # for src/conv.c</span><br><span> AC_FUNC_ALLOCA</span><br><span> AC_SEARCH_LIBS([dlopen], [dl dld], [LIBRARY_DLOPEN="$LIBS";LIBS=""])</span><br><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index 17f7d1c..6ed7fe6 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -52,6 +52,7 @@</span><br><span>                        osmocom/core/timer_compat.h \</span><br><span>                        osmocom/core/utils.h \</span><br><span>                        osmocom/core/write_queue.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/core/sockaddr_str.h \</span><br><span>                        osmocom/crypt/auth.h \</span><br><span>                        osmocom/crypt/gprs_cipher.h \</span><br><span>                        osmocom/ctrl/control_cmd.h \</span><br><span>diff --git a/include/osmocom/core/sockaddr_str.h b/include/osmocom/core/sockaddr_str.h</span><br><span>new file mode 100644</span><br><span>index 0000000..253b755</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/core/sockaddr_str.h</span><br><span>@@ -0,0 +1,87 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file sockaddr_str.h</span><br><span style="color: hsl(120, 100%, 40%);">+ * Common API to store an IP address and port.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: neels@hofmeyr.de</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/inet.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct in_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+struct in6_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+struct sockaddr_storage;</span><br><span style="color: hsl(120, 100%, 40%);">+struct sockaddr_in;</span><br><span style="color: hsl(120, 100%, 40%);">+struct sockaddr_in6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup sockaddr_str  IP address/port utilities.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file sockaddr_str.h</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ip_str_type(const char *ip);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_sockaddr_str {</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! AF_INET for IPv4 address, or AF_INET6 for IPv6 address. */</span><br><span style="color: hsl(120, 100%, 40%);">+        int af;</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! NUL terminated string of the IPv4 or IPv6 address. */</span><br><span style="color: hsl(120, 100%, 40%);">+     char ip[INET6_ADDRSTRLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! Port number */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint16_t port;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Format string to print an osmo_sockaddr_str.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * For example:</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *     struct osmo_sockaddr_str *my_sockaddr_str = ...;</span><br><span style="color: hsl(120, 100%, 40%);">+ *     printf("got " OSMO_SOCKADDR_STR_FMT "\n", OSMO_SOCKADDR_STR_FMT_ARGS(my_sockaddr_str));</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_SOCKADDR_STR_FMT "%s:%u"</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_SOCKADDR_STR_FMT_ARGS(R) ((R)->ip ? : ""), (R)->port</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+bool osmo_sockaddr_str_is_set(const struct osmo_sockaddr_str *sockaddr_str);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_str(struct osmo_sockaddr_str *sockaddr_str, const char *ip, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_in_addr(struct osmo_sockaddr_str *sockaddr_str, const struct in_addr *addr, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_in6_addr(struct osmo_sockaddr_str *sockaddr_str, const struct in6_addr *addr, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_32(struct osmo_sockaddr_str *sockaddr_str, uint32_t ip, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_32n(struct osmo_sockaddr_str *sockaddr_str, uint32_t ip, uint16_t port);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr_in(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_in *src);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr_in6(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_in6 *src);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_storage *src);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_in_addr(const struct osmo_sockaddr_str *sockaddr_str, struct in_addr *dst);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_in6_addr(const struct osmo_sockaddr_str *sockaddr_str, struct in6_addr *dst);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_32(const struct osmo_sockaddr_str *sockaddr_str, uint32_t *ip);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_32n(const struct osmo_sockaddr_str *sockaddr_str, uint32_t *ip);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr_in(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_in *dst);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr_in6(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_in6 *dst);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_storage *dst);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/Makefile.am b/src/Makefile.am</span><br><span>index 27ab702..1fae8b0 100644</span><br><span>--- a/src/Makefile.am</span><br><span>+++ b/src/Makefile.am</span><br><span>@@ -24,7 +24,9 @@</span><br><span>                         macaddr.c stat_item.c stats.c stats_statsd.c prim.c \</span><br><span>                        conv_acc.c conv_acc_generic.c sercomm.c prbs.c \</span><br><span>                     isdnhdlc.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                    tdef.c</span><br><span style="color: hsl(120, 100%, 40%);">+                        tdef.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                      sockaddr_str.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                      $(NULL)</span><br><span> </span><br><span> if HAVE_SSSE3</span><br><span> libosmocore_la_SOURCES += conv_acc_sse.c</span><br><span>diff --git a/src/sockaddr_str.c b/src/sockaddr_str.c</span><br><span>new file mode 100644</span><br><span>index 0000000..c9d9a94</span><br><span>--- /dev/null</span><br><span>+++ b/src/sockaddr_str.c</span><br><span>@@ -0,0 +1,378 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file sockaddr_str.c</span><br><span style="color: hsl(120, 100%, 40%);">+ * Common implementation to store an IP address and port.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: neels@hofmeyr.de</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "config.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef HAVE_NETINET_IN_H</span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/in.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arpa/inet.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/byteswap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup sockaddr_str</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Common operations to store IP address as a char string along with a uint16_t port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Convert IP address string to/from in_addr and in6_addr, with bounds checking and basic housekeeping.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * The initial purpose is to store and translate IP address info between GSM CC and MGCP protocols -- GSM mostly using</span><br><span style="color: hsl(120, 100%, 40%);">+ * 32-bit IPv4 addresses, and MGCP forwarding addresses as ASCII character strings.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (At the time of writing, there are no immediate IPv6 users that come to mind, but it seemed appropriate to</span><br><span style="color: hsl(120, 100%, 40%);">+ * accommodate both address families from the start.)</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file sockaddr_str.c</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Return true if all elements of the osmo_sockaddr_str instance are set.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to examine.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return True iff ip is nonempty, port is not 0 and af is set to either AF_INET or AF_INET6.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+bool osmo_sockaddr_str_is_set(const struct osmo_sockaddr_str *sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     return *sockaddr_str->ip</span><br><span style="color: hsl(120, 100%, 40%);">+           && sockaddr_str->port</span><br><span style="color: hsl(120, 100%, 40%);">+              && (sockaddr_str->af == AF_INET || sockaddr_str->af == AF_INET6);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Distinguish between valid IPv4 and IPv6 strings.</span><br><span style="color: hsl(120, 100%, 40%);">+ * This does not verify whether the string is a valid IP address; it assumes that the input is a valid IP address, and</span><br><span style="color: hsl(120, 100%, 40%);">+ * on that premise returns whether it is an IPv4 or IPv6 string, by looking for '.' and ':' characters.  It is safe to</span><br><span style="color: hsl(120, 100%, 40%);">+ * feed invalid address strings, but the return value is only guaranteed to be meaningful if the input was valid.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] ip  Valid IP address string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return AF_INET or AF_INET6, or AF_UNSPEC if neither '.' nor ':' are found in the string.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_ip_str_type(const char *ip)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ip)</span><br><span style="color: hsl(120, 100%, 40%);">+              return AF_UNSPEC;</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Could also be IPv4-mapped IPv6 format with both colons and dots: x:x:x:x:x:x:d.d.d.d */</span><br><span style="color: hsl(120, 100%, 40%);">+    if (strchr(ip, ':'))</span><br><span style="color: hsl(120, 100%, 40%);">+          return AF_INET6;</span><br><span style="color: hsl(120, 100%, 40%);">+      if (strchr(ip, '.'))</span><br><span style="color: hsl(120, 100%, 40%);">+          return AF_INET;</span><br><span style="color: hsl(120, 100%, 40%);">+       return AF_UNSPEC;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Safely copy the given ip string to sockaddr_str, classify to AF_INET or AF_INET6, and set the port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Data will be written to sockaddr_str even if an error is returned.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] ip  Valid IP address string.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port  Port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative if copying the address string failed (e.g. too long), if the address family could</span><br><span style="color: hsl(120, 100%, 40%);">+ *         not be detected (i.e. if osmo_ip_str_type() returned AF_UNSPEC), or if sockaddr_str is NULL.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_str(struct osmo_sockaddr_str *sockaddr_str, const char *ip, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!ip)</span><br><span style="color: hsl(120, 100%, 40%);">+              ip = "";</span><br><span style="color: hsl(120, 100%, 40%);">+    *sockaddr_str = (struct osmo_sockaddr_str){</span><br><span style="color: hsl(120, 100%, 40%);">+           .af = osmo_ip_str_type(ip),</span><br><span style="color: hsl(120, 100%, 40%);">+           .port = port,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = osmo_strlcpy(sockaddr_str->ip, ip, sizeof(sockaddr_str->ip));</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return -EIO;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc >= sizeof(sockaddr_str->ip))</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sockaddr_str->af == AF_UNSPEC)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv4 address to osmo_sockaddr_str, and set port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] addr  IPv4 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port  Port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_in_addr(struct osmo_sockaddr_str *sockaddr_str, const struct in_addr *addr, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       *sockaddr_str = (struct osmo_sockaddr_str){</span><br><span style="color: hsl(120, 100%, 40%);">+           .af = AF_INET,</span><br><span style="color: hsl(120, 100%, 40%);">+                .port = port,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!inet_ntop(AF_INET, addr, sockaddr_str->ip, sizeof(sockaddr_str->ip)))</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv6 address to osmo_sockaddr_str, and set port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] addr  IPv6 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port  Port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_in6_addr(struct osmo_sockaddr_str *sockaddr_str, const struct in6_addr *addr, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       *sockaddr_str = (struct osmo_sockaddr_str){</span><br><span style="color: hsl(120, 100%, 40%);">+           .af = AF_INET6,</span><br><span style="color: hsl(120, 100%, 40%);">+               .port = port,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!inet_ntop(AF_INET6, addr, sockaddr_str->ip, sizeof(sockaddr_str->ip)))</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv4 address from 32bit host-byte-order to osmo_sockaddr_str, and set port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] addr  32bit IPv4 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port  Port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_32(struct osmo_sockaddr_str *sockaddr_str, uint32_t ip, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct in_addr addr;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       addr.s_addr = ip;</span><br><span style="color: hsl(120, 100%, 40%);">+     return osmo_sockaddr_str_from_in_addr(sockaddr_str, &addr, port);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv4 address from 32bit network-byte-order to osmo_sockaddr_str, and set port.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] addr  32bit IPv4 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] port  Port number.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_32n(struct osmo_sockaddr_str *sockaddr_str, uint32_t ip, uint16_t port)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       return osmo_sockaddr_str_from_32(sockaddr_str, osmo_ntohl(ip), port);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv4 address and port to osmo_sockaddr_str.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] src  IPv4 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr_in(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_in *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!src)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (src->sin_family != AF_INET)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return osmo_sockaddr_str_from_in_addr(sockaddr_str, &src->sin_addr, osmo_ntohs(src->sin_port));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv6 address and port to osmo_sockaddr_str.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] src  IPv6 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr_in6(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_in6 *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!src)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (src->sin6_family != AF_INET6)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return osmo_sockaddr_str_from_in6_addr(sockaddr_str, &src->sin6_addr, osmo_ntohs(src->sin6_port));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert IPv4 or IPv6 address and port to osmo_sockaddr_str.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] sockaddr_str  The instance to copy to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] src  IPv4 or IPv6 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative if src does not indicate AF_INET nor AF_INET6 (or if the conversion fails, which</span><br><span style="color: hsl(120, 100%, 40%);">+ *         should not be possible in practice).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_from_sockaddr(struct osmo_sockaddr_str *sockaddr_str, const struct sockaddr_storage *src)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct sockaddr_in *sin = (void*)src;</span><br><span style="color: hsl(120, 100%, 40%);">+   const struct sockaddr_in6 *sin6 = (void*)src;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!src)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sin->sin_family == AF_INET)</span><br><span style="color: hsl(120, 100%, 40%);">+            return osmo_sockaddr_str_from_sockaddr_in(sockaddr_str, sin);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sin6->sin6_family == AF_INET6)</span><br><span style="color: hsl(120, 100%, 40%);">+         return osmo_sockaddr_str_from_sockaddr_in6(sockaddr_str, sin6);</span><br><span style="color: hsl(120, 100%, 40%);">+       return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string to IPv4 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv4 address data to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv4 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_in_addr(const struct osmo_sockaddr_str *sockaddr_str, struct in_addr *dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!dst)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sockaddr_str->af != AF_INET)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EAFNOSUPPORT;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = inet_pton(AF_INET, sockaddr_str->ip, dst);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rc != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string to IPv6 address data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv6 address data to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv6 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_in6_addr(const struct osmo_sockaddr_str *sockaddr_str, struct in6_addr *dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!dst)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sockaddr_str->af != AF_INET6)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = inet_pton(AF_INET6, sockaddr_str->ip, dst);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc != 1)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string to IPv4 address data in host-byte-order.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv4 address data in 32bit host-byte-order format to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv4 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_32(const struct osmo_sockaddr_str *sockaddr_str, uint32_t *ip)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct in_addr addr;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!ip)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = osmo_sockaddr_str_to_in_addr(sockaddr_str, &addr);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    *ip = addr.s_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+    return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string to IPv4 address data in network-byte-order.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv4 address data in 32bit network-byte-order format to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv4 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_32n(const struct osmo_sockaddr_str *sockaddr_str, uint32_t *ip)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t ip_h;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!ip)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       rc = osmo_sockaddr_str_to_32(sockaddr_str, &ip_h);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    *ip = osmo_htonl(ip_h);</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string and port to IPv4 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP and port of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv4 address and port data to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv4 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr_in(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_in *dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!dst)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sockaddr_str->af != AF_INET)</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *dst = (struct sockaddr_in){</span><br><span style="color: hsl(120, 100%, 40%);">+          .sin_family = sockaddr_str->af,</span><br><span style="color: hsl(120, 100%, 40%);">+            .sin_port = osmo_htons(sockaddr_str->port),</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+    return osmo_sockaddr_str_to_in_addr(sockaddr_str, &dst->sin_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string and port to IPv6 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP and port of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv6 address and port data to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IPv6 address string).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr_in6(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_in6 *dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!dst)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (sockaddr_str->af != AF_INET6)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *dst = (struct sockaddr_in6){</span><br><span style="color: hsl(120, 100%, 40%);">+         .sin6_family = sockaddr_str->af,</span><br><span style="color: hsl(120, 100%, 40%);">+           .sin6_port = osmo_htons(sockaddr_str->port),</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    return osmo_sockaddr_str_to_in6_addr(sockaddr_str, &dst->sin6_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Convert osmo_sockaddr_str address string and port to IPv4 or IPv6 address and port data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Depending on sockaddr_str->af, dst will be handled as struct sockaddr_in or struct sockaddr_in6.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] sockaddr_str  The instance to convert the IP and port of.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] dst  IPv4/IPv6 address and port data to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 on success, negative on error (e.g. invalid IP address string for the family indicated by sockaddr_str->af).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_sockaddr_str_to_sockaddr(const struct osmo_sockaddr_str *sockaddr_str, struct sockaddr_storage *dst)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sockaddr_str)</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!dst)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -ENOSPC;</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (sockaddr_str->af) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+         return osmo_sockaddr_str_to_sockaddr_in(sockaddr_str, (void*)dst);</span><br><span style="color: hsl(120, 100%, 40%);">+    case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                return osmo_sockaddr_str_to_sockaddr_in6(sockaddr_str, (void*)dst);</span><br><span style="color: hsl(120, 100%, 40%);">+   default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span style="color: hsl(120, 100%, 40%);">+#endif // HAVE_NETINET_IN_H</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index ab3728f..88bcd7e 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -30,6 +30,7 @@</span><br><span>           tdef/tdef_test tdef/tdef_vty_test_config_root          \</span><br><span>             tdef/tdef_vty_test_config_subnode                      \</span><br><span>             tdef/tdef_vty_test_dynamic                             \</span><br><span style="color: hsl(120, 100%, 40%);">+              sockaddr_str/sockaddr_str_test                         \</span><br><span>             $(NULL)</span><br><span> </span><br><span> if ENABLE_MSGFILE</span><br><span>@@ -236,6 +237,9 @@</span><br><span> tdef_tdef_vty_test_dynamic_SOURCES = tdef/tdef_vty_test_dynamic.c</span><br><span> tdef_tdef_vty_test_dynamic_LDADD = $(LDADD) $(top_builddir)/src/vty/libosmovty.la</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+sockaddr_str_sockaddr_str_test_SOURCES = sockaddr_str/sockaddr_str_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+sockaddr_str_sockaddr_str_test_LDADD = $(LDADD)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> # The `:;' works around a Bash 3.2 bug when the output is not writeable.</span><br><span> $(srcdir)/package.m4: $(top_srcdir)/configure.ac</span><br><span>      :;{ \</span><br><span>@@ -304,6 +308,7 @@</span><br><span>       tdef/tdef_vty_test_config_root.vty \</span><br><span>         tdef/tdef_vty_test_config_subnode.vty \</span><br><span>              tdef/tdef_vty_test_dynamic.vty \</span><br><span style="color: hsl(120, 100%, 40%);">+      sockaddr_str/sockaddr_str_test.ok \</span><br><span>          $(NULL)</span><br><span> </span><br><span> DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c</span><br><span>diff --git a/tests/sockaddr_str/sockaddr_str_test.c b/tests/sockaddr_str/sockaddr_str_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..d2e7944</span><br><span>--- /dev/null</span><br><span>+++ b/tests/sockaddr_str/sockaddr_str_test.c</span><br><span>@@ -0,0 +1,239 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* tests for osmo_sockaddr_str API of libmsomcore */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: neels@hofmeyr.de</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/sockaddr_str.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <netinet/in.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_sockaddr_str oip_data[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { .af = AF_INET, .ip = "1.2.3.4", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .af = AF_INET, .ip = "0.0.0.0", .port = 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .af = AF_INET, .ip = "0.0.0.256", .port = 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET, .ip = "not an ip address", .port = 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET6, .ip = "::", .port = 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+  { .af = AF_INET6, .ip = "::1", .port = 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .af = AF_INET6, .ip = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", .port = 65535 },</span><br><span style="color: hsl(120, 100%, 40%);">+ { .af = AF_INET6, .ip = "::fffff", .port = 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .af = AF_INET6, .ip = "not an ip address", .port = 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ { .af = AF_INET6, .ip = "1.2.3.4", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .af = AF_INET, .ip = "1:2:3::4", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .af = AF_UNSPEC, .ip = "1.2.3.4", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET, .ip = "", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+     { .af = AF_INET6, .ip = "", .port = 5 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET, .ip = "1.2.3.4", .port = 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+      { .af = AF_INET, .ip = "1.2.3:4:5", .port = 0 },</span><br><span style="color: hsl(120, 100%, 40%);">+    { .af = AF_INET6, .ip = "::1:10.9.8.7", .port = 1 },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const char *af_name(int af)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (af) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+         return "AF_INET";</span><br><span style="color: hsl(120, 100%, 40%);">+   case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                return "AF_INET6";</span><br><span style="color: hsl(120, 100%, 40%);">+  case AF_UNSPEC:</span><br><span style="color: hsl(120, 100%, 40%);">+               return "AF_UNSPEC";</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return "?";</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct value_string err_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+      { -EINVAL, "-EINVAL" },</span><br><span style="color: hsl(120, 100%, 40%);">+     {}</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *err_name(int err)</span><br><span style="color: hsl(120, 100%, 40%);">+{ return get_value_string(err_names, err); }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *rc_name(int rc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!rc)</span><br><span style="color: hsl(120, 100%, 40%);">+              return "rc == 0";</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return "rc < 0";</span><br><span style="color: hsl(120, 100%, 40%);">+ return "rc > 0";</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void dump_oip(const struct osmo_sockaddr_str *oip)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("{ .af = %s, .ip = %s, .port = %u }\n", af_name(oip->af), osmo_quote_str(oip->ip, -1), oip->port);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void sockaddr_str_test_conversions()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        char buf[1024];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define hexdump(what) \</span><br><span style="color: hsl(120, 100%, 40%);">+    osmo_hexdump_buf(buf, sizeof(buf), (void*)(&what), sizeof(what), "", false)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < ARRAY_SIZE(oip_data); i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct osmo_sockaddr_str *x = &oip_data[i];</span><br><span style="color: hsl(120, 100%, 40%);">+               int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             dump_oip(x);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("  osmo_sockaddr_str_is_set() = %s\n", osmo_sockaddr_str_is_set(x) ? "true" : "false");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct in_addr a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = osmo_sockaddr_str_to_in_addr(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("  osmo_sockaddr_str_to_in_addr() %s in_addr=%s\n", rc_name(rc), hexdump(a));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_in_addr(&back, &a, x->port);</span><br><span style="color: hsl(120, 100%, 40%);">+                           printf("   -> osmo_sockaddr_str_from_in_addr() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                               dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct in6_addr a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = osmo_sockaddr_str_to_in6_addr(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                        printf("  osmo_sockaddr_str_to_in6_addr() %s in6_addr=%s\n", rc_name(rc), hexdump(a));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_in6_addr(&back, &a, x->port);</span><br><span style="color: hsl(120, 100%, 40%);">+                          printf("   -> osmo_sockaddr_str_from_in6_addr() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                              dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     uint32_t a = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = osmo_sockaddr_str_to_32(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf("  osmo_sockaddr_str_to_32() %s uint32_t=0x%x\n", rc_name(rc), a);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_32(&back, a, x->port);</span><br><span style="color: hsl(120, 100%, 40%);">+                             printf("   -> osmo_sockaddr_str_from_32() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                            dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     uint32_t a = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = osmo_sockaddr_str_to_32n(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("  osmo_sockaddr_str_to_32n() %s uint32_t=0x%x\n", rc_name(rc), a);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                        if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_32n(&back, a, x->port);</span><br><span style="color: hsl(120, 100%, 40%);">+                            printf("   -> osmo_sockaddr_str_from_32n() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                           dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct sockaddr_in a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                  rc = osmo_sockaddr_str_to_sockaddr_in(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("  osmo_sockaddr_str_to_sockaddr_in() %s sockaddr_in=%s\n", rc_name(rc), hexdump(a));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_sockaddr_in(&back, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                           printf("   -> osmo_sockaddr_str_from_sockaddr_in() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                           dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct sockaddr_in6 a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                 rc = osmo_sockaddr_str_to_sockaddr_in6(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("  osmo_sockaddr_str_to_sockaddr_in6() %s sockaddr_in6=%s\n", rc_name(rc), hexdump(a));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_sockaddr_in6(&back, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                          printf("   -> osmo_sockaddr_str_from_sockaddr_in6() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                          dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct sockaddr_storage a = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                     rc = osmo_sockaddr_str_to_sockaddr(x, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                        printf("  osmo_sockaddr_str_to_sockaddr() %s sockaddr_storage=%s\n", rc_name(rc), hexdump(a));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                    if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                                struct osmo_sockaddr_str back;</span><br><span style="color: hsl(120, 100%, 40%);">+                                rc = osmo_sockaddr_str_from_sockaddr(&back, &a);</span><br><span style="color: hsl(120, 100%, 40%);">+                              printf("   -> osmo_sockaddr_str_from_sockaddr() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                              dump_oip(&back);</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (memcmp(x, &back, sizeof(back)))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 }</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct osmo_sockaddr_str from_str;</span><br><span style="color: hsl(120, 100%, 40%);">+                    rc = osmo_sockaddr_str_from_str(&from_str, x->ip, x->port);</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("  osmo_sockaddr_str_from_str() %s ", rc_name(rc));</span><br><span style="color: hsl(120, 100%, 40%);">+                  dump_oip(&from_str);</span><br><span style="color: hsl(120, 100%, 40%);">+                      if (rc == 0 && memcmp(x, &from_str, sizeof(from_str)))</span><br><span style="color: hsl(120, 100%, 40%);">+                            printf("      DIFFERS!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  sockaddr_str_test_conversions();</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/tests/sockaddr_str/sockaddr_str_test.ok b/tests/sockaddr_str/sockaddr_str_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..d69314d</span><br><span>--- /dev/null</span><br><span>+++ b/tests/sockaddr_str/sockaddr_str_test.ok</span><br><span>@@ -0,0 +1,288 @@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc == 0 in_addr=01020304</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in_addr() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc == 0 uint32_t=0x4030201</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc == 0 uint32_t=0x1020304</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32n() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc == 0 sockaddr_in=02000005010203040000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0200000501020304000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc == 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in_addr() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc == 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc == 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32n() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc == 0 sockaddr_in=02000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "0.0.0.0", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc == 0 in_addr=ffffffff</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in_addr() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc == 0 uint32_t=0xffffffff</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc == 0 uint32_t=0xffffffff</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32n() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc == 0 sockaddr_in=0200ffffffffffff0000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0200ffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "255.255.255.255", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "0.0.0.256", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=02000001000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0200000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "0.0.0.256", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "not an ip address", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=02000001000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0200000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc < 0 { .af = AF_UNSPEC, .ip = "not an ip address", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=00010002000300000000000000000004</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a000005000000000001000200030000000000000000000400000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a00000500000000000100020003000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "::", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "::", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "::", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "::", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "::", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "::1", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=00000000000000000000000000000001</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "::1", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a000000000000000000000000000000000000000000000100000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "::1", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a00000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "::1", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "::1", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=ffffffffffffffffffffffffffffffff</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a00ffff00000000ffffffffffffffffffffffffffffffff00000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a00ffff00000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=ffffffffffffffffffffffffffffffff</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a00ffff00000000ffffffffffffffffffffffffffffffff00000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a00ffff00000000ffffffffffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF", .port = 65535 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "::fffff", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=0a000001000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0a00000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "::fffff", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "not an ip address", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=0a000001000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0a00000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc < 0 { .af = AF_UNSPEC, .ip = "not an ip address", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=0a000005000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0a00000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=02000005000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0200000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "1:2:3::4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_UNSPEC, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=02000005000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0200000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc < 0 { .af = AF_UNSPEC, .ip = "", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=0a000005000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0a00000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc < 0 { .af = AF_UNSPEC, .ip = "", .port = 5 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc == 0 in_addr=01020304</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in_addr() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc == 0 uint32_t=0x4030201</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc == 0 uint32_t=0x1020304</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_32n() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc == 0 sockaddr_in=02000000010203040000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0200000001020304000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET, .ip = "1.2.3.4", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET, .ip = "1.2.3:4:5", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = false</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc < 0 in6_addr=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=02000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc < 0 sockaddr_in6=00000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc < 0 sockaddr_storage=0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "1.2.3:4:5", .port = 0 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+{ .af = AF_INET6, .ip = "::1:10.9.8.7", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_is_set() = true</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in_addr() rc < 0 in_addr=00000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_in6_addr() rc == 0 in6_addr=0000000000000000000000010a090807</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_in6_addr() rc == 0 { .af = AF_INET6, .ip = "::1:a09:807", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_32n() rc < 0 uint32_t=0x0</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in() rc < 0 sockaddr_in=00000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr_in6() rc == 0 sockaddr_in6=0a000001000000000000000000000000000000010a09080700000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr_in6() rc == 0 { .af = AF_INET6, .ip = "::1:a09:807", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_to_sockaddr() rc == 0 sockaddr_storage=0a000001000000000000000000000000000000010a0908070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</span><br><span style="color: hsl(120, 100%, 40%);">+   -> osmo_sockaddr_str_from_sockaddr() rc == 0 { .af = AF_INET6, .ip = "::1:a09:807", .port = 1 }</span><br><span style="color: hsl(120, 100%, 40%);">+      DIFFERS!</span><br><span style="color: hsl(120, 100%, 40%);">+  osmo_sockaddr_str_from_str() rc == 0 { .af = AF_INET6, .ip = "::1:10.9.8.7", .port = 1 }</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 0093403..db2003f 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -331,3 +331,9 @@</span><br><span> cat $abs_srcdir/tdef/tdef_test.ok > expout</span><br><span> AT_CHECK([$abs_top_builddir/tests/tdef/tdef_test], [0], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([sockaddr_str])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([sockaddr_str])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/sockaddr_str/sockaddr_str_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/sockaddr_str/sockaddr_str_test], [0], [expout], [ignore])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/13123">change 13123</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/13123"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Id617265337f09dfb6ddfe111ef5e578cd3dc9f63 </div>
<div style="display:none"> Gerrit-Change-Number: 13123 </div>
<div style="display:none"> Gerrit-PatchSet: 11 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Assignee: osmith <osmith@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Max <suraev@alumni.ntnu.no> </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: osmith <osmith@sysmocom.de> </div>