1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/net/netutils: add netutils_get_ipv4()

This commit is contained in:
Hendrik van Essen 2022-03-06 15:41:57 +01:00
parent a3faa79612
commit ffd93c9b1b
5 changed files with 136 additions and 10 deletions

View File

@ -16,6 +16,7 @@
* @brief Common network interface API definitions
*
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*/
#ifndef NET_UTILS_H
@ -24,6 +25,7 @@
#include <stdint.h>
#include <stddef.h>
#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
#include "net/netif.h"
@ -31,6 +33,18 @@
extern "C" {
#endif
/**
* @brief Parse an IPv4 address / hostname string.
* If the @ref net_sock_dns module is used, this will
* attempt to resolve hostnames via DNS to IPv4 addresses.
*
* @param[out] addr IPv4 address of the host
* @param[in] hostname IPv4 address string or hostname
*
* @return 0 on success, error otherwise
*/
int netutils_get_ipv4(ipv4_addr_t *addr, const char *hostname);
/**
* @brief Parse an IPv6 address / hostname string.
* If the @ref net_sock_dns module is used, this will

View File

@ -11,6 +11,7 @@
*
* @file
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
* @author Hendrik van Essen <hendrik.ve@fu-berlin.de>
*/
#include <errno.h>
@ -34,6 +35,40 @@ static bool _netif_get(netif_t **current_netif)
return netif_iter(netif);
}
int netutils_get_ipv4(ipv4_addr_t *addr, const char *hostname)
{
if (hostname == NULL) {
return -EINVAL;
}
for (size_t i = 0; i < strlen(hostname); i++) {
bool is_not_ipv4 = (hostname[i] < '0' || hostname[i] > '9') && hostname[i] != '.';
#ifdef MODULE_SOCK_DNS
/* once we see an invalid character for an IPv4 address try to
* resolve the hostname by DNS */
if (is_not_ipv4) {
int res = sock_dns_query(hostname, addr, AF_INET);
if (res < 0) {
return res;
}
return 0;
}
#else
if (is_not_ipv4) {
return -EINVAL;
}
#endif
}
size_t len = strlen(hostname);
if (ipv4_addr_from_buf(addr, hostname, len) == NULL) {
return -EINVAL;
}
return 0;
}
int netutils_get_ipv6(ipv6_addr_t *addr, netif_t **netif, const char *hostname)
{
*netif = NULL;
@ -71,7 +106,7 @@ int netutils_get_ipv6(ipv6_addr_t *addr, netif_t **netif, const char *hostname)
}
if (ipv6_addr_from_buf(addr, hostname, len) == NULL) {
return -EINVAL;
return -EINVAL;
}
return 0;

View File

@ -8,6 +8,9 @@ USEMODULE += embunit
USEMODULE += gnrc_sock_udp
USEMODULE += gnrc_ipv6
USEMODULE += ipv4_addr
USEMODULE += ipv6_addr
# pretend to include sock_dns
CFLAGS += -DMODULE_SOCK_DNS=1

View File

@ -121,7 +121,73 @@ static void test_ipv6_addr_from_str__success5(void)
TEST_ASSERT(ipv6_addr_equal(&a, &address));
}
Test *tests_netutils_tests(void)
static void test_ipv4_addr_from_str__missing_parts(void)
{
ipv4_addr_t address;
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1"), -EINVAL);
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1."), -EINVAL);
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1.2"), -EINVAL);
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1.2."), -EINVAL);
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1.2.3"), -EINVAL);
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1.2.3."), -EINVAL);
}
static void test_ipv4_addr_from_str__illegal_chars(void)
{
ipv4_addr_t address;
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, ":-D"), -ENOTSUP);
}
static void test_ipv4_addr_from_str__addr_NULL(void)
{
ipv4_addr_t address;
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, NULL), -EINVAL);
}
static void test_ipv4_addr_from_str__address_NULL(void)
{
TEST_ASSERT_NULL(ipv4_addr_from_str(NULL, "1.2.3.4"));
}
static void test_ipv4_addr_from_str__success(void)
{
static const ipv4_addr_t a = { { 0x01, 0x02, 0x03, 0x04 } };
ipv4_addr_t address;
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "1.2.3.4"), 0);
TEST_ASSERT(ipv4_addr_equal(&a, &address));
}
static void test_ipv4_addr_from_str__success2(void)
{
static const ipv4_addr_t a = { { 0x5d, 0xb8, 0xd8, 0x22 } };
ipv4_addr_t address;
TEST_ASSERT_EQUAL_INT(netutils_get_ipv4(&address, "example.com"), 0);
TEST_ASSERT(ipv4_addr_equal(&a, &address));
}
Test *tests_netutils_ipv4_tests(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
/* IPv4 tests */
new_TestFixture(test_ipv4_addr_from_str__missing_parts),
new_TestFixture(test_ipv4_addr_from_str__illegal_chars),
new_TestFixture(test_ipv4_addr_from_str__addr_NULL),
new_TestFixture(test_ipv4_addr_from_str__address_NULL),
new_TestFixture(test_ipv4_addr_from_str__success),
new_TestFixture(test_ipv4_addr_from_str__success2),
};
EMB_UNIT_TESTCALLER(ipv4_addr_tests, NULL, NULL, fixtures);
return (Test *)&ipv4_addr_tests;
}
Test *tests_netutils_ipv6_tests(void)
{
for (unsigned i = 0; i < ARRAY_SIZE(dummy_netif); ++i) {
netif_register(&dummy_netif[i].netif);
@ -149,7 +215,8 @@ Test *tests_netutils_tests(void)
int main(void)
{
TESTS_START();
TESTS_RUN(tests_netutils_tests());
TESTS_RUN(tests_netutils_ipv4_tests());
TESTS_RUN(tests_netutils_ipv6_tests());
TESTS_END();
return 0;

View File

@ -17,26 +17,33 @@
#include <string.h>
#include "net/af.h"
#include "net/ipv4/addr.h"
#include "net/ipv6/addr.h"
#include "net/sock/dns.h"
int sock_dns_query(const char *domain_name, void *addr_out, int family)
{
const ipv6_addr_t a = { {
const ipv4_addr_t addr_ipv4 = { { 0x5d, 0xb8, 0xd8, 0x22 } };
const ipv6_addr_t addr_ipv6 = { {
0x26, 0x06, 0x28, 0x00, 0x02, 0x20, 0x00, 0x01,
0x02, 0x48, 0x18, 0x93, 0x25, 0xc8, 0x19, 0x46
}
};
if (family != AF_INET6) {
return -EAFNOSUPPORT;
}
if (strcmp(domain_name, "example.com")) {
return -ENOTSUP;
}
memcpy(addr_out, &a, sizeof(a));
return 0;
switch (family) {
case AF_INET:
memcpy(addr_out, &addr_ipv4, sizeof(addr_ipv4));
return 0;
case AF_INET6:
memcpy(addr_out, &addr_ipv6, sizeof(addr_ipv6));
return 0;
default:
return -EAFNOSUPPORT;
}
}
/** @} */