Merge pull request #16634 from benpicco/gnrc_netif_parse_hostname
netutils: add netutils_parse_hostname()
This commit is contained in:
commit
7793098ed8
@ -22,6 +22,7 @@ USEMODULE += gnrc_icmpv6_echo
|
|||||||
# Required by gcoap example
|
# Required by gcoap example
|
||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
USEMODULE += fmt
|
USEMODULE += fmt
|
||||||
|
USEMODULE += netutils
|
||||||
# Add also the shell, some shell commands
|
# Add also the shell, some shell commands
|
||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
USEMODULE += shell_commands
|
USEMODULE += shell_commands
|
||||||
|
|||||||
@ -24,6 +24,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "net/gcoap.h"
|
#include "net/gcoap.h"
|
||||||
|
#include "net/utils.h"
|
||||||
#include "od.h"
|
#include "od.h"
|
||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
|
|
||||||
@ -254,40 +255,17 @@ static ssize_t _riot_board_handler(coap_pkt_t *pdu, uint8_t *buf, size_t len, vo
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool _parse_endpoint(sock_udp_ep_t *remote,
|
static bool _parse_endpoint(sock_udp_ep_t *remote,
|
||||||
char *addr_str, char *port_str)
|
const char *addr_str, const char *port_str)
|
||||||
{
|
{
|
||||||
ipv6_addr_t addr;
|
netif_t *netif;
|
||||||
remote->family = AF_INET6;
|
|
||||||
|
|
||||||
/* parse for interface */
|
/* parse hostname */
|
||||||
char *iface = ipv6_addr_split_iface(addr_str);
|
if (netutils_get_ipv6((ipv6_addr_t *)&remote->addr, &netif, addr_str) < 0) {
|
||||||
if (!iface) {
|
|
||||||
if (gnrc_netif_numof() == 1) {
|
|
||||||
/* assign the single interface found in gnrc_netif_numof() */
|
|
||||||
remote->netif = (uint16_t)gnrc_netif_iter(NULL)->pid;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
remote->netif = SOCK_ADDR_ANY_NETIF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int pid = atoi(iface);
|
|
||||||
if (gnrc_netif_get_by_pid(pid) == NULL) {
|
|
||||||
puts("gcoap_cli: interface not valid");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
remote->netif = pid;
|
|
||||||
}
|
|
||||||
/* parse destination address */
|
|
||||||
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
|
||||||
puts("gcoap_cli: unable to parse destination address");
|
puts("gcoap_cli: unable to parse destination address");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if ((remote->netif == SOCK_ADDR_ANY_NETIF) && ipv6_addr_is_link_local(&addr)) {
|
remote->netif = netif ? netif_get_id(netif) : SOCK_ADDR_ANY_NETIF;
|
||||||
puts("gcoap_cli: must specify interface for link local target");
|
remote->family = AF_INET6;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(&remote->addr.ipv6[0], &addr.u8[0], sizeof(addr.u8));
|
|
||||||
|
|
||||||
/* parse port */
|
/* parse port */
|
||||||
remote->port = atoi(port_str);
|
remote->port = atoi(port_str);
|
||||||
|
|||||||
@ -22,6 +22,7 @@ USEMODULE += gnrc_icmpv6_echo
|
|||||||
# Required by gcoap example
|
# Required by gcoap example
|
||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
USEMODULE += fmt
|
USEMODULE += fmt
|
||||||
|
USEMODULE += netutils
|
||||||
# Add also the shell, some shell commands
|
# Add also the shell, some shell commands
|
||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
USEMODULE += shell_commands
|
USEMODULE += shell_commands
|
||||||
|
|||||||
@ -23,6 +23,7 @@ USEMODULE += auto_init_gnrc_rpl
|
|||||||
USEMODULE += gnrc_pktdump
|
USEMODULE += gnrc_pktdump
|
||||||
# Additional networking modules that can be dropped if not needed
|
# Additional networking modules that can be dropped if not needed
|
||||||
USEMODULE += gnrc_icmpv6_echo
|
USEMODULE += gnrc_icmpv6_echo
|
||||||
|
USEMODULE += netutils
|
||||||
# Add also the shell, some shell commands
|
# Add also the shell, some shell commands
|
||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
USEMODULE += shell_commands
|
USEMODULE += shell_commands
|
||||||
|
|||||||
@ -28,6 +28,7 @@
|
|||||||
#include "net/gnrc/netif/hdr.h"
|
#include "net/gnrc/netif/hdr.h"
|
||||||
#include "net/gnrc/udp.h"
|
#include "net/gnrc/udp.h"
|
||||||
#include "net/gnrc/pktdump.h"
|
#include "net/gnrc/pktdump.h"
|
||||||
|
#include "net/utils.h"
|
||||||
#include "timex.h"
|
#include "timex.h"
|
||||||
#include "utlist.h"
|
#include "utlist.h"
|
||||||
#if IS_USED(MODULE_ZTIMER_MSEC)
|
#if IS_USED(MODULE_ZTIMER_MSEC)
|
||||||
@ -43,21 +44,12 @@ static gnrc_netreg_entry_t server =
|
|||||||
static void send(char *addr_str, char *port_str, char *data, unsigned int num,
|
static void send(char *addr_str, char *port_str, char *data, unsigned int num,
|
||||||
unsigned int delay)
|
unsigned int delay)
|
||||||
{
|
{
|
||||||
gnrc_netif_t *netif = NULL;
|
netif_t *netif;
|
||||||
char *iface;
|
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
ipv6_addr_t addr;
|
ipv6_addr_t addr;
|
||||||
|
|
||||||
iface = ipv6_addr_split_iface(addr_str);
|
|
||||||
if ((!iface) && (gnrc_netif_numof() == 1)) {
|
|
||||||
netif = gnrc_netif_iter(NULL);
|
|
||||||
}
|
|
||||||
else if (iface) {
|
|
||||||
netif = gnrc_netif_get_by_pid(atoi(iface));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* parse destination address */
|
/* parse destination address */
|
||||||
if (ipv6_addr_from_str(&addr, addr_str) == NULL) {
|
if (netutils_get_ipv6(&addr, &netif, addr_str) < 0) {
|
||||||
puts("Error: unable to parse destination address");
|
puts("Error: unable to parse destination address");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -97,7 +89,8 @@ static void send(char *addr_str, char *port_str, char *data, unsigned int num,
|
|||||||
if (netif != NULL) {
|
if (netif != NULL) {
|
||||||
gnrc_pktsnip_t *netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
|
gnrc_pktsnip_t *netif_hdr = gnrc_netif_hdr_build(NULL, 0, NULL, 0);
|
||||||
|
|
||||||
gnrc_netif_hdr_set_netif(netif_hdr->data, netif);
|
gnrc_netif_hdr_set_netif(netif_hdr->data,
|
||||||
|
container_of(netif, gnrc_netif_t, netif));
|
||||||
ip = gnrc_pkt_prepend(ip, netif_hdr);
|
ip = gnrc_pkt_prepend(ip, netif_hdr);
|
||||||
}
|
}
|
||||||
/* send packet */
|
/* send packet */
|
||||||
|
|||||||
@ -113,6 +113,9 @@ endif
|
|||||||
ifneq (,$(filter netstats_neighbor,$(USEMODULE)))
|
ifneq (,$(filter netstats_neighbor,$(USEMODULE)))
|
||||||
DIRS += net/netstats
|
DIRS += net/netstats
|
||||||
endif
|
endif
|
||||||
|
ifneq (,$(filter netutils,$(USEMODULE)))
|
||||||
|
DIRS += net/netutils
|
||||||
|
endif
|
||||||
ifneq (,$(filter sema,$(USEMODULE)))
|
ifneq (,$(filter sema,$(USEMODULE)))
|
||||||
DIRS += sema
|
DIRS += sema
|
||||||
endif
|
endif
|
||||||
|
|||||||
@ -185,6 +185,10 @@ ifneq (,$(filter od_string,$(USEMODULE)))
|
|||||||
USEMODULE += od
|
USEMODULE += od
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter netutils,$(USEMODULE)))
|
||||||
|
USEMODULE += ipv6_addr
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter newlib_gnu_source,$(USEMODULE)))
|
ifneq (,$(filter newlib_gnu_source,$(USEMODULE)))
|
||||||
FEATURES_REQUIRED += newlib
|
FEATURES_REQUIRED += newlib
|
||||||
endif
|
endif
|
||||||
@ -252,6 +256,10 @@ ifneq (,$(filter shell_commands,$(USEMODULE)))
|
|||||||
USEMODULE += posix_inet
|
USEMODULE += posix_inet
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (,$(filter gnrc_icmpv6_echo,$(USEMODULE)))
|
||||||
|
USEMODULE += netutils
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter nimble_netif,$(USEMODULE)))
|
ifneq (,$(filter nimble_netif,$(USEMODULE)))
|
||||||
USEMODULE += nimble_scanner
|
USEMODULE += nimble_scanner
|
||||||
USEMODULE += nimble_scanlist
|
USEMODULE += nimble_scanlist
|
||||||
|
|||||||
52
sys/include/net/utils.h
Normal file
52
sys/include/net/utils.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 ML!PA Consulting GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup net_utils Network helper functions
|
||||||
|
* @ingroup net
|
||||||
|
* @brief Common network helper functions
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Common network interface API definitions
|
||||||
|
*
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NET_UTILS_H
|
||||||
|
#define NET_UTILS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "net/ipv6/addr.h"
|
||||||
|
#include "net/netif.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse an IPv6 address / hostname string.
|
||||||
|
* If the @ref net_sock_dns module is used, this will
|
||||||
|
* attempt to resolve hostnames via DNS to IPv6 addresses.
|
||||||
|
*
|
||||||
|
* @param[out] addr IPv6 address of the host
|
||||||
|
* @param[out] netif Interface if address is link-local
|
||||||
|
* @param[in] hostname IPv6 address string or hostname
|
||||||
|
*
|
||||||
|
* @return 0 on success, error otherwise
|
||||||
|
*/
|
||||||
|
int netutils_get_ipv6(ipv6_addr_t *addr, netif_t **netif, const char *hostname);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* NET_UTILS_H */
|
||||||
|
/** @} */
|
||||||
3
sys/net/netutils/Makefile
Normal file
3
sys/net/netutils/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
MODULE = netutils
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.base
|
||||||
78
sys/net/netutils/util.c
Normal file
78
sys/net/netutils/util.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 ML!PA Consulting GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "net/utils.h"
|
||||||
|
#ifdef MODULE_SOCK_DNS
|
||||||
|
#include "net/af.h"
|
||||||
|
#include "net/sock/dns.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* get the next netif, returns true if there are more */
|
||||||
|
static bool _netif_get(netif_t **current_netif)
|
||||||
|
{
|
||||||
|
netif_t *netif = *current_netif;
|
||||||
|
netif = netif_iter(netif);
|
||||||
|
|
||||||
|
*current_netif = netif;
|
||||||
|
return netif_iter(netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
int netutils_get_ipv6(ipv6_addr_t *addr, netif_t **netif, const char *hostname)
|
||||||
|
{
|
||||||
|
*netif = NULL;
|
||||||
|
|
||||||
|
if (hostname == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_SOCK_DNS
|
||||||
|
/* hostname is not an IPv6 address */
|
||||||
|
if (strchr(hostname, ':') == NULL) {
|
||||||
|
int res = sock_dns_query(hostname, addr, AF_INET6);
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* search for interface ID */
|
||||||
|
size_t len = strlen(hostname);
|
||||||
|
char *iface = strchr(hostname, '%');
|
||||||
|
if (iface) {
|
||||||
|
*netif = netif_get_by_id(atoi(iface + 1));
|
||||||
|
len -= strlen(iface);
|
||||||
|
|
||||||
|
if (*netif == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* preliminary select the first interface */
|
||||||
|
else if (_netif_get(netif)) {
|
||||||
|
/* don't take it if there is more than one interface */
|
||||||
|
*netif = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipv6_addr_from_buf(addr, hostname, len) == NULL) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
@ -37,11 +37,9 @@
|
|||||||
#ifdef MODULE_GNRC_IPV6_NIB
|
#ifdef MODULE_GNRC_IPV6_NIB
|
||||||
#include "net/gnrc/ipv6/nib/nc.h"
|
#include "net/gnrc/ipv6/nib/nc.h"
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULE_SOCK_DNS
|
|
||||||
#include "net/sock/dns.h"
|
|
||||||
#endif
|
|
||||||
#include "net/icmpv6.h"
|
#include "net/icmpv6.h"
|
||||||
#include "net/ipv6.h"
|
#include "net/ipv6.h"
|
||||||
|
#include "net/utils.h"
|
||||||
#include "timex.h"
|
#include "timex.h"
|
||||||
#include "unaligned.h"
|
#include "unaligned.h"
|
||||||
#include "utlist.h"
|
#include "utlist.h"
|
||||||
@ -167,16 +165,6 @@ static void _usage(char *cmdname)
|
|||||||
"of any responses, otherwise wait for two RTTs");
|
"of any responses, otherwise wait for two RTTs");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the next netif, returns true if there are more */
|
|
||||||
static bool _netif_get(gnrc_netif_t **current_netif)
|
|
||||||
{
|
|
||||||
gnrc_netif_t *netif = *current_netif;
|
|
||||||
netif = gnrc_netif_iter(netif);
|
|
||||||
|
|
||||||
*current_netif = netif;
|
|
||||||
return !gnrc_netif_highlander() && gnrc_netif_iter(netif);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _configure(int argc, char **argv, _ping_data_t *data)
|
static int _configure(int argc, char **argv, _ping_data_t *data)
|
||||||
{
|
{
|
||||||
char *cmdname = argv[0];
|
char *cmdname = argv[0];
|
||||||
@ -188,27 +176,11 @@ static int _configure(int argc, char **argv, _ping_data_t *data)
|
|||||||
if (arg[0] != '-') {
|
if (arg[0] != '-') {
|
||||||
|
|
||||||
data->hostname = arg;
|
data->hostname = arg;
|
||||||
#ifdef MODULE_SOCK_DNS
|
|
||||||
if (strchr(data->hostname, ':') == NULL &&
|
|
||||||
sock_dns_query(data->hostname, &data->host, AF_INET6) > 0) {
|
|
||||||
res = 0;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
char *iface = ipv6_addr_split_iface(data->hostname);
|
|
||||||
if (iface) {
|
|
||||||
data->netif = gnrc_netif_get_by_pid(atoi(iface));
|
|
||||||
}
|
|
||||||
/* preliminary select the first interface */
|
|
||||||
else if (_netif_get(&data->netif)) {
|
|
||||||
/* don't take it if there is more than one interface */
|
|
||||||
data->netif = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ipv6_addr_from_str(&data->host, data->hostname) == NULL) {
|
res = netutils_get_ipv6(&data->host, (netif_t **)&data->netif, arg);
|
||||||
|
if (res) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
res = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (arg[1]) {
|
switch (arg[1]) {
|
||||||
|
|||||||
14
tests/netutils/Makefile
Normal file
14
tests/netutils/Makefile
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
include ../Makefile.tests_common
|
||||||
|
|
||||||
|
USEMODULE += netutils
|
||||||
|
USEMODULE += netif
|
||||||
|
USEMODULE += embunit
|
||||||
|
|
||||||
|
# make sure we have an implementation of sock_types.h
|
||||||
|
USEMODULE += gnrc_sock_udp
|
||||||
|
USEMODULE += gnrc_ipv6
|
||||||
|
|
||||||
|
# pretend to include sock_dns
|
||||||
|
CFLAGS += -DMODULE_SOCK_DNS=1
|
||||||
|
|
||||||
|
include $(RIOTBASE)/Makefile.include
|
||||||
28
tests/netutils/Makefile.ci
Normal file
28
tests/netutils/Makefile.ci
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
BOARD_INSUFFICIENT_MEMORY := \
|
||||||
|
arduino-duemilanove \
|
||||||
|
arduino-leonardo \
|
||||||
|
arduino-mega2560 \
|
||||||
|
arduino-nano \
|
||||||
|
arduino-uno \
|
||||||
|
atmega328p-xplained-mini \
|
||||||
|
atmega328p \
|
||||||
|
atxmega-a1u-xpro \
|
||||||
|
bluepill-stm32f030c8 \
|
||||||
|
i-nucleo-lrwan1 \
|
||||||
|
msb-430 \
|
||||||
|
msb-430h \
|
||||||
|
nucleo-f030r8 \
|
||||||
|
nucleo-f031k6 \
|
||||||
|
nucleo-f042k6 \
|
||||||
|
nucleo-l011k4 \
|
||||||
|
nucleo-l031k6 \
|
||||||
|
nucleo-l053r8 \
|
||||||
|
samd10-xmini \
|
||||||
|
slstk3400a \
|
||||||
|
stk3200 \
|
||||||
|
stm32f030f4-demo \
|
||||||
|
stm32f0discovery \
|
||||||
|
stm32l0538-disco \
|
||||||
|
telosb \
|
||||||
|
waspmote-pro \
|
||||||
|
#
|
||||||
157
tests/netutils/main.c
Normal file
157
tests/netutils/main.c
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Copyright (C) 2021 ML!PA Consulting GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
*
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
|
*/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "embUnit.h"
|
||||||
|
|
||||||
|
#include "net/gnrc/netif.h"
|
||||||
|
#include "net/utils.h"
|
||||||
|
|
||||||
|
static gnrc_netif_t dummy_netif[2];
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__one_colon_start(void)
|
||||||
|
{
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, ":ff::1"), -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__three_colons(void)
|
||||||
|
{
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, "ff02:::1"), -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__illegal_chars(void)
|
||||||
|
{
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, ":-D"), -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__addr_NULL(void)
|
||||||
|
{
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, NULL), -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__address_NULL(void)
|
||||||
|
{
|
||||||
|
TEST_ASSERT_NULL(ipv6_addr_from_str(NULL, "::"));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__success(void)
|
||||||
|
{
|
||||||
|
static const ipv6_addr_t a = { {
|
||||||
|
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||||
|
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, "1:203:405:607:809:a0b:c0d:e0f"), 0);
|
||||||
|
TEST_ASSERT(ipv6_addr_equal(&a, &address));
|
||||||
|
TEST_ASSERT_NULL(netif);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__success2(void)
|
||||||
|
{
|
||||||
|
static const ipv6_addr_t a = { {
|
||||||
|
0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, "fe80::f8f9:fafb:fcfd:feff%1"), 0);
|
||||||
|
TEST_ASSERT_EQUAL_INT((uintptr_t)netif, (uintptr_t)&dummy_netif[1]);
|
||||||
|
TEST_ASSERT(ipv6_addr_equal(&a, &address));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__invalid_interface(void)
|
||||||
|
{
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, "fe80::f8f9:fafb:fcfd:feff%3"), -EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__success4(void)
|
||||||
|
{
|
||||||
|
static const ipv6_addr_t a = { {
|
||||||
|
0x26, 0x06, 0x28, 0x00, 0x02, 0x20, 0x00, 0x01,
|
||||||
|
0x02, 0x48, 0x18, 0x93, 0x25, 0xc8, 0x19, 0x46
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ipv6_addr_t address;
|
||||||
|
netif_t *netif;
|
||||||
|
|
||||||
|
TEST_ASSERT_EQUAL_INT(netutils_get_ipv6(&address, &netif, "example.com"), 0);
|
||||||
|
TEST_ASSERT(ipv6_addr_equal(&a, &address));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_ipv6_addr_from_str__success5(void)
|
||||||
|
{
|
||||||
|
static const ipv6_addr_t a = IPV6_ADDR_LOOPBACK;
|
||||||
|
ipv6_addr_t address;
|
||||||
|
|
||||||
|
TEST_ASSERT_NOT_NULL(ipv6_addr_from_str(&address, "::1"));
|
||||||
|
TEST_ASSERT(ipv6_addr_equal(&a, &address));
|
||||||
|
}
|
||||||
|
|
||||||
|
Test *tests_netutils_tests(void)
|
||||||
|
{
|
||||||
|
for (unsigned i = 0; i < ARRAY_SIZE(dummy_netif); ++i) {
|
||||||
|
netif_register(&dummy_netif[i].netif);
|
||||||
|
dummy_netif[i].pid = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
EMB_UNIT_TESTFIXTURES(fixtures) {
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__one_colon_start),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__three_colons),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__illegal_chars),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__addr_NULL),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__address_NULL),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__success),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__success2),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__invalid_interface),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__success4),
|
||||||
|
new_TestFixture(test_ipv6_addr_from_str__success5),
|
||||||
|
};
|
||||||
|
|
||||||
|
EMB_UNIT_TESTCALLER(ipv6_addr_tests, NULL, NULL, fixtures);
|
||||||
|
|
||||||
|
return (Test *)&ipv6_addr_tests;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
TESTS_START();
|
||||||
|
TESTS_RUN(tests_netutils_tests());
|
||||||
|
TESTS_END();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
43
tests/netutils/mock_dns.c
Normal file
43
tests/netutils/mock_dns.c
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 ML!PA Consulting GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
* General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
* directory for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Mock implementation of sock_dns
|
||||||
|
*
|
||||||
|
* @author Benjamin Valentin <benjamin.valentin@ml-pa.com>
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "net/af.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 = { {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
/** @} */
|
||||||
14
tests/netutils/tests/01-run.py
Executable file
14
tests/netutils/tests/01-run.py
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (C) 2017 Freie Universität Berlin
|
||||||
|
#
|
||||||
|
# This file is subject to the terms and conditions of the GNU Lesser
|
||||||
|
# General Public License v2.1. See the file LICENSE in the top level
|
||||||
|
# directory for more details.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from testrunner import run_check_unittests
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(run_check_unittests())
|
||||||
@ -14,6 +14,8 @@ BOARD_INSUFFICIENT_MEMORY := \
|
|||||||
nucleo-f302r8 \
|
nucleo-f302r8 \
|
||||||
nucleo-f303k8 \
|
nucleo-f303k8 \
|
||||||
nucleo-f334r8 \
|
nucleo-f334r8 \
|
||||||
|
nucleo-g070rb \
|
||||||
|
nucleo-g071rb \
|
||||||
nucleo-l031k6 \
|
nucleo-l031k6 \
|
||||||
nucleo-l053r8 \
|
nucleo-l053r8 \
|
||||||
saml10-xpro \
|
saml10-xpro \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user