diff --git a/sys/include/net/gnrc/ipv6.h b/sys/include/net/gnrc/ipv6.h index deb8536f370384b6a360a8a620833697b3897490..39d56387cb5db841ddc01de0f8bdce85e5797c94 100644 --- a/sys/include/net/gnrc/ipv6.h +++ b/sys/include/net/gnrc/ipv6.h @@ -134,6 +134,19 @@ kernel_pid_t gnrc_ipv6_init(void); */ void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh); +/** + * @brief Get the IPv6 header from a given list of @ref gnrc_pktsnip_t + * + * This function may be used with e.g. a pointer to a (full) UDP datagram. + * + * @param[in] pkt The pointer to the first @ref gnrc_pktsnip_t of the + * packet. + * + * @return A pointer to the @ref ipv6_hdr_t of the packet. + * @return NULL if the packet does not contain an IPv6 header. + */ +ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt); + #ifdef __cplusplus } #endif diff --git a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c index 53b0f7028aebb63261812c0bf69545379959dae5..7a76c74c42d2b9aee76c136b483fa385e0066875 100644 --- a/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c +++ b/sys/net/gnrc/network_layer/ipv6/gnrc_ipv6.c @@ -196,6 +196,17 @@ void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *current, gnrc_pktsnip_t assert(false); } +ipv6_hdr_t *gnrc_ipv6_get_header(gnrc_pktsnip_t *pkt) +{ + ipv6_hdr_t *hdr = NULL; + gnrc_pktsnip_t *tmp = gnrc_pktsnip_search_type(pkt, GNRC_NETTYPE_IPV6); + if ((tmp) && ipv6_hdr_is(tmp->data)) { + hdr = ((ipv6_hdr_t*) tmp->data); + } + + return hdr; +} + /* internal functions */ static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh, bool interested) diff --git a/tests/unittests/tests-gnrc_ipv6/Makefile b/tests/unittests/tests-gnrc_ipv6/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2 --- /dev/null +++ b/tests/unittests/tests-gnrc_ipv6/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/tests/unittests/tests-gnrc_ipv6/Makefile.include b/tests/unittests/tests-gnrc_ipv6/Makefile.include new file mode 100644 index 0000000000000000000000000000000000000000..0577e7d9a37b40d984a608b3e1db5f9440597333 --- /dev/null +++ b/tests/unittests/tests-gnrc_ipv6/Makefile.include @@ -0,0 +1 @@ +USEMODULE += gnrc_ipv6 diff --git a/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.c b/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.c new file mode 100644 index 0000000000000000000000000000000000000000..b8baa8743af9c031e9371fc2fc78768f82306236 --- /dev/null +++ b/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 INRIA + * + * 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. + */ + +/** + * @{ + * + * @author Oliver Hahm <oliver.hahm@inria.fr> + * @file + */ + +#include "embUnit.h" + +#include "net/ipv6/addr.h" +#include "net/ipv6/hdr.h" +#include "net/gnrc/ipv6.h" +#include "net/gnrc/pktbuf.h" + +#include "unittests-constants.h" +#include "tests-gnrc_ipv6.h" + +#define DEFAULT_TEST_SRC { { \ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f \ + } \ + } +#define DEFAULT_TEST_DST { { \ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f \ + } \ + } + +#define DEFAULT_TEST_V_TC_FL TEST_UINT32 +#define DEFAULT_TEST_LEN TEST_UINT16 +#define DEFAULT_TEST_NH TEST_UINT8 +#define DEFAULT_TEST_HL TEST_UINT8 + +static gnrc_pktsnip_t *_pkt_w_ip_hdr, *_pkt_no_ip_hdr; + +static void set_up(void) +{ + ipv6_hdr_t ip = (ipv6_hdr_t) { + .v_tc_fl = byteorder_htonl(DEFAULT_TEST_V_TC_FL), + .len = byteorder_htons(DEFAULT_TEST_LEN), + .nh = DEFAULT_TEST_NH, + .hl = DEFAULT_TEST_HL, + .src = DEFAULT_TEST_SRC, + .dst = DEFAULT_TEST_DST + }; + + ipv6_hdr_set_version(&ip); + + gnrc_pktbuf_init(); + _pkt_w_ip_hdr = gnrc_pktbuf_add(NULL, NULL, 1, GNRC_NETTYPE_NETIF); + assert(_pkt_w_ip_hdr); + _pkt_w_ip_hdr = gnrc_pktbuf_add(_pkt_w_ip_hdr, &ip, sizeof(ipv6_hdr_t), GNRC_NETTYPE_IPV6); + assert(_pkt_w_ip_hdr); + _pkt_w_ip_hdr = gnrc_pktbuf_add(_pkt_w_ip_hdr, NULL, 1, GNRC_NETTYPE_UNDEF); + assert(_pkt_w_ip_hdr); + + _pkt_no_ip_hdr = gnrc_pktbuf_add(NULL, NULL, 1, GNRC_NETTYPE_NETIF); + assert(_pkt_no_ip_hdr); + _pkt_no_ip_hdr = gnrc_pktbuf_add(_pkt_no_ip_hdr, NULL, 1, GNRC_NETTYPE_UNDEF); + assert(_pkt_no_ip_hdr); +} + +static void tear_down(void) +{ + gnrc_pktbuf_release(_pkt_w_ip_hdr->next->next); + gnrc_pktbuf_release(_pkt_no_ip_hdr->next); +} + +static void test_gnrc_ipv6_get_header(void) +{ + TEST_ASSERT_NOT_NULL(gnrc_ipv6_get_header(_pkt_w_ip_hdr)); +} + +static void test_gnrc_ipv6_get_header_no_header(void) +{ + TEST_ASSERT_NULL(gnrc_ipv6_get_header(_pkt_no_ip_hdr)); +} + +static void test_gnrc_ipv6_get_header_check_version(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + + TEST_ASSERT(ipv6_hdr_get_version(hdr) == 0x06); +} + +static void test_gnrc_ipv6_get_header_check_len(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + + TEST_ASSERT(byteorder_ntohs(hdr->len) == DEFAULT_TEST_LEN); +} + +static void test_gnrc_ipv6_get_header_check_nh(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + + TEST_ASSERT(hdr->nh == DEFAULT_TEST_NH); +} + +static void test_gnrc_ipv6_get_header_check_hl(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + + TEST_ASSERT(hdr->hl == DEFAULT_TEST_HL); +} + +static void test_gnrc_ipv6_get_header_check_src(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + ipv6_addr_t addr = DEFAULT_TEST_SRC; + + TEST_ASSERT(ipv6_addr_equal(&(hdr->src), &addr)); +} + +static void test_gnrc_ipv6_get_header_check_dst(void) +{ + ipv6_hdr_t *hdr = gnrc_ipv6_get_header(_pkt_w_ip_hdr); + ipv6_addr_t addr = DEFAULT_TEST_DST; + + TEST_ASSERT(ipv6_addr_equal(&(hdr->dst), &addr)); +} + +Test *tests_gnrc_ipv6_tests(void) +{ + EMB_UNIT_TESTFIXTURES(fixtures) { + new_TestFixture(test_gnrc_ipv6_get_header), + new_TestFixture(test_gnrc_ipv6_get_header_no_header), + new_TestFixture(test_gnrc_ipv6_get_header_check_version), + new_TestFixture(test_gnrc_ipv6_get_header_check_len), + new_TestFixture(test_gnrc_ipv6_get_header_check_nh), + new_TestFixture(test_gnrc_ipv6_get_header_check_hl), + new_TestFixture(test_gnrc_ipv6_get_header_check_src), + new_TestFixture(test_gnrc_ipv6_get_header_check_dst), + }; + + EMB_UNIT_TESTCALLER(gnrc_ipv6_tests, set_up, tear_down, fixtures); + + return (Test *)&gnrc_ipv6_tests; +} + +void tests_gnrc_ipv6(void) +{ + TESTS_RUN(tests_gnrc_ipv6_tests()); +} +/** @} */ diff --git a/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.h b/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.h new file mode 100644 index 0000000000000000000000000000000000000000..58904805cbb6fc1a6e3fd3d52e63c4202cf3e2e8 --- /dev/null +++ b/tests/unittests/tests-gnrc_ipv6/tests-gnrc_ipv6.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016 INRIA + * + * 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. + */ + +/** + * @addtogroup unittests + * @{ + * + * @file + * @brief Unittests for the ``gnrc_ipv6`` module + * + * @author Oliver Hahm <oliver.hahm@inria.fr> + */ +#ifndef TESTS_GNRC_IPV6_H_ +#define TESTS_GNRC_IPV6_H_ + +#include "embUnit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief The entry point of this test suite. + */ +void tests_gnrc_ipv6(void); + +#ifdef __cplusplus +} +#endif + +#endif /* TESTS_GNRC_IPV6_H_ */ +/** @} */