From b2d6f4aed3a25d9e58db40e8e3fc3a4d1e6ca687 Mon Sep 17 00:00:00 2001
From: Yonezawa-T2 <Yonezawa-T2@mail.dnp.co.jp>
Date: Tue, 1 Mar 2016 19:28:55 +0900
Subject: [PATCH] tests: add a test application for gnrc_ipv6_ext

---
 tests/gnrc_ipv6_ext/Makefile        |  43 ++++++++++
 tests/gnrc_ipv6_ext/README.md       |  43 ++++++++++
 tests/gnrc_ipv6_ext/main.c          | 125 ++++++++++++++++++++++++++++
 tests/gnrc_ipv6_ext/tests/01-run.py |  38 +++++++++
 4 files changed, 249 insertions(+)
 create mode 100644 tests/gnrc_ipv6_ext/Makefile
 create mode 100644 tests/gnrc_ipv6_ext/README.md
 create mode 100644 tests/gnrc_ipv6_ext/main.c
 create mode 100755 tests/gnrc_ipv6_ext/tests/01-run.py

diff --git a/tests/gnrc_ipv6_ext/Makefile b/tests/gnrc_ipv6_ext/Makefile
new file mode 100644
index 0000000000..3a4db2d10e
--- /dev/null
+++ b/tests/gnrc_ipv6_ext/Makefile
@@ -0,0 +1,43 @@
+# name of your application
+APPLICATION = gnrc_ipv6_ext
+
+# If no BOARD is found in the environment, use this default:
+BOARD ?= native
+
+# This has to be the absolute path to the RIOT base directory:
+RIOTBASE ?= $(CURDIR)/../..
+
+BOARD_INSUFFICIENT_MEMORY := airfy-beacon chronos msb-430 msb-430h nrf51dongle \
+                          nrf6310 nucleo-f103 nucleo-f334 pca10000 pca10005 spark-core \
+                          stm32f0discovery telosb weio wsn430-v1_3b wsn430-v1_4 \
+                          yunjia-nrf51822 z1
+
+# Include packages that pull up and auto-init the link layer.
+# NOTE: 6LoWPAN will be included if IEEE802.15.4 devices are present
+USEMODULE += gnrc_netif_default
+USEMODULE += auto_init_gnrc_netif
+# Specify the mandatory networking modules for IPv6
+USEMODULE += gnrc_ipv6_router_default
+# IPv6 extension headers
+USEMODULE += gnrc_ipv6_ext
+USEMODULE += gnrc_rpl_srh
+# Add also the shell, some shell commands
+USEMODULE += shell
+USEMODULE += shell_commands
+USEMODULE += ps
+
+# Comment this out to disable code in RIOT that does safety checking
+# which is not needed in a production environment but helps in the
+# development process:
+CFLAGS += -DDEVELHELP
+
+# Change this to 0 show compiler invocation lines by default:
+QUIET ?= 1
+
+include $(RIOTBASE)/Makefile.include
+
+# This requires ENABLE_DEBUG in gnrc_ipv6.c to be 1
+test:
+# `testrunner` calls `make term` recursively, results in duplicated `TERMFLAGS`.
+# So clears `TERMFLAGS` before run.
+	TERMFLAGS= tests/01-run.py
diff --git a/tests/gnrc_ipv6_ext/README.md b/tests/gnrc_ipv6_ext/README.md
new file mode 100644
index 0000000000..89650e40fb
--- /dev/null
+++ b/tests/gnrc_ipv6_ext/README.md
@@ -0,0 +1,43 @@
+# `gnrc_ipv6_ext` test
+
+This test sends a packet to itself with extension headers. This is based on gnrc_networking example.
+
+Enable debug output of `gnrc_ipv6.c` before run. When the test is run, it should show the following debug output:
+
+```
+ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)
+ipv6: forward nh = 0 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 0)
+ipv6: forward nh = 43 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 43)
+ipv6: waiting for incoming message.
+ipv6: GNRC_NETAPI_MSG_TYPE_RCV received
+ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 40)
+ipv6: forward nh = 0 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 0)
+ipv6: forward nh = 43 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 43)
+ipv6: waiting for incoming message.
+ipv6: GNRC_NETAPI_MSG_TYPE_RCV received
+ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)
+ipv6: forward nh = 0 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 0)
+ipv6: forward nh = 43 to other threads
+ipv6: unable to forward packet as no one is interested in it
+ipv6: handle extension header (nh = 43)
+ipv6: forward nh = 17 to other threads
+ipv6: Send receive command for 0x1060b8 to 5
+ipv6: waiting for incoming message.
+pkt->users: 0
+```
+
+It configures the network interface with addresses fd01::02 and fd01::03. Then it sends a packet to fd01::02 with a routing extension header containing addresses fd01::03 and fd01::02. So the packet should be forwarded from fd01::02 to fd01::03, then to fd01::02 again.
+
+The packet has a Hop-by-Hop extension header that should be ignored.
+
+The test also asserts that the packet is released.
diff --git a/tests/gnrc_ipv6_ext/main.c b/tests/gnrc_ipv6_ext/main.c
new file mode 100644
index 0000000000..ddf0c939ae
--- /dev/null
+++ b/tests/gnrc_ipv6_ext/main.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2015 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.
+ */
+
+/**
+ * @ingroup     tests
+ * @{
+ *
+ * @file
+ * @brief       Tests extension header handling of gnrc stack.
+ *
+ * @author      Hauke Petersen <hauke.petersen@fu-berlin.de>
+ * @author      Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp>
+ *
+ * @}
+ */
+
+#include <stdio.h>
+
+#include "shell.h"
+#include "msg.h"
+#include "net/ipv6/addr.h"
+#include "net/gnrc/ipv6/netif.h"
+#include "net/gnrc/pkt.h"
+#include "net/gnrc/pktbuf.h"
+#include "net/gnrc/netreg.h"
+#include "net/gnrc/netapi.h"
+#include "net/gnrc/netif.h"
+
+#define MAIN_QUEUE_SIZE     (8)
+static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];
+
+static void _send_packet(void) {
+    kernel_pid_t ifs[GNRC_NETIF_NUMOF];
+    ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED;
+
+    gnrc_netif_get(ifs);
+
+    addr.u8[0] = 0xfd;
+    addr.u8[1] = 0x01;
+    addr.u8[15] = 0x02;
+    /* fd01::02 */
+    gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST);
+
+    addr.u8[15] = 0x03;
+    /* fd01::03 */
+    gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST);
+
+    uint8_t data[] = {
+        /* IPv6 Header */
+        0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */
+        0x00, 0x28, /* payload length: 40 */
+        0x00, /* next header: Hop-by-Hop Option */
+        0x10, /* hop limit: 16 */
+        /* source address: fd01::1 */
+        0xfd, 0x01, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x01,
+        /* destination address: fd01::2 */
+        0xfd, 0x01, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x02,
+
+        /* Hop-by-Hop Options Header */
+        /* https://tools.ietf.org/html/rfc6553 */
+        0x2b, /* next header: IPv6-Route */
+        0x00, /* hdr ext len: 0 * 8 + 8 = 8 */
+        0x63, /* option type: RPL Option */
+        0x04, /* opt data len: 4 */
+        0x80, /* flags, Down: 1, Rank-Error: 0, Forwarding-Error: 0 */
+        0x00, /* RPLInstanceID */
+        0x80, 0x00, /* SenderRank */
+
+        /* RPL Routing Header */
+        /* https://tools.ietf.org/html/rfc6554 */
+        0x11, /* next header: UDP */
+        0x02, /* hdr ext len: 2 * 8 + 8 = 24 */
+        0x03, /* routing type: SRH */
+        0x02, /* segments left: 2 */
+        0xef, /* ComprI: 14, ComprE: 15 */
+        0xd0, 0x00, 0x00, /* pad and reserved */
+        /* address: fd01::3, fd01::2 */
+        0x00, 0x03, 0x02, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+        0x00, 0x00, 0x00, 0x00,
+
+        /* UDP (ignored) */
+        0x1f, 0x90, /* source port: 8080 */
+        0x1f, 0x90, /* destination port: 8080 */
+        0x00, 0x08, /* length: 8 */
+        0xff, 0xff, /* checksum */
+    };
+
+    gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, data, sizeof(data), GNRC_NETTYPE_UNDEF);
+
+    gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt);
+
+    printf("pkt->users: %d\n", pkt->users);
+    assert(pkt->users == 0);
+}
+
+int main(void)
+{
+    /* we need a message queue for the thread running the shell in order to
+     * receive potentially fast incoming networking packets */
+    msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
+    puts("RIOT network stack example application");
+
+    _send_packet();
+
+    /* start shell */
+    puts("All up, running the shell now");
+    char line_buf[SHELL_DEFAULT_BUFSIZE];
+    shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
+
+    /* should be never reached */
+    return 0;
+}
diff --git a/tests/gnrc_ipv6_ext/tests/01-run.py b/tests/gnrc_ipv6_ext/tests/01-run.py
new file mode 100755
index 0000000000..0e50cb66dd
--- /dev/null
+++ b/tests/gnrc_ipv6_ext/tests/01-run.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+
+# Copyright (C) 2016 Kaspar Schleiser <kaspar@schleiser.de>
+# Copyright (C) 2016 Takuo Yonezawa <Yonezawa-T2@mail.dnp.co.jp>
+#
+# 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 sys
+
+sys.path.append(os.path.join(os.environ['RIOTBASE'], 'dist/tools/testrunner'))
+import testrunner
+
+def testfunc(child):
+    index = child.expect_exact([
+        "ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)",
+        "pkt->users: 0"
+    ])
+
+    if index == 1:
+        # debug is disabled
+        return
+
+    child.expect_exact("ipv6: handle extension header (nh = 0)")
+    child.expect_exact("ipv6: handle extension header (nh = 43)")
+    child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 40)")
+    child.expect_exact("ipv6: handle extension header (nh = 0)")
+    child.expect_exact("ipv6: handle extension header (nh = 43)")
+    child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)")
+    child.expect_exact("ipv6: handle extension header (nh = 0)")
+    child.expect_exact("ipv6: handle extension header (nh = 43)")
+    child.expect_exact("ipv6: forward nh = 17 to other threads")
+    child.expect_exact("pkt->users: 0")
+
+if __name__ == "__main__":
+    sys.exit(testrunner.run(testfunc))
-- 
GitLab