<p>lynxis lazus has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/20564">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_sockaddr_to_str_buf/osmo_sockaddr_to_str<br><br>Add helper to format osmo_sockaddr into a string.<br><br>Change-Id: I917f25ebd1239eae5855d973ced15b93731e33a0<br>---<br>M include/osmocom/core/socket.h<br>M src/socket.c<br>M tests/socket/socket_test.c<br>M tests/socket/socket_test.ok<br>4 files changed, 150 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/64/20564/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/core/socket.h b/include/osmocom/core/socket.h</span><br><span>index 9878240..a69320b 100644</span><br><span>--- a/include/osmocom/core/socket.h</span><br><span>+++ b/include/osmocom/core/socket.h</span><br><span>@@ -118,5 +118,9 @@</span><br><span> int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,</span><br><span>                 const struct osmo_sockaddr *b);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const struct osmo_sockaddr *sockaddr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif /* (!EMBEDDED) */</span><br><span> /*! @} */</span><br><span>diff --git a/src/socket.c b/src/socket.c</span><br><span>index 93b3d99..0fdebec 100644</span><br><span>--- a/src/socket.c</span><br><span>+++ b/src/socket.c</span><br><span>@@ -1715,6 +1715,67 @@</span><br><span>  }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! string-format a given osmo_sockaddr address</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] sockaddr the osmo_sockaddr to print</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \return pointer to the string on success; NULL on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  /* INET6 contains already a null termination, adding '[' ']' ':' '16 bit port' */</span><br><span style="color: hsl(120, 100%, 40%);">+     static __thread char buf[INET6_ADDRSTRLEN + 8];</span><br><span style="color: hsl(120, 100%, 40%);">+       return osmo_sockaddr_to_str_buf(buf, sizeof(buf), sockaddr);</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%);">+/*! string-format a given osmo_sockaddr address into a user-supplied buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user-supplied output buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf_len size of the user-supplied output buffer in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] sockaddr the osmo_sockaddr to print</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \return pointer to the string on success; NULL on error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const struct osmo_sockaddr *sockaddr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint16_t port = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t written;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (buf_len < 5)</span><br><span style="color: hsl(120, 100%, 40%);">+           return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!sockaddr)</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (sockaddr->u.sa.sa_family) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case AF_INET:</span><br><span style="color: hsl(120, 100%, 40%);">+         written = osmo_sockaddr_to_str_and_uint(buf, buf_len, &port, &sockaddr->u.sa);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (written + 1 >= buf_len && port)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+          if (port)</span><br><span style="color: hsl(120, 100%, 40%);">+                     snprintf(buf + written, buf_len - written, ":%d", port);</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case AF_INET6:</span><br><span style="color: hsl(120, 100%, 40%);">+                buf[0] = '[';</span><br><span style="color: hsl(120, 100%, 40%);">+         written = osmo_sockaddr_to_str_and_uint(buf + 1, buf_len - 1, &port, &sockaddr->u.sa);</span><br><span style="color: hsl(120, 100%, 40%);">+             if (written + 2 >= buf_len)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (written + 3 >= buf_len && port)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                if (port)</span><br><span style="color: hsl(120, 100%, 40%);">+                     snprintf(buf + 1 + written, buf_len - written - 1, "]:%d", port);</span><br><span style="color: hsl(120, 100%, 40%);">+           else {</span><br><span style="color: hsl(120, 100%, 40%);">+                        buf[written + 1] = ']';</span><br><span style="color: hsl(120, 100%, 40%);">+                       buf[written + 2] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+         }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              snprintf(buf, buf_len, "unsupported family %d", sockaddr->u.sa.sa_family);</span><br><span style="color: hsl(120, 100%, 40%);">+               return buf;</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 buf;</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> #endif /* HAVE_SYS_SOCKET_H */</span><br><span> </span><br><span> /*! @} */</span><br><span>diff --git a/tests/socket/socket_test.c b/tests/socket/socket_test.c</span><br><span>index 671177f..0bf2127 100644</span><br><span>--- a/tests/socket/socket_test.c</span><br><span>+++ b/tests/socket/socket_test.c</span><br><span>@@ -313,6 +313,80 @@</span><br><span>    return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_osa_str(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char buf[256];</span><br><span style="color: hsl(120, 100%, 40%);">+        const char *result;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct osmo_sockaddr localhost4 = {};</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_sockaddr localhost6 = {};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       localhost4.u.sin = (struct sockaddr_in){</span><br><span style="color: hsl(120, 100%, 40%);">+              .sin_family = AF_INET,</span><br><span style="color: hsl(120, 100%, 40%);">+                .sin_addr.s_addr = inet_addr("127.0.0.1"),</span><br><span style="color: hsl(120, 100%, 40%);">+          .sin_port = htons(42),</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%);">+  localhost6.u.sin6 = (struct sockaddr_in6){</span><br><span style="color: hsl(120, 100%, 40%);">+            .sin6_family = AF_INET6,</span><br><span style="color: hsl(120, 100%, 40%);">+              .sin6_port = htons(42),</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    inet_pton(AF_INET6, "::1", &localhost6.u.sin6.sin6_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* test a too short str */</span><br><span style="color: hsl(120, 100%, 40%);">+    memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 1, &localhost4);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Checking osmo_sockaddr_to_str_buf to small IPv4\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_ASSERT(result == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost4);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Checking osmo_sockaddr_to_str_buf IPv4\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!strncmp("127.0.0.1:42", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 256, &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Checking osmo_sockaddr_to_str_buf IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!strncmp("[::1]:42", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 8, &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(!strncmp("[::1]:4", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(result == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        localhost6.u.sin6.sin6_port = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(result == NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        inet_pton(AF_INET6, "::", &localhost6.u.sin6.sin6_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+        memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(!strncmp("[::]", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       inet_pton(AF_INET6, "2003:1234:5678:90ab:cdef:1234:4321:4321", &localhost6.u.sin6.sin6_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+   memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Checking osmo_sockaddr_to_str_buf long IPv6\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  localhost6.u.sin6.sin6_port = htons(23420);</span><br><span style="color: hsl(120, 100%, 40%);">+   memset(&buf[0], 0, sizeof(buf));</span><br><span style="color: hsl(120, 100%, 40%);">+  result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Checking osmo_sockaddr_to_str_buf long IPv6 port\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    result = osmo_sockaddr_to_str(&localhost6);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const struct log_info_cat default_categories[] = {</span><br><span> };</span><br><span> </span><br><span>@@ -332,6 +406,7 @@</span><br><span>  test_sockinit2();</span><br><span>    test_get_ip_and_port();</span><br><span>      test_sockinit_osa();</span><br><span style="color: hsl(120, 100%, 40%);">+  test_osa_str();</span><br><span> </span><br><span>  return EXIT_SUCCESS;</span><br><span> }</span><br><span>diff --git a/tests/socket/socket_test.ok b/tests/socket/socket_test.ok</span><br><span>index 9a52d44..236c011 100644</span><br><span>--- a/tests/socket/socket_test.ok</span><br><span>+++ b/tests/socket/socket_test.ok</span><br><span>@@ -21,3 +21,13 @@</span><br><span> Checking osmo_sock_init_osa() must fail on mixed IPv4 & IPv6</span><br><span> Checking osmo_sock_init_osa() must fail on mixed IPv6 & IPv4</span><br><span> Checking osmo_sock_init_osa() must fail on invalid osmo_sockaddr</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf to small IPv4</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf IPv4</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf too short IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf too short IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf long IPv6</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf long IPv6 port</span><br><span style="color: hsl(120, 100%, 40%);">+Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/20564">change 20564</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/c/libosmocore/+/20564"/><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-Change-Id: I917f25ebd1239eae5855d973ced15b93731e33a0 </div>
<div style="display:none"> Gerrit-Change-Number: 20564 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: lynxis lazus <lynxis@fe80.eu> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>