Merge pull request #14068 from miri64/sock_util/enh/netif-str2ep
sock_util: add interface descriptor parsing to str2ep
This commit is contained in:
commit
f3dddd6127
@ -33,6 +33,9 @@
|
|||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define PORT_STR_LEN (5)
|
||||||
|
#define NETIF_STR_LEN (5)
|
||||||
|
|
||||||
int sock_udp_ep_fmt(const sock_udp_ep_t *endpoint, char *addr_str, uint16_t *port)
|
int sock_udp_ep_fmt(const sock_udp_ep_t *endpoint, char *addr_str, uint16_t *port)
|
||||||
{
|
{
|
||||||
void *addr_ptr;
|
void *addr_ptr;
|
||||||
@ -147,6 +150,45 @@ int sock_urlsplit(const char *url, char *hostport, char *urlpath)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _parse_port(sock_udp_ep_t *ep_out, const char *portstart)
|
||||||
|
{
|
||||||
|
int port_len = strlen(portstart);
|
||||||
|
|
||||||
|
/* Checks here verify that the supplied port number is up to 5 (random)
|
||||||
|
* chars in size and result is smaller or equal to UINT16_MAX. */
|
||||||
|
if (port_len > PORT_STR_LEN) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
uint32_t port = atol(portstart);
|
||||||
|
if (port > UINT16_MAX) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ep_out->port = (uint16_t)port;
|
||||||
|
return port_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _parse_netif(sock_udp_ep_t *ep_out, char *netifstart)
|
||||||
|
{
|
||||||
|
char *netifend;
|
||||||
|
size_t netiflen;
|
||||||
|
char netifbuf[NETIF_STR_LEN + 1];
|
||||||
|
|
||||||
|
for (netifend = netifstart; *netifend && *netifend != ']';
|
||||||
|
netifend++);
|
||||||
|
netiflen = netifend - netifstart;
|
||||||
|
if (!*netifend || (netiflen >= NETIF_STR_LEN) || (netiflen == 0)) {
|
||||||
|
/* no netif found, bail out */
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
strncpy(netifbuf, netifstart, netiflen);
|
||||||
|
int netif = strtol(netifbuf, NULL, 10);
|
||||||
|
if ((netif < 0) || (((unsigned)netif) > UINT16_MAX)) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ep_out->netif = (uint16_t)netif;
|
||||||
|
return (netifend - netifstart);
|
||||||
|
}
|
||||||
|
|
||||||
int sock_udp_str2ep(sock_udp_ep_t *ep_out, const char *str)
|
int sock_udp_str2ep(sock_udp_ep_t *ep_out, const char *str)
|
||||||
{
|
{
|
||||||
unsigned brackets_flag;
|
unsigned brackets_flag;
|
||||||
@ -159,7 +201,8 @@ int sock_udp_str2ep(sock_udp_ep_t *ep_out, const char *str)
|
|||||||
|
|
||||||
if (*hoststart == '[') {
|
if (*hoststart == '[') {
|
||||||
brackets_flag = 1;
|
brackets_flag = 1;
|
||||||
for (hostend = ++hoststart; *hostend && *hostend != ']';
|
for (hostend = ++hoststart;
|
||||||
|
*hostend && *hostend != ']' && *hostend != '%';
|
||||||
hostend++);
|
hostend++);
|
||||||
if (! *hostend || ((size_t)(hostend - hoststart) >= sizeof(hostbuf))) {
|
if (! *hostend || ((size_t)(hostend - hoststart) >= sizeof(hostbuf))) {
|
||||||
/* none found, bail out */
|
/* none found, bail out */
|
||||||
@ -171,26 +214,28 @@ int sock_udp_str2ep(sock_udp_ep_t *ep_out, const char *str)
|
|||||||
for (hostend = hoststart; *hostend && (*hostend != ':') && \
|
for (hostend = hoststart; *hostend && (*hostend != ':') && \
|
||||||
((size_t)(hostend - hoststart) < sizeof(hostbuf)); hostend++) {}
|
((size_t)(hostend - hoststart) < sizeof(hostbuf)); hostend++) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t hostlen = hostend - hoststart;
|
size_t hostlen = hostend - hoststart;
|
||||||
if (*(hostend + brackets_flag) == ':') {
|
if (*(hostend + brackets_flag) == ':') {
|
||||||
char *portstart = hostend + brackets_flag + 1;
|
int res = _parse_port(ep_out, hostend + brackets_flag + 1);
|
||||||
/* Checks here verify that the supplied port number is up to 5 (random)
|
if (res < 0) {
|
||||||
* chars in size and result is smaller or equal to UINT16_MAX. */
|
return res;
|
||||||
if (strlen(portstart) > 5) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
uint32_t port = atol(portstart);
|
|
||||||
if (port > UINT16_MAX) {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
ep_out->port = (uint16_t)port;
|
else if (brackets_flag && (*hostend == '%')) {
|
||||||
|
int res = _parse_netif(ep_out, hostend + 1);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
char *colon_ptr = hostend + res + brackets_flag + 1;
|
||||||
|
if ((*colon_ptr == ':') &&
|
||||||
|
((res = _parse_port(ep_out, colon_ptr + 1)) < 0)) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hostlen >= sizeof(hostbuf)) {
|
if (hostlen >= sizeof(hostbuf)) {
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(hostbuf, hoststart, hostlen);
|
memcpy(hostbuf, hoststart, hostlen);
|
||||||
|
|
||||||
hostbuf[hostlen] = '\0';
|
hostbuf[hostlen] = '\0';
|
||||||
|
|||||||
@ -61,6 +61,12 @@
|
|||||||
#define TEST_STR2EP_V4_INVALID "[10.0.0.1]:53"
|
#define TEST_STR2EP_V4_INVALID "[10.0.0.1]:53"
|
||||||
#define TEST_STR2EP_INVALID "[2001:db8:a:b:c:d:e:f:1]"
|
#define TEST_STR2EP_INVALID "[2001:db8:a:b:c:d:e:f:1]"
|
||||||
#define TEST_STR2EP_INVALID2 "[2001:db8:a:b:c:d:e:f]:66000"
|
#define TEST_STR2EP_INVALID2 "[2001:db8:a:b:c:d:e:f]:66000"
|
||||||
|
#define TEST_STR2EP_NETIF "[fe80::1%45]"
|
||||||
|
#define TEST_STR2EP_NETIF2 "[fe80::1%23]:243"
|
||||||
|
#define TEST_STR2EP_NETIF_GLOBAL "[2001:db8:a::1%75]"
|
||||||
|
#define TEST_STR2EP_NETIF_INVALID "[fe80::1%]:752"
|
||||||
|
#define TEST_STR2EP_NETIF_INVALID2 "[fe80::1%56776]:1346"
|
||||||
|
#define TEST_STR2EP_NETIF_INVALID3 "[fe80::1%53:4232"
|
||||||
|
|
||||||
static char addr[CONFIG_SOCK_URLPATH_MAXLEN];
|
static char addr[CONFIG_SOCK_URLPATH_MAXLEN];
|
||||||
static char urlpath[CONFIG_SOCK_URLPATH_MAXLEN];
|
static char urlpath[CONFIG_SOCK_URLPATH_MAXLEN];
|
||||||
@ -170,6 +176,7 @@ static void test_sock_util_str2ep__ipv6_noport(void)
|
|||||||
ep.port = 0;
|
ep.port = 0;
|
||||||
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP));
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP));
|
||||||
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, ep.netif);
|
||||||
TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family);
|
TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,6 +186,7 @@ static void test_sock_util_str2ep__ipv4_noport(void)
|
|||||||
ep.port = 0;
|
ep.port = 0;
|
||||||
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_V4));
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_V4));
|
||||||
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, ep.netif);
|
||||||
TEST_ASSERT_EQUAL_INT(AF_INET, ep.family);
|
TEST_ASSERT_EQUAL_INT(AF_INET, ep.family);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -187,6 +195,7 @@ static void test_sock_util_str2ep__ipv4_port(void)
|
|||||||
sock_udp_ep_t ep;
|
sock_udp_ep_t ep;
|
||||||
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_V4_2));
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_V4_2));
|
||||||
TEST_ASSERT_EQUAL_INT(53, ep.port);
|
TEST_ASSERT_EQUAL_INT(53, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, ep.netif);
|
||||||
TEST_ASSERT_EQUAL_INT(AF_INET, ep.family);
|
TEST_ASSERT_EQUAL_INT(AF_INET, ep.family);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,18 +206,66 @@ static void test_sock_util_str2ep__ipv4_bracketed(void)
|
|||||||
TEST_STR2EP_V4_INVALID));
|
TEST_STR2EP_V4_INVALID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__invalid_bracket_missing(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep,
|
||||||
|
TEST_STR2EP_NETIF_INVALID3));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_sock_util_str2ep__invalid_ipv6(void)
|
static void test_sock_util_str2ep__invalid_ipv6(void)
|
||||||
{
|
{
|
||||||
sock_udp_ep_t ep;
|
sock_udp_ep_t ep;
|
||||||
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep, TEST_STR2EP_INVALID));
|
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep, TEST_STR2EP_INVALID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__invalid_netif_missing(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep,
|
||||||
|
TEST_STR2EP_NETIF_INVALID));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__invalid_netif(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep,
|
||||||
|
TEST_STR2EP_NETIF_INVALID2));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_sock_util_str2ep__invalid_port(void)
|
static void test_sock_util_str2ep__invalid_port(void)
|
||||||
{
|
{
|
||||||
sock_udp_ep_t ep;
|
sock_udp_ep_t ep;
|
||||||
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep, TEST_STR2EP_INVALID2));
|
TEST_ASSERT_EQUAL_INT(-EINVAL, sock_udp_str2ep(&ep, TEST_STR2EP_INVALID2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__netif(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_NETIF));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(45, ep.netif);
|
||||||
|
TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__netif_with_port(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_NETIF2));
|
||||||
|
TEST_ASSERT_EQUAL_INT(243, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(23, ep.netif);
|
||||||
|
TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sock_util_str2ep__netif_with_global_addr(void)
|
||||||
|
{
|
||||||
|
sock_udp_ep_t ep;
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, sock_udp_str2ep(&ep, TEST_STR2EP_NETIF_GLOBAL));
|
||||||
|
TEST_ASSERT_EQUAL_INT(0, ep.port);
|
||||||
|
TEST_ASSERT_EQUAL_INT(75, ep.netif);
|
||||||
|
TEST_ASSERT_EQUAL_INT(AF_INET6, ep.family);
|
||||||
|
}
|
||||||
|
|
||||||
Test *tests_sock_util_all(void)
|
Test *tests_sock_util_all(void)
|
||||||
{
|
{
|
||||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||||
@ -228,8 +285,14 @@ Test *tests_sock_util_all(void)
|
|||||||
new_TestFixture(test_sock_util_str2ep__ipv4_noport),
|
new_TestFixture(test_sock_util_str2ep__ipv4_noport),
|
||||||
new_TestFixture(test_sock_util_str2ep__ipv4_port),
|
new_TestFixture(test_sock_util_str2ep__ipv4_port),
|
||||||
new_TestFixture(test_sock_util_str2ep__ipv4_bracketed),
|
new_TestFixture(test_sock_util_str2ep__ipv4_bracketed),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__invalid_bracket_missing),
|
||||||
new_TestFixture(test_sock_util_str2ep__invalid_ipv6),
|
new_TestFixture(test_sock_util_str2ep__invalid_ipv6),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__invalid_netif),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__invalid_netif_missing),
|
||||||
new_TestFixture(test_sock_util_str2ep__invalid_port),
|
new_TestFixture(test_sock_util_str2ep__invalid_port),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__netif),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__netif_with_port),
|
||||||
|
new_TestFixture(test_sock_util_str2ep__netif_with_global_addr),
|
||||||
};
|
};
|
||||||
|
|
||||||
EMB_UNIT_TESTCALLER(sockutil_tests, setup, NULL, fixtures);
|
EMB_UNIT_TESTCALLER(sockutil_tests, setup, NULL, fixtures);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user