diff --git a/tests/gnrc_sixlowpan/Makefile b/tests/gnrc_sixlowpan/Makefile new file mode 100644 index 0000000000..345770653a --- /dev/null +++ b/tests/gnrc_sixlowpan/Makefile @@ -0,0 +1,39 @@ +# name of your application +APPLICATION = gnrc_sixlowpan + +# 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_netdev_default +USEMODULE += auto_init_gnrc_netif +# 6LoWPAN and its extensions +USEMODULE += gnrc_sixlowpan_default +# UDP +USEMODULE += gnrc_udp +# Dumps packets +USEMODULE += gnrc_pktdump + +# 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 + +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_sixlowpan/main.c b/tests/gnrc_sixlowpan/main.c new file mode 100644 index 0000000000..de5e775e86 --- /dev/null +++ b/tests/gnrc_sixlowpan/main.c @@ -0,0 +1,167 @@ +/* + * 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 + * @author Takuo Yonezawa + * + * @} + */ + +#include + +#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" +#include "net/gnrc/netif/hdr.h" +#include "net/gnrc/pktdump.h" + +static void _init_interface(void) +{ + kernel_pid_t ifs[GNRC_NETIF_NUMOF]; + ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; + + gnrc_netif_get(ifs); + + /* fd01::01 */ + addr.u8[0] = 0xfd; + addr.u8[1] = 0x01; + addr.u8[15] = 0x01; + gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST); +} + +static void _send_packet(void) +{ + kernel_pid_t ifs[GNRC_NETIF_NUMOF]; + + gnrc_netif_get(ifs); + + struct { + gnrc_netif_hdr_t netif_hdr; + uint8_t src[8]; + uint8_t dst[8]; + } netif_hdr = { + .src = { 0x02, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x02 }, + .dst = { 0x02, 0x00, 0x00, 0xFF, 0xFE, 0x00, 0x00, 0x01 }, + }; + + gnrc_netif_hdr_init(&(netif_hdr.netif_hdr), 8, 8); + + netif_hdr.netif_hdr.if_pid = ifs[0]; + + uint8_t data1[] = { + /* 6LoWPAN Header */ + /* Fragmentation Header (first) */ + 0xc0, 0x94, /* 0b11000: frag1, 0b00010010100: datagram_size (148) */ + 0x00, 0x01, /* datagram_tag */ + /* 0b011: LOWPAN_IPHC */ + /* 0b11: Traffic Class and Flow Label are elided */ + /* 0b1: Next Header is compressed */ + /* 0b11: The Hop Limit field is compressed and the hop limit is 255 */ + 0x7f, + /* 0b0: No additional 8-bit Context Identifier Extension is used */ + /* 0b0: Source address compression uses stateless compression */ + /* 0b11: source address mode is 0 bits */ + /* 0b0: Destination address is not a multicast address */ + /* 0x0: Destination address compression uses stateless compression */ + /* 0x00: destination address mode is 128 bits */ + 0x30, + + /* destination address: fd01::1 */ + 0xfd, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + + /* 0b11110: UDP LOWPAN_NHC */ + /* 0b0: Checksum is carried in-line */ + /* 0b11: First 12 bits of both Source Port and Destination Port are 0xf0b and elided */ + 0xf3, + 0x00, /* Source Port and Destination Port (4 bits each) */ + 0x23, 0x2f, /* Checksum */ + + /* payload */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + }; + + uint8_t data2[] = { + /* 6LoWPAN Header */ + /* Fragmentation Header (rest) */ + 0xe0, 0x94, /* 0b11100: frag1, 0b00010010100: datagram_size (148) */ + 0x00, 0x01, /* datagram_tag */ + 0x0c, /* datagram_offset (12 * 8 = 96) */ + + /* payload */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + gnrc_netreg_entry_t dump_6lowpan = { NULL, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_pktdump_pid }; + gnrc_netreg_entry_t dump_ipv6 = { NULL, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_pktdump_pid }; + gnrc_netreg_entry_t dump_udp = { NULL, GNRC_NETREG_DEMUX_CTX_ALL, gnrc_pktdump_pid }; + gnrc_netreg_entry_t dump_udp_61616 = { NULL, 61616, gnrc_pktdump_pid }; + + gnrc_netreg_register(GNRC_NETTYPE_SIXLOWPAN, &dump_6lowpan); + gnrc_netreg_register(GNRC_NETTYPE_IPV6, &dump_ipv6); + gnrc_netreg_register(GNRC_NETTYPE_UDP, &dump_udp); + gnrc_netreg_register(GNRC_NETTYPE_UDP, &dump_udp_61616); + + gnrc_pktsnip_t *netif1 = gnrc_pktbuf_add(NULL, + &netif_hdr, + sizeof(netif_hdr), + GNRC_NETTYPE_NETIF); + gnrc_pktsnip_t *pkt1 = gnrc_pktbuf_add(netif1, + data1, + sizeof(data1), + GNRC_NETTYPE_SIXLOWPAN); + + gnrc_netapi_dispatch_receive(GNRC_NETTYPE_SIXLOWPAN, GNRC_NETREG_DEMUX_CTX_ALL, pkt1); + + gnrc_pktsnip_t *netif2 = gnrc_pktbuf_add(NULL, + &netif_hdr, + sizeof(netif_hdr), + GNRC_NETTYPE_NETIF); + gnrc_pktsnip_t *pkt2 = gnrc_pktbuf_add(netif2, + data2, + sizeof(data2), + GNRC_NETTYPE_SIXLOWPAN); + + gnrc_netapi_dispatch_receive(GNRC_NETTYPE_SIXLOWPAN, GNRC_NETREG_DEMUX_CTX_ALL, pkt2); +} + +int main(void) +{ + puts("RIOT network stack example application"); + + _init_interface(); + _send_packet(); + + return 0; +} diff --git a/tests/gnrc_sixlowpan/tests/01-run.py b/tests/gnrc_sixlowpan/tests/01-run.py new file mode 100755 index 0000000000..ee9acabed6 --- /dev/null +++ b/tests/gnrc_sixlowpan/tests/01-run.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 + +# Copyright (C) 2016 Kaspar Schleiser +# Copyright (C) 2016 Takuo Yonezawa +# +# 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): + # 1st 6LoWPAN fragment + child.expect_exact("PKTDUMP: data received:") + child.expect_exact("~~ SNIP 0 - size: 74 byte, type: NETTYPE_SIXLOWPAN (1)") + child.expect_exact("Fragmentation Header (first)") + child.expect_exact("datagram size: 148") + child.expect_exact("tag: 0x1") + child.expect_exact("IPHC dispatch") + child.expect_exact("TF: traffic class and flow label elided") + child.expect_exact("NH: LOWPAN_NHC") + child.expect_exact("HLIM: 255") + child.expect_exact("Stateless source address compression: elided (use L2 address)") + child.expect_exact("Stateless destinaton address compression: 128 bits inline") + + # 2nd 6LoWPAN fragment + child.expect_exact("PKTDUMP: data received:") + child.expect_exact("~~ SNIP 0 - size: 57 byte, type: NETTYPE_SIXLOWPAN (1)") + child.expect_exact("Fragmentation Header (subsequent)") + child.expect_exact("datagram size: 148") + child.expect_exact("tag: 0x1") + child.expect_exact("offset: 0x12") + + # IPv6 + child.expect_exact("PKTDUMP: data received:") + child.expect_exact("~~ SNIP 0 - size: 148 byte, type: NETTYPE_IPV6 (2)") + child.expect_exact("traffic class: 0x00 (ECN: 0x0, DSCP: 0x00)") + child.expect_exact("flow label: 0x00000") + child.expect_exact("length: 108 next header: 17 hop limit: 255") + child.expect_exact("source address: fe80::ff:fe00:2") + child.expect_exact("destination address: fd01::1") + + # UDP + child.expect_exact("PKTDUMP: data received:") + child.expect_exact("~~ SNIP 0 - size: 108 byte, type: NETTYPE_UDP (4)") + child.expect_exact(" src-port: 61616 dst-port: 61616") + child.expect_exact(" length: 108 cksum: 0x4232f") + child.expect_exact("~~ SNIP 1 - size: 40 byte, type: NETTYPE_IPV6 (2)") + child.expect_exact("traffic class: 0x00 (ECN: 0x0, DSCP: 0x00)") + child.expect_exact("flow label: 0x00000") + child.expect_exact("length: 108 next header: 17 hop limit: 255") + child.expect_exact("source address: fe80::ff:fe00:2") + child.expect_exact("destination address: fd01::1") + + # UDP (port 61616) + child.expect_exact("PKTDUMP: data received:") + child.expect_exact("~~ SNIP 0 - size: 100 byte, type: NETTYPE_UNDEF (0)") + child.expect_exact("000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00") + child.expect_exact("000060 00 00 00 00") + child.expect_exact("~~ SNIP 1 - size: 8 byte, type: NETTYPE_UDP (4)") + child.expect_exact(" src-port: 61616 dst-port: 61616") + child.expect_exact(" length: 108 cksum: 0x4232f") + child.expect_exact("~~ SNIP 2 - size: 40 byte, type: NETTYPE_IPV6 (2)") + child.expect_exact("traffic class: 0x00 (ECN: 0x0, DSCP: 0x00)") + child.expect_exact("flow label: 0x00000") + child.expect_exact("length: 108 next header: 17 hop limit: 255") + child.expect_exact("source address: fe80::ff:fe00:2") + child.expect_exact("destination address: fd01::1") + +if __name__ == "__main__": + sys.exit(testrunner.run(testfunc))