mirror of https://gerrit.osmocom.org/libosmocore
add osmo_sockaddr_to_str_buf/osmo_sockaddr_to_str
Add helper to format osmo_sockaddr into a string. Change-Id: I917f25ebd1239eae5855d973ced15b93731e33a0
This commit is contained in:
parent
d420ea9dce
commit
80788fac9e
|
@ -118,5 +118,9 @@ int osmo_sockaddr_local_ip(struct osmo_sockaddr *local_ip,
|
|||
int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
|
||||
const struct osmo_sockaddr *b);
|
||||
|
||||
const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr);
|
||||
char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len,
|
||||
const struct osmo_sockaddr *sockaddr);
|
||||
|
||||
#endif /* (!EMBEDDED) */
|
||||
/*! @} */
|
||||
|
|
62
src/socket.c
62
src/socket.c
|
@ -1715,6 +1715,68 @@ int osmo_sockaddr_cmp(const struct osmo_sockaddr *a,
|
|||
}
|
||||
}
|
||||
|
||||
/*! string-format a given osmo_sockaddr address
|
||||
* \param[in] sockaddr the osmo_sockaddr to print
|
||||
* \return pointer to the string on success; NULL on error
|
||||
*/
|
||||
const char *osmo_sockaddr_to_str(const struct osmo_sockaddr *sockaddr)
|
||||
{
|
||||
/* INET6_ADDRSTRLEN contains already a null termination,
|
||||
* adding '[' ']' ':' '16 bit port' */
|
||||
static __thread char buf[INET6_ADDRSTRLEN + 8];
|
||||
return osmo_sockaddr_to_str_buf(buf, sizeof(buf), sockaddr);
|
||||
}
|
||||
|
||||
/*! string-format a given osmo_sockaddr address into a user-supplied buffer
|
||||
* \param[in] buf user-supplied output buffer
|
||||
* \param[in] buf_len size of the user-supplied output buffer in bytes
|
||||
* \param[in] sockaddr the osmo_sockaddr to print
|
||||
* \return pointer to the string on success; NULL on error
|
||||
*/
|
||||
char *osmo_sockaddr_to_str_buf(char *buf, size_t buf_len,
|
||||
const struct osmo_sockaddr *sockaddr)
|
||||
{
|
||||
uint16_t port = 0;
|
||||
size_t written;
|
||||
if (buf_len < 5)
|
||||
return NULL;
|
||||
|
||||
if (!sockaddr)
|
||||
return NULL;
|
||||
|
||||
switch (sockaddr->u.sa.sa_family) {
|
||||
case AF_INET:
|
||||
written = osmo_sockaddr_to_str_and_uint(buf, buf_len, &port, &sockaddr->u.sa);
|
||||
if (written + 1 >= buf_len && port)
|
||||
return NULL;
|
||||
if (port)
|
||||
snprintf(buf + written, buf_len - written, ":%u", port);
|
||||
break;
|
||||
case AF_INET6:
|
||||
buf[0] = '[';
|
||||
written = osmo_sockaddr_to_str_and_uint(buf + 1, buf_len - 1, &port, &sockaddr->u.sa);
|
||||
if (written + 2 >= buf_len)
|
||||
return NULL;
|
||||
|
||||
if (written + 3 >= buf_len && port)
|
||||
return NULL;
|
||||
|
||||
if (port)
|
||||
snprintf(buf + 1 + written, buf_len - written - 1, "]:%u", port);
|
||||
else {
|
||||
buf[written + 1] = ']';
|
||||
buf[written + 2] = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, buf_len, "unsupported family %d", sockaddr->u.sa.sa_family);
|
||||
return buf;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_SYS_SOCKET_H */
|
||||
|
||||
/*! @} */
|
||||
|
|
|
@ -313,6 +313,80 @@ static int test_sockinit_osa(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void test_osa_str(void)
|
||||
{
|
||||
char buf[256];
|
||||
const char *result;
|
||||
struct osmo_sockaddr localhost4 = {};
|
||||
struct osmo_sockaddr localhost6 = {};
|
||||
|
||||
localhost4.u.sin = (struct sockaddr_in){
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = inet_addr("127.0.0.1"),
|
||||
.sin_port = htons(42),
|
||||
};
|
||||
|
||||
localhost6.u.sin6 = (struct sockaddr_in6){
|
||||
.sin6_family = AF_INET6,
|
||||
.sin6_port = htons(42),
|
||||
};
|
||||
inet_pton(AF_INET6, "::1", &localhost6.u.sin6.sin6_addr);
|
||||
|
||||
/* test a too short str */
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 1, &localhost4);
|
||||
printf("Checking osmo_sockaddr_to_str_buf to small IPv4\n");
|
||||
OSMO_ASSERT(result == NULL);
|
||||
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost4);
|
||||
printf("Checking osmo_sockaddr_to_str_buf IPv4\n");
|
||||
OSMO_ASSERT(!strncmp("127.0.0.1:42", result, sizeof(buf)));
|
||||
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 256, &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf IPv6\n");
|
||||
OSMO_ASSERT(!strncmp("[::1]:42", result, sizeof(buf)));
|
||||
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 8, &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");
|
||||
OSMO_ASSERT(!strncmp("[::1]:4", result, sizeof(buf)));
|
||||
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf too short IPv6\n");
|
||||
OSMO_ASSERT(result == NULL);
|
||||
|
||||
localhost6.u.sin6.sin6_port = 0;
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");
|
||||
OSMO_ASSERT(result == NULL);
|
||||
|
||||
inet_pton(AF_INET6, "::", &localhost6.u.sin6.sin6_addr);
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, 5, &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6\n");
|
||||
OSMO_ASSERT(!strncmp("[::]", result, sizeof(buf)));
|
||||
|
||||
inet_pton(AF_INET6, "2003:1234:5678:90ab:cdef:1234:4321:4321", &localhost6.u.sin6.sin6_addr);
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf long IPv6\n");
|
||||
OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]", result, sizeof(buf)));
|
||||
|
||||
localhost6.u.sin6.sin6_port = htons(23420);
|
||||
memset(&buf[0], 0, sizeof(buf));
|
||||
result = osmo_sockaddr_to_str_buf(buf, sizeof(buf), &localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf long IPv6 port\n");
|
||||
OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));
|
||||
|
||||
result = osmo_sockaddr_to_str(&localhost6);
|
||||
printf("Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer\n");
|
||||
OSMO_ASSERT(!strncmp("[2003:1234:5678:90ab:cdef:1234:4321:4321]:23420", result, sizeof(buf)));
|
||||
}
|
||||
|
||||
const struct log_info_cat default_categories[] = {
|
||||
};
|
||||
|
||||
|
@ -332,6 +406,7 @@ int main(int argc, char *argv[])
|
|||
test_sockinit2();
|
||||
test_get_ip_and_port();
|
||||
test_sockinit_osa();
|
||||
test_osa_str();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -21,3 +21,13 @@ Checking osmo_sock_init_osa() for combined BIND + CONNECT on IPv6
|
|||
Checking osmo_sock_init_osa() must fail on mixed IPv4 & IPv6
|
||||
Checking osmo_sock_init_osa() must fail on mixed IPv6 & IPv4
|
||||
Checking osmo_sock_init_osa() must fail on invalid osmo_sockaddr
|
||||
Checking osmo_sockaddr_to_str_buf to small IPv4
|
||||
Checking osmo_sockaddr_to_str_buf IPv4
|
||||
Checking osmo_sockaddr_to_str_buf IPv6
|
||||
Checking osmo_sockaddr_to_str_buf too short IPv6
|
||||
Checking osmo_sockaddr_to_str_buf too short IPv6
|
||||
Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6
|
||||
Checking osmo_sockaddr_to_str_buf only 5 bytes IPv6
|
||||
Checking osmo_sockaddr_to_str_buf long IPv6
|
||||
Checking osmo_sockaddr_to_str_buf long IPv6 port
|
||||
Checking osmo_sockaddr_to_str_buf long IPv6 port static buffer
|
||||
|
|
Loading…
Reference in New Issue