Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions tests/gnrc_ipv6_nib_dns/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
include ../Makefile.tests_common

RIOTBASE ?= $(CURDIR)/../..

export TAP ?= tap0

USEMODULE += sock_dns
USEMODULE += gnrc_sock_udp
USEMODULE += gnrc_ipv6_default
USEMODULE += gnrc_ipv6_nib_dns
# use Ethernet as link-layer protocol
ifeq (native,$(BOARD))
TERMFLAGS ?= $(TAP)
else
ETHOS_BAUDRATE ?= 115200
CFLAGS += -DETHOS_BAUDRATE=$(ETHOS_BAUDRATE)
TERMDEPS += ethos
TERMPROG ?= sudo $(RIOTTOOLS)/ethos/ethos
TERMFLAGS ?= $(TAP) $(PORT) $(ETHOS_BAUDRATE)
endif
USEMODULE += auto_init_gnrc_netif

USEMODULE += shell
USEMODULE += shell_commands

USEMODULE += posix_inet

LOW_MEMORY_BOARDS := nucleo-f334r8 msb-430 msb-430h

ifeq ($(BOARD),$(filter $(BOARD),$(LOW_MEMORY_BOARDS)))
CFLAGS += -DGNRC_PKTBUF_SIZE=512 -DCONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF=2 \
-DGNRC_NETIF_IPV6_GROUPS_NUMOF=2 -DGNRC_IPV6_NIB_NUMOF=1 \
-DNRC_IPV6_NIB_OFFL_NUMOF=1
endif

# The test requires some setup and to be run as root
# So it cannot currently be run
TEST_ON_CI_BLACKLIST += all

.PHONY: ethos

ethos:
$(Q)env -u CC -u CFLAGS make -C $(RIOTTOOLS)/ethos

include $(RIOTBASE)/Makefile.include
6 changes: 6 additions & 0 deletions tests/gnrc_ipv6_nib_dns/Makefile.board.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Put board specific dependencies here
ifeq (native,$(BOARD))
USEMODULE += netdev_tap
else
USEMODULE += stdio_ethos
endif
28 changes: 28 additions & 0 deletions tests/gnrc_ipv6_nib_dns/Makefile.ci
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BOARD_INSUFFICIENT_MEMORY := \
arduino-duemilanove \
arduino-leonardo \
arduino-mega2560 \
arduino-nano \
arduino-uno \
atmega1284p \
atmega328p \
derfmega128 \
i-nucleo-lrwan1 \
mega-xplained \
microduino-corerf \
msb-430 \
msb-430h \
nucleo-f030r8 \
nucleo-f031k6 \
nucleo-f042k6 \
nucleo-f303k8 \
nucleo-l031k6 \
nucleo-l053r8 \
stm32f030f4-demo \
stm32f0discovery \
stm32l0538-disco \
telosb \
waspmote-pro \
wsn430-v1_3b \
wsn430-v1_4 \
#
23 changes: 23 additions & 0 deletions tests/gnrc_ipv6_nib_dns/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Overview

This test utilizes [scapy] to test GNRC's RDNSS option implementation for
router advertisements

To test, compile and flash the application to any board of your liking (since
`ethos` is used to communicate with non-native boards it really doesn't matter
as long as the application fits and the board is supported).

make flash

And run the tests using

```
sudo make test
```

Note that root privileges are required since `scapy` needs to construct Ethernet
frames to properly communicate over the TAP interface.

The test passes on success, on failure an exception is shown.

[scapy]: https://scapy.readthedocs.io/en/latest/
82 changes: 82 additions & 0 deletions tests/gnrc_ipv6_nib_dns/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2017 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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.
*/

/**
* @ingroup tests
* @{
*
* @file
* @brief sock DNS client test application
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/

#include <stdio.h>
#include <string.h>

#include <arpa/inet.h>

#include "net/sock/dns.h"
#include "shell.h"

#define MAIN_QUEUE_SIZE (8)
static int _dns(int argc, char **argv);

static const shell_command_t _shell_commands[] = {
{ "dns", "configures and requests a DNS server", _dns },
{ NULL, NULL, NULL },
};
static char _shell_buffer[SHELL_DEFAULT_BUFSIZE];

static void _usage(char *cmd)
{
printf("usage: %s server\n", cmd);
}

static int _dns_server(int argc, char **argv)
{
int res = (argc < 2);

if (!res) {
if (sock_dns_server.port > 0) {
char addrstr[INET6_ADDRSTRLEN];

inet_ntop(AF_INET6, sock_dns_server.addr.ipv6, addrstr,
sizeof(addrstr));
printf("DNS server: [%s%%%d]:%u\n", addrstr, sock_dns_server.netif,
sock_dns_server.port);
}
else {
puts("DNS server: -");
}
}
else {
_usage(argv[0]);
}
return res;
}

static int _dns(int argc, char **argv)
{
if ((argc > 1) && (strcmp(argv[1], "server") == 0)) {
return _dns_server(argc, argv);
}
else {
_usage(argv[0]);
return 1;
}
}

int main(void)
{
/* start shell */
shell_run(_shell_commands, _shell_buffer, sizeof(_shell_buffer));
return 0;
}
81 changes: 81 additions & 0 deletions tests/gnrc_ipv6_nib_dns/tests/01-run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#!/usr/bin/env python3

# Copyright (C) 2018 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 os
import re
import sys
import subprocess

from scapy.all import Ether, IPv6, ICMPv6ND_RA, ICMPv6NDOptRDNSS, sendp
from testrunner import run


def check_and_search_output(cmd, pattern, res_group, *args, **kwargs):
output = subprocess.check_output(cmd, *args, **kwargs).decode("utf-8")
for line in output.splitlines():
m = re.search(pattern, line)
if m is not None:
return m.group(res_group)
return None


def get_bridge(tap):
res = check_and_search_output(
["bridge", "link"],
r"{}.+master\s+(?P<master>[^\s]+)".format(tap),
"master"
)
return tap if res is None else res


def get_host_lladdr(tap):
res = check_and_search_output(
["ip", "addr", "show", "dev", tap, "scope", "link"],
r"inet6\s+(?P<lladdr>[0-9A-Fa-f:]+)/\d+",
"lladdr"
)
if res is None:
raise AssertionError(
"Can't find host link-local address on interface {}".format(tap)
)
else:
return res


def dns_server(child):
child.sendline("dns server")
res = child.expect([r"DNS server: -",
r"DNS server: \[([0-9a-f:]+)%\d+\]:(\d+)"])
if res > 0:
return child.match.group(1), int(child.match.group(2))
else:
return None


DNS_ADDR = "2001:db8:affe::dead:beef"
DNS_PORT = 53


def testfunc(child):
tap = get_bridge(os.environ["TAP"])
lladdr_src = get_host_lladdr(tap)
child.sendline("ifconfig")
child.expect(r"HWaddr: (?P<hwaddr>[A-Fa-f:0-9]+)\s")
hwaddr_dst = child.match.group("hwaddr").lower()
child.expect(r"(?P<lladdr>fe80::[A-Fa-f:0-9]+)\s")
lladdr_dst = child.match.group("lladdr").lower()

assert dns_server(child) is None
sendp(Ether(dst=hwaddr_dst) / IPv6(dst=lladdr_dst, src=lladdr_src) /
ICMPv6ND_RA() / ICMPv6NDOptRDNSS(dns=[DNS_ADDR]),
iface=tap)
assert dns_server(child) == (DNS_ADDR, DNS_PORT)


if __name__ == "__main__":
sys.exit(run(testfunc, timeout=1, echo=True))