mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys/net/ipv6: add ipv6_addr_from_buf function
This allows to parse IPv6 address from strings that not end with '\0'.
This commit is contained in:
parent
4305fcc010
commit
f14c898dd0
@ -720,8 +720,8 @@ char *ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len
|
||||
* RFC 5952
|
||||
* </a>
|
||||
*
|
||||
* @param[in] result The resulting byte representation
|
||||
* @param[in] addr An IPv6 address string representation
|
||||
* @param[out] result The resulting byte representation
|
||||
* @param[in] addr An IPv6 address string representation
|
||||
*
|
||||
* @return @p result, on success
|
||||
* @return NULL, if @p addr was malformed
|
||||
@ -729,6 +729,27 @@ char *ipv6_addr_to_str(char *result, const ipv6_addr_t *addr, uint8_t result_len
|
||||
*/
|
||||
ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr);
|
||||
|
||||
/**
|
||||
* @brief Converts an IPv6 address from a buffer of characters to a
|
||||
* byte-represented IPv6 address
|
||||
*
|
||||
* @see <a href="https://tools.ietf.org/html/rfc5952">
|
||||
* RFC 5952
|
||||
* </a>
|
||||
*
|
||||
* @note @p addr_len should be between 0 and IPV6_ADDR_MAX_STR_LEN
|
||||
*
|
||||
* @param[out] result The resulting byte representation
|
||||
* @param[in] addr An IPv6 address string representation
|
||||
* @param[in] addr_len The amount of characters to parse
|
||||
*
|
||||
* @return @p result, on success
|
||||
* @return NULL, if @p addr was malformed
|
||||
* @return NULL, if @p result or @p addr was NULL
|
||||
*/
|
||||
ipv6_addr_t *ipv6_addr_from_buf(ipv6_addr_t *result, const char *addr,
|
||||
size_t addr_len);
|
||||
|
||||
/**
|
||||
* @brief split IPv6 address string representation and return remaining string
|
||||
*
|
||||
|
@ -38,18 +38,20 @@
|
||||
#define HEX_U "0123456789ABCDEF"
|
||||
|
||||
/* based on inet_pton6() by Paul Vixie */
|
||||
ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
|
||||
ipv6_addr_t *ipv6_addr_from_buf(ipv6_addr_t *result, const char *addr,
|
||||
size_t addr_len)
|
||||
{
|
||||
uint8_t *colonp = 0;
|
||||
const char *start = addr;
|
||||
#ifdef MODULE_IPV4_ADDR
|
||||
const char *curtok = addr;
|
||||
#endif
|
||||
uint32_t val = 0;
|
||||
char ch;
|
||||
uint8_t saw_xdigit = 0;
|
||||
uint8_t i = 0;
|
||||
|
||||
if ((result == NULL) || (addr == NULL)) {
|
||||
if ((result == NULL) || (addr == NULL) || (addr_len == 0) ||
|
||||
(addr_len > IPV6_ADDR_MAX_STR_LEN)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -62,7 +64,8 @@ ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
|
||||
}
|
||||
}
|
||||
|
||||
while ((ch = *addr++) != '\0') {
|
||||
while ((size_t)(addr - start) < addr_len) {
|
||||
char ch = *addr++;
|
||||
const char *pch;
|
||||
const char *xdigits;
|
||||
|
||||
@ -109,8 +112,8 @@ ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
|
||||
|
||||
#ifdef MODULE_IPV4_ADDR
|
||||
if (ch == '.' && ((i + sizeof(ipv4_addr_t)) <= sizeof(ipv6_addr_t)) &&
|
||||
ipv4_addr_from_str((ipv4_addr_t *)(&(result->u8[i])),
|
||||
curtok) != NULL) {
|
||||
ipv4_addr_from_buf((ipv4_addr_t *)(&(result->u8[i])),
|
||||
curtok, addr_len - (curtok - start)) != NULL) {
|
||||
i += sizeof(ipv4_addr_t);
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by ipv4_addr_from_str(). */
|
||||
@ -151,6 +154,15 @@ ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
|
||||
return result;
|
||||
}
|
||||
|
||||
ipv6_addr_t *ipv6_addr_from_str(ipv6_addr_t *result, const char *addr)
|
||||
{
|
||||
if ((result == NULL) || (addr == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ipv6_addr_from_buf(result, addr, strlen(addr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
@ -1056,6 +1056,30 @@ static void test_ipv6_addr_split_prefix__with_prefix(void)
|
||||
TEST_ASSERT_EQUAL_INT(strcmp("fd00:dead:beef::1", a), 0);
|
||||
}
|
||||
|
||||
static void test_ipv6_addr_from_buf__success(void)
|
||||
{
|
||||
ipv6_addr_t a = { {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 255, 255, 255, 255
|
||||
}
|
||||
};
|
||||
ipv6_addr_t result;
|
||||
|
||||
#ifdef MODULE_IPV4_ADDR
|
||||
TEST_ASSERT_NOT_NULL(ipv6_addr_from_buf(&result, "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255%tap0", 45));
|
||||
#else
|
||||
TEST_ASSERT_NOT_NULL(ipv6_addr_from_buf(&result, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff%tap0", 39));
|
||||
#endif
|
||||
TEST_ASSERT(ipv6_addr_equal(&a, &result));
|
||||
}
|
||||
|
||||
static void test_ipv6_addr_from_buf__too_long_len(void)
|
||||
{
|
||||
ipv6_addr_t result;
|
||||
|
||||
TEST_ASSERT_NULL(ipv6_addr_from_buf(&result, "::1", IPV6_ADDR_MAX_STR_LEN + 1));
|
||||
}
|
||||
|
||||
Test *tests_ipv6_addr_tests(void)
|
||||
{
|
||||
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||
@ -1148,6 +1172,8 @@ Test *tests_ipv6_addr_tests(void)
|
||||
new_TestFixture(test_ipv6_addr_split_iface__with_iface),
|
||||
new_TestFixture(test_ipv6_addr_split_prefix__no_prefix),
|
||||
new_TestFixture(test_ipv6_addr_split_prefix__with_prefix),
|
||||
new_TestFixture(test_ipv6_addr_from_buf__success),
|
||||
new_TestFixture(test_ipv6_addr_from_buf__too_long_len),
|
||||
};
|
||||
|
||||
EMB_UNIT_TESTCALLER(ipv6_addr_tests, NULL, NULL, fixtures);
|
||||
|
Loading…
Reference in New Issue
Block a user