1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/tests/net/gnrc_ndp/main.c

1327 lines
49 KiB
C

/*
* 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 NDP message handling of gnrc stack.
*
* @author Martine S. Lenders <m.lenders@fu-berlin.de>
*
* @}
*/
#include <kernel_defines.h>
#include <stdio.h>
#include "byteorder.h"
#include "embUnit.h"
#include "embUnit/embUnit.h"
#include "msg.h"
#include "net/gnrc/ipv6/nib/conf.h"
#include "net/gnrc/netapi.h"
#include "net/gnrc/netif/hdr.h"
#include "net/gnrc/netif/internal.h"
#include "net/gnrc/netreg.h"
#include "net/gnrc/pktbuf.h"
#include "net/icmpv6.h"
#include "net/ndp.h"
#include "net/netdev_test.h"
#include "net/netopt.h"
#include "sched.h"
#include "test_utils/expect.h"
#include "pktbuf_static.h"
#include "net/gnrc/ndp.h"
#define TEST_CUR_HL (194U)
#define TEST_LTIME (894U)
#define TEST_REACH_TIME (1597495062U)
#define TEST_RETRANS_TIMER (1819101160U)
#define TEST_PFX_LEN (42U)
#define TEST_VALID_LTIME (223526372U)
#define TEST_PREF_LTIME (2056660713U)
#define TEST_NDP_OPT_SIZE (14U)
#define TEST_NDP_OPT_TYPE (142U)
#define TEST_MTU (669256124U)
#define TEST_ASSERT_ALLOCATION(pkt, s, t) \
TEST_ASSERT_NULL((pkt)->next); \
TEST_ASSERT_NOT_NULL((pkt)->data); \
TEST_ASSERT_EQUAL_INT((s), (pkt)->size); \
TEST_ASSERT_EQUAL_INT((t), (pkt)->type)
static const ipv6_addr_t test_dst = { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x73, 0x25, 0x22, 0xc6, 0xdf, 0x05, 0xf2, 0x6b } };
static const ipv6_addr_t test_src = { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xe5, 0x43, 0xb7, 0x74, 0xd7, 0xa9, 0x30, 0x74 } };
static const ipv6_addr_t test_tgt = { { 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x31, 0x78, 0x95, 0x84, 0x71, 0x5f, 0x47, 0x53 } };
static const ipv6_addr_t test_pfx = { { 0x47, 0x25, 0xd9, 0x3b, 0x7f, 0xcc, 0x15, 0x6c,
0x64, 0x3e, 0x76, 0x0d, 0x30, 0x10, 0x0d, 0xc8 } };
static const uint8_t test_src_l2[] = { 0xe7, 0x43, 0xb7, 0x74, 0xd7, 0xa9, 0x30, 0x74 };
static gnrc_netif_t *test_netif = NULL;
static gnrc_netif_t _netif;
static void init_pkt_handler(void);
static inline size_t ceil8(size_t size);
static void set_up(void)
{
gnrc_pktbuf_init();
}
static void fill_pktbuf(void)
{
gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
_align(sizeof(gnrc_pktsnip_t)),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(pkt);
TEST_ASSERT(gnrc_pktbuf_is_sane());
}
static void test_nbr_sol_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_nbr_sol_build(&test_tgt, NULL));
}
static void test_nbr_sol_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_nbr_sol_t *nbr_sol;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_nbr_sol_build(&test_tgt, NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, sizeof(ndp_nbr_sol_t), GNRC_NETTYPE_ICMPV6);
/* check packet content */
nbr_sol = pkt->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_NBR_SOL, nbr_sol->type);
TEST_ASSERT_EQUAL_INT(0, nbr_sol->code);
TEST_ASSERT_EQUAL_INT(0, nbr_sol->resv.u32);
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&test_tgt, &nbr_sol->tgt),
"nbr_sol->tgt != test_tgt");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_nbr_adv_build(&test_tgt, 0, NULL));
}
static void test_nbr_adv_build__success(uint8_t flags)
{
gnrc_pktsnip_t *pkt;
ndp_nbr_adv_t *nbr_adv;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_nbr_adv_build(&test_tgt, flags,
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, sizeof(ndp_nbr_adv_t), GNRC_NETTYPE_ICMPV6);
/* check packet content */
nbr_adv = pkt->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_NBR_ADV, nbr_adv->type);
TEST_ASSERT_EQUAL_INT(0, nbr_adv->code);
TEST_ASSERT_EQUAL_INT(flags, nbr_adv->flags);
TEST_ASSERT_EQUAL_INT(0, nbr_adv->resv[0]);
TEST_ASSERT_EQUAL_INT(0, nbr_adv->resv[1]);
TEST_ASSERT_EQUAL_INT(0, nbr_adv->resv[2]);
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&test_tgt, &nbr_adv->tgt),
"nbr_adv->tgt != test_tgt");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_build__success_without_flags(void)
{
test_nbr_adv_build__success(0);
}
static void test_nbr_adv_build__success_with_flags(void)
{
test_nbr_adv_build__success(NDP_NBR_ADV_FLAGS_S);
}
static void test_rtr_sol_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_rtr_sol_build(NULL));
}
static void test_rtr_sol_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_rtr_sol_t *rtr_sol;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_rtr_sol_build(NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, sizeof(ndp_rtr_sol_t), GNRC_NETTYPE_ICMPV6);
/* check packet content */
rtr_sol = pkt->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_RTR_SOL, rtr_sol->type);
TEST_ASSERT_EQUAL_INT(0, rtr_sol->code);
TEST_ASSERT_EQUAL_INT(0, rtr_sol->resv.u32);
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_rtr_adv_build(TEST_CUR_HL, 0, TEST_LTIME,
TEST_REACH_TIME,
TEST_RETRANS_TIMER, NULL));
}
static void test_rtr_adv_build__success(uint8_t flags)
{
gnrc_pktsnip_t *pkt;
ndp_rtr_adv_t *rtr_adv;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_rtr_adv_build(TEST_CUR_HL, flags,
TEST_LTIME,
TEST_REACH_TIME,
TEST_RETRANS_TIMER,
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, sizeof(ndp_rtr_adv_t), GNRC_NETTYPE_ICMPV6);
/* check packet content */
rtr_adv = pkt->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_RTR_ADV, rtr_adv->type);
TEST_ASSERT_EQUAL_INT(0, rtr_adv->code);
TEST_ASSERT_EQUAL_INT(TEST_CUR_HL, rtr_adv->cur_hl);
TEST_ASSERT_EQUAL_INT(flags, rtr_adv->flags);
TEST_ASSERT_EQUAL_INT(TEST_LTIME, byteorder_ntohs(rtr_adv->ltime));
TEST_ASSERT_EQUAL_INT(TEST_REACH_TIME,
byteorder_ntohl(rtr_adv->reach_time));
TEST_ASSERT_EQUAL_INT(TEST_RETRANS_TIMER,
byteorder_ntohl(rtr_adv->retrans_timer));
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_build__success_without_flags(void)
{
test_rtr_adv_build__success(0);
}
static void test_rtr_adv_build__success_with_flags(void)
{
test_rtr_adv_build__success(NDP_RTR_ADV_FLAGS_M);
}
static void test_opt_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_opt_build(TEST_NDP_OPT_TYPE, TEST_NDP_OPT_SIZE,
NULL));
}
static void test_opt_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_opt_t *opt;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_opt_build(TEST_NDP_OPT_TYPE,
TEST_NDP_OPT_SIZE,
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, ceil8(TEST_NDP_OPT_SIZE), GNRC_NETTYPE_UNDEF);
/* check packet content */
opt = pkt->data;
TEST_ASSERT_EQUAL_INT(TEST_NDP_OPT_TYPE, opt->type);
TEST_ASSERT_EQUAL_INT(ceil8(TEST_NDP_OPT_SIZE) / 8, opt->len);
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_opt_sl2a_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_opt_sl2a_build(test_src_l2, sizeof(test_src_l2),
NULL));
}
static void test_opt_sl2a_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_opt_t *opt;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_opt_sl2a_build(test_src_l2,
sizeof(test_src_l2),
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, ceil8(sizeof(ndp_opt_t) + sizeof(test_src_l2)),
GNRC_NETTYPE_UNDEF);
/* check packet content */
opt = pkt->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_SL2A, opt->type);
TEST_ASSERT_EQUAL_INT(ceil8(sizeof(ndp_opt_t) + sizeof(test_src_l2)) / 8,
opt->len);
TEST_ASSERT_MESSAGE(memcmp(test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"opt->l2addr != test_src_l2");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_opt_tl2a_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_opt_tl2a_build(test_src_l2, sizeof(test_src_l2),
NULL));
}
static void test_opt_tl2a_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_opt_t *opt;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_opt_tl2a_build(test_src_l2,
sizeof(test_src_l2),
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, ceil8(sizeof(ndp_opt_t) + sizeof(test_src_l2)),
GNRC_NETTYPE_UNDEF);
/* check packet content */
opt = pkt->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_TL2A, opt->type);
TEST_ASSERT_EQUAL_INT(ceil8(sizeof(ndp_opt_t) + sizeof(test_src_l2)) / 8,
opt->len);
TEST_ASSERT_MESSAGE(memcmp(test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"opt->l2addr != test_src_l2");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_opt_pi_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_opt_pi_build(&test_pfx, TEST_PFX_LEN,
TEST_VALID_LTIME, TEST_PREF_LTIME,
0, NULL));
}
static void test_opt_pi_build__success(uint8_t flags)
{
gnrc_pktsnip_t *pkt;
ndp_opt_pi_t *opt;
ipv6_addr_t exp_pfx = IPV6_ADDR_UNSPECIFIED;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_opt_pi_build(&test_pfx, TEST_PFX_LEN,
TEST_VALID_LTIME,
TEST_PREF_LTIME, flags,
NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, ceil8(sizeof(ndp_opt_pi_t)),
GNRC_NETTYPE_UNDEF);
/* check packet content */
/* prepare expected prefix (the function MUST remove all the garbage after
* the prefix) */
ipv6_addr_init_prefix(&exp_pfx, &test_pfx, TEST_PFX_LEN);
opt = pkt->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_PI, opt->type);
TEST_ASSERT_EQUAL_INT(NDP_OPT_PI_LEN, opt->len);
TEST_ASSERT_EQUAL_INT(TEST_PFX_LEN, opt->prefix_len);
TEST_ASSERT_EQUAL_INT(flags, opt->flags);
TEST_ASSERT_EQUAL_INT(TEST_VALID_LTIME,
byteorder_ntohl(opt->valid_ltime));
TEST_ASSERT_EQUAL_INT(TEST_PREF_LTIME,
byteorder_ntohl(opt->pref_ltime));
TEST_ASSERT_EQUAL_INT(0, opt->resv.u32);
TEST_ASSERT_MESSAGE(ipv6_addr_equal(&exp_pfx, &opt->prefix),
"opt->prefix != exp_pfx");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_opt_pi_build__success_without_flags(void)
{
test_opt_pi_build__success(0);
}
static void test_opt_pi_build__success_with_flags(void)
{
test_opt_pi_build__success(NDP_OPT_PI_FLAGS_L);
}
static void test_opt_mtu_build__pktbuf_full(void)
{
fill_pktbuf();
TEST_ASSERT_NULL(gnrc_ndp_opt_mtu_build(TEST_MTU, NULL));
}
static void test_opt_mtu_build__success(void)
{
gnrc_pktsnip_t *pkt;
ndp_opt_mtu_t *opt;
TEST_ASSERT(gnrc_pktbuf_is_empty());
TEST_ASSERT_NOT_NULL((pkt = gnrc_ndp_opt_mtu_build(TEST_MTU, NULL)));
TEST_ASSERT(gnrc_pktbuf_is_sane());
/* check packet meta-data */
TEST_ASSERT_ALLOCATION(pkt, ceil8(sizeof(ndp_opt_mtu_t)), GNRC_NETTYPE_UNDEF);
/* check packet content */
opt = pkt->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_MTU, opt->type);
TEST_ASSERT_EQUAL_INT(NDP_OPT_MTU_LEN, opt->len);
TEST_ASSERT_EQUAL_INT(0, opt->resv.u16);
TEST_ASSERT_EQUAL_INT(TEST_MTU, byteorder_ntohl(opt->mtu));
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static inline kernel_pid_t _get_iface(gnrc_netif_hdr_t *hdr)
{
return hdr->if_pid;
}
static inline ipv6_addr_t *_get_ipv6_src(ipv6_hdr_t *hdr)
{
return &hdr->src;
}
static inline ipv6_addr_t *_get_ipv6_dst(ipv6_hdr_t *hdr)
{
return &hdr->dst;
}
#define ASSERT_NETIF_HDR(netif, pkt) \
TEST_ASSERT_NOT_NULL(pkt); \
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_NETIF, pkt->type); \
TEST_ASSERT_NOT_NULL(pkt->data); \
TEST_ASSERT_EQUAL_INT(netif->pid, _get_iface(pkt->data))
#define ASSERT_IPV6_HDR(src, dst, pkt) \
TEST_ASSERT_NOT_NULL(pkt); \
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_IPV6, pkt->type); \
TEST_ASSERT_NOT_NULL(pkt->data); \
TEST_ASSERT_MESSAGE(memcmp(src, _get_ipv6_src(pkt->data), \
sizeof(ipv6_addr_t)) == 0, "src != pkt->src"); \
TEST_ASSERT_MESSAGE(memcmp(dst, _get_ipv6_dst(pkt->data), \
sizeof(ipv6_addr_t)) == 0, "dst != pkt->dst")
#define ASSERT_ICMPV6_HDR(pkt) \
TEST_ASSERT_NOT_NULL(pkt); \
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_ICMPV6, pkt->type); \
TEST_ASSERT_NOT_NULL(pkt->data)
static void test_nbr_sol_send(const ipv6_addr_t *src)
{
msg_t msg;
gnrc_pktsnip_t *pkt;
ndp_nbr_sol_t *nbr_sol;
while (msg_try_receive(&msg) == 1) {
/* empty message queue */
}
TEST_ASSERT_NOT_NULL(test_netif);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, src, &test_dst, NULL);
msg_receive(&msg);
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_netif, pkt);
if ((src != NULL) && ipv6_addr_is_unspecified(src)) {
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &test_dst, pkt->next);
}
else {
ASSERT_IPV6_HDR(&test_src, &test_dst, pkt->next);
}
ASSERT_ICMPV6_HDR(pkt->next->next);
TEST_ASSERT_EQUAL_INT(sizeof(ndp_nbr_sol_t), pkt->next->next->size);
nbr_sol = pkt->next->next->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_NBR_SOL, nbr_sol->type);
TEST_ASSERT_MESSAGE(memcmp(&test_tgt, &nbr_sol->tgt, sizeof(ipv6_addr_t)) == 0,
"tgt != nbr_sol->tgt");
if ((src != NULL) && ipv6_addr_is_unspecified(src)) {
TEST_ASSERT_NULL(pkt->next->next->next);
}
else {
TEST_ASSERT_NOT_NULL(pkt->next->next->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_UNDEF, pkt->next->next->next->type);
TEST_ASSERT_NOT_NULL(pkt->next->next->next->data);
ndp_opt_t *opt = pkt->next->next->next->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_SL2A, opt->type);
TEST_ASSERT_MESSAGE(memcmp(&test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"src_l2 != pkt->l2");
TEST_ASSERT_NULL(pkt->next->next->next->next);
}
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_sol_send__src_NULL(void)
{
test_nbr_sol_send(NULL);
}
static void test_nbr_sol_send__src_unspecified(void)
{
test_nbr_sol_send(&ipv6_addr_unspecified);
}
static void test_nbr_sol_send__src_NOT_NULL(void)
{
test_nbr_sol_send(&test_src);
}
static void test_nbr_sol_send__pktbuf_full1(void)
{
/* don't be able to fit any more data into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
_align(sizeof(gnrc_pktsnip_t)),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, &test_src, &test_dst, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_sol_send__pktbuf_full2(void)
{
/* just be able to fit the SLLAO into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(2 * _align(sizeof(gnrc_pktsnip_t))) - 16,
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, &test_src, &test_dst, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_sol_send__pktbuf_full3(void)
{
/* just be able to fit the SLLAO and NS into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(3 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_nbr_sol_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, &test_src, &test_dst, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_sol_send__pktbuf_full4(void)
{
/* just be able to fit the SLLAO, NS, and IPv6 header into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(4 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_nbr_sol_t) -
sizeof(ipv6_hdr_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_sol_send(&test_tgt, test_netif, &test_src, &test_dst, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_send(const ipv6_addr_t *tgt, const ipv6_addr_t *dst,
bool supply_tl2a, gnrc_pktsnip_t *exp_ext_opts)
{
msg_t msg;
gnrc_pktsnip_t *pkt;
ndp_nbr_adv_t *nbr_adv;
TEST_ASSERT_NOT_NULL(test_netif);
gnrc_ndp_nbr_adv_send(tgt, test_netif, dst, supply_tl2a, exp_ext_opts);
msg_receive(&msg);
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_netif, pkt);
if (ipv6_addr_is_unspecified(dst)) {
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &ipv6_addr_all_nodes_link_local,
pkt->next);
}
else {
ASSERT_IPV6_HDR(&ipv6_addr_unspecified, &test_dst, pkt->next);
}
ASSERT_ICMPV6_HDR(pkt->next->next);
TEST_ASSERT_EQUAL_INT(sizeof(ndp_nbr_adv_t), pkt->next->next->size);
nbr_adv = pkt->next->next->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_NBR_ADV, nbr_adv->type);
TEST_ASSERT_MESSAGE(memcmp(tgt, &nbr_adv->tgt, sizeof(ipv6_addr_t)) == 0,
"tgt != nbr_adv->tgt");
if (supply_tl2a || ipv6_addr_is_unspecified(dst) || (exp_ext_opts != NULL)) {
gnrc_pktsnip_t *ext_opts = NULL;
TEST_ASSERT_NOT_NULL(pkt->next->next->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_UNDEF, pkt->next->next->next->type);
TEST_ASSERT_NOT_NULL(pkt->next->next->next->data);
/* implicitly this is the same */
if (supply_tl2a || ipv6_addr_is_unspecified(dst)) {
ndp_opt_t *opt = pkt->next->next->next->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_TL2A, opt->type);
TEST_ASSERT_MESSAGE(memcmp(&test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"src_l2 != pkt->l2");
if (exp_ext_opts == NULL) {
TEST_ASSERT_NULL(pkt->next->next->next->next);
}
else {
/* extra option comes after TL2AO */
ext_opts = pkt->next->next->next->next;
}
}
else {
/* extra option comes directly after neighbor advertisement */
ext_opts = pkt->next->next->next;
}
TEST_ASSERT(exp_ext_opts == ext_opts);
}
else {
TEST_ASSERT_NULL(pkt->next->next->next);
}
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, NULL);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, NULL);
}
static void test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &test_dst, false, NULL);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &test_dst, false, ext_opts);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &test_dst, true, NULL);
}
static void test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &test_dst, true, ext_opts);
}
static void test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, NULL);
}
static void test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, false, ext_opts);
}
static void test_nbr_adv_send__src_tgt_unspecified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, NULL);
}
static void test_nbr_adv_send__src_tgt_unspecified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &ipv6_addr_unspecified, true, ext_opts);
}
static void test_nbr_adv_send__src_tgt_specified_dst_no_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &test_dst, false, NULL);
}
static void test_nbr_adv_send__src_tgt_specified_dst_no_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &test_dst, false, ext_opts);
}
static void test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_no_ext_opts(void)
{
test_nbr_adv_send(&test_src, &test_dst, true, NULL);
}
static void test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_nbr_adv_send(&test_src, &test_dst, true, ext_opts);
}
static void test_nbr_adv_send__pktbuf_full1(void)
{
/* don't be able to fit any more data into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
_align(sizeof(gnrc_pktsnip_t)),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_adv_send(&test_src, test_netif, &test_dst, true, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_send__pktbuf_full2(void)
{
/* just be able to fit the TLLAO into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of TLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(2 * _align(sizeof(gnrc_pktsnip_t))) - 16,
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_adv_send(&test_src, test_netif, &test_dst, true, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_send__pktbuf_full3(void)
{
/* just be able to fit the TLLAO and NA into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of TLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(3 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_nbr_adv_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_adv_send(&test_src, test_netif, &test_dst, true, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_nbr_adv_send__pktbuf_full4(void)
{
/* just be able to fit the TLLAO, NA, and IPv6 header into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of TLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(4 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_nbr_adv_t) -
sizeof(ipv6_hdr_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_nbr_adv_send(&test_src, test_netif, &test_dst, true, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_sol_send(const ipv6_addr_t *dst)
{
msg_t msg;
gnrc_pktsnip_t *pkt;
ndp_rtr_sol_t *rtr_sol;
TEST_ASSERT_NOT_NULL(test_netif);
gnrc_ndp_rtr_sol_send(test_netif, dst);
msg_receive(&msg);
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_netif, pkt);
if (dst != NULL) {
ASSERT_IPV6_HDR(&test_src, dst, pkt->next);
}
else {
ASSERT_IPV6_HDR(&test_src, &ipv6_addr_all_routers_link_local,
pkt->next);
}
ASSERT_ICMPV6_HDR(pkt->next->next);
TEST_ASSERT_EQUAL_INT(sizeof(ndp_rtr_sol_t), pkt->next->next->size);
rtr_sol = pkt->next->next->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_RTR_SOL, rtr_sol->type);
if ((dst == NULL) || ipv6_addr_is_link_local(dst)) {
TEST_ASSERT_NOT_NULL(pkt->next->next->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_UNDEF, pkt->next->next->next->type);
TEST_ASSERT_NOT_NULL(pkt->next->next->next->data);
ndp_opt_t *opt = pkt->next->next->next->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_SL2A, opt->type);
TEST_ASSERT_MESSAGE(memcmp(&test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"src_l2 != pkt->l2");
TEST_ASSERT_NULL(pkt->next->next->next->next);
}
else {
TEST_ASSERT_NULL(pkt->next->next->next);
}
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_sol_send__dst_NULL(void)
{
test_rtr_sol_send(NULL);
}
static void test_rtr_sol_send__dst_local(void)
{
test_rtr_sol_send(&test_dst);
}
static void test_rtr_sol_send__dst_global(void)
{
ipv6_addr_t dst;
memcpy(&dst, &test_dst, sizeof(dst));
ipv6_addr_init_prefix(&dst, &test_pfx, 64);
test_rtr_sol_send(&test_dst);
}
static void test_rtr_sol_send__pktbuf_full1(void)
{
/* don't be able to fit any more data into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
_align(sizeof(gnrc_pktsnip_t)),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_sol_send(test_netif, &test_dst);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_sol_send__pktbuf_full2(void)
{
/* just be able to fit the SLLAO into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(2 * _align(sizeof(gnrc_pktsnip_t))) - 16,
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_sol_send(test_netif, &test_dst);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_sol_send__pktbuf_full3(void)
{
/* just be able to fit the SLLAO and RS into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(3 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_rtr_sol_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_sol_send(test_netif, &test_dst);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_sol_send__pktbuf_full4(void)
{
/* just be able to fit the SLLAO, RS, and IPv6 header into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(4 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_rtr_sol_t) -
sizeof(ipv6_hdr_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_sol_send(test_netif, &test_dst);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
static void test_rtr_adv_send(const ipv6_addr_t *src, const ipv6_addr_t *dst,
bool fin, gnrc_pktsnip_t *exp_ext_opts)
{
msg_t msg;
gnrc_pktsnip_t *pkt;
ndp_rtr_adv_t *rtr_adv;
TEST_ASSERT_NOT_NULL(test_netif);
gnrc_ndp_rtr_adv_send(test_netif, src, dst, fin, exp_ext_opts);
msg_receive(&msg);
TEST_ASSERT_EQUAL_INT(GNRC_NETAPI_MSG_TYPE_SND, msg.type);
pkt = msg.content.ptr;
/* check packet */
ASSERT_NETIF_HDR(test_netif, pkt);
/* testing for unspecified source is complicated so we skip it here and
* do it in later integration tests */
if (dst != NULL) {
ASSERT_IPV6_HDR(&test_src, dst, pkt->next);
}
else {
ASSERT_IPV6_HDR(&test_src, &ipv6_addr_all_nodes_link_local,
pkt->next);
}
ASSERT_ICMPV6_HDR(pkt->next->next);
TEST_ASSERT_EQUAL_INT(sizeof(ndp_rtr_adv_t), pkt->next->next->size);
rtr_adv = pkt->next->next->data;
TEST_ASSERT_EQUAL_INT(ICMPV6_RTR_ADV, rtr_adv->type);
if (fin) {
TEST_ASSERT_EQUAL_INT(0, rtr_adv->ltime.u16);
}
else {
TEST_ASSERT_MESSAGE(rtr_adv->ltime.u16 != 0, "rtr_adv->ltime == 0");
}
/* check for SLLAO */
TEST_ASSERT_NOT_NULL(pkt->next->next->next);
TEST_ASSERT_EQUAL_INT(GNRC_NETTYPE_UNDEF, pkt->next->next->next->type);
TEST_ASSERT_NOT_NULL(pkt->next->next->next->data);
ndp_opt_t *opt = pkt->next->next->next->data;
TEST_ASSERT_EQUAL_INT(NDP_OPT_SL2A, opt->type);
TEST_ASSERT_MESSAGE(memcmp(&test_src_l2, opt + 1, sizeof(test_src_l2)) == 0,
"src_l2 != pkt->l2");
TEST_ASSERT_MESSAGE(pkt->next->next->next->next == exp_ext_opts,
"ext_opts set wrong");
gnrc_pktbuf_release(pkt);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_send__src_NULL_dst_NULL_no_fin_no_ext_opts(void)
{
test_rtr_adv_send(NULL, NULL, false, NULL);
}
static void test_rtr_adv_send__src_NULL_dst_NULL_no_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(NULL, NULL, false, ext_opts);
}
static void test_rtr_adv_send__src_NULL_dst_NULL_fin_no_ext_opts(void)
{
test_rtr_adv_send(NULL, NULL, true, NULL);
}
static void test_rtr_adv_send__src_NULL_dst_NULL_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(NULL, NULL, true, ext_opts);
}
static void test_rtr_adv_send__src_NULL_dst_no_fin_no_ext_opts(void)
{
test_rtr_adv_send(NULL, &test_dst, false, NULL);
}
static void test_rtr_adv_send__src_NULL_dst_no_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(NULL, &test_dst, false, ext_opts);
}
static void test_rtr_adv_send__src_NULL_dst_fin_no_ext_opts(void)
{
test_rtr_adv_send(NULL, &test_dst, true, NULL);
}
static void test_rtr_adv_send__src_NULL_dst_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(NULL, &test_dst, true, ext_opts);
}
static void test_rtr_adv_send__src_dst_NULL_no_fin_no_ext_opts(void)
{
test_rtr_adv_send(&test_src, NULL, false, NULL);
}
static void test_rtr_adv_send__src_dst_NULL_no_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(&test_src, NULL, false, ext_opts);
}
static void test_rtr_adv_send__src_dst_NULL_fin_no_ext_opts(void)
{
test_rtr_adv_send(&test_src, NULL, true, NULL);
}
static void test_rtr_adv_send__src_dst_NULL_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(&test_src, NULL, true, ext_opts);
}
static void test_rtr_adv_send__src_dst_no_fin_no_ext_opts(void)
{
test_rtr_adv_send(&test_src, &test_dst, false, NULL);
}
static void test_rtr_adv_send__src_dst_no_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(&test_src, &test_dst, false, ext_opts);
}
static void test_rtr_adv_send__src_dst_fin_no_ext_opts(void)
{
test_rtr_adv_send(&test_src, &test_dst, true, NULL);
}
static void test_rtr_adv_send__src_dst_fin_ext_opts(void)
{
gnrc_pktsnip_t *ext_opts = gnrc_pktbuf_add(NULL, NULL, 8U, GNRC_NETTYPE_UNDEF);
test_rtr_adv_send(&test_src, &test_dst, true, ext_opts);
}
static void test_rtr_adv_send__pktbuf_full1(void)
{
/* don't be able to fit any more data into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
_align(sizeof(gnrc_pktsnip_t)),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_adv_send(test_netif, &test_src, &test_dst, false, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_send__pktbuf_full2(void)
{
/* just be able to fit the SLLAO into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(2 * _align(sizeof(gnrc_pktsnip_t))) - 16,
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_adv_send(test_netif, &test_src, &test_dst, false, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_send__pktbuf_full3(void)
{
/* just be able to fit the SLLAO and RA into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(3 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_rtr_adv_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_adv_send(test_netif, &test_src, &test_dst, false, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
static void test_rtr_adv_send__pktbuf_full4(void)
{
/* just be able to fit the SLLAO, RA, and IPv6 header into packet buffer
* - sizeof(gnrc_pktsnip_t) + pktbuf internal padding
* - 16 == size of SLLAO for IEEE 802.15.4 */
gnrc_pktsnip_t *tmp = gnrc_pktbuf_add(NULL, NULL,
CONFIG_GNRC_PKTBUF_SIZE -
(4 * _align(sizeof(gnrc_pktsnip_t))) - 16 -
sizeof(ndp_rtr_adv_t) -
sizeof(ipv6_hdr_t),
GNRC_NETTYPE_UNDEF);
TEST_ASSERT_NOT_NULL(tmp);
gnrc_ndp_rtr_adv_send(test_netif, &test_src, &test_dst, false, NULL);
gnrc_pktbuf_release(tmp);
TEST_ASSERT(gnrc_pktbuf_is_sane());
TEST_ASSERT(gnrc_pktbuf_is_empty());
}
#endif
static Test *tests_gnrc_ndp_build(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_nbr_sol_build__pktbuf_full),
new_TestFixture(test_nbr_sol_build__success),
new_TestFixture(test_nbr_adv_build__pktbuf_full),
new_TestFixture(test_nbr_adv_build__success_without_flags),
new_TestFixture(test_nbr_adv_build__success_with_flags),
new_TestFixture(test_rtr_sol_build__pktbuf_full),
new_TestFixture(test_rtr_sol_build__success),
new_TestFixture(test_rtr_adv_build__pktbuf_full),
new_TestFixture(test_rtr_adv_build__success_without_flags),
new_TestFixture(test_rtr_adv_build__success_with_flags),
new_TestFixture(test_opt_build__pktbuf_full),
new_TestFixture(test_opt_build__success),
new_TestFixture(test_opt_sl2a_build__pktbuf_full),
new_TestFixture(test_opt_sl2a_build__success),
new_TestFixture(test_opt_tl2a_build__pktbuf_full),
new_TestFixture(test_opt_tl2a_build__success),
new_TestFixture(test_opt_pi_build__pktbuf_full),
new_TestFixture(test_opt_pi_build__success_without_flags),
new_TestFixture(test_opt_pi_build__success_with_flags),
new_TestFixture(test_opt_mtu_build__pktbuf_full),
new_TestFixture(test_opt_mtu_build__success),
};
EMB_UNIT_TESTCALLER(tests, set_up, NULL, fixtures);
return (Test *)&tests;
}
static Test *tests_gnrc_ndp_send(void)
{
EMB_UNIT_TESTFIXTURES(fixtures) {
new_TestFixture(test_nbr_sol_send__src_NULL),
new_TestFixture(test_nbr_sol_send__src_unspecified),
new_TestFixture(test_nbr_sol_send__src_NOT_NULL),
new_TestFixture(test_nbr_sol_send__pktbuf_full1),
new_TestFixture(test_nbr_sol_send__pktbuf_full2),
new_TestFixture(test_nbr_sol_send__pktbuf_full3),
new_TestFixture(test_nbr_sol_send__pktbuf_full4),
new_TestFixture(test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_unspecified_dst_no_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_unspecified_dst_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_specified_dst_no_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__foreign_tgt_specified_dst_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_unspecified_dst_no_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_unspecified_dst_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_unspecified_dst_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_specified_dst_no_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_specified_dst_no_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_no_ext_opts),
new_TestFixture(test_nbr_adv_send__src_tgt_specified_dst_supply_tl2a_ext_opts),
new_TestFixture(test_nbr_adv_send__pktbuf_full1),
new_TestFixture(test_nbr_adv_send__pktbuf_full2),
new_TestFixture(test_nbr_adv_send__pktbuf_full3),
new_TestFixture(test_nbr_adv_send__pktbuf_full4),
new_TestFixture(test_rtr_sol_send__dst_NULL),
new_TestFixture(test_rtr_sol_send__dst_local),
new_TestFixture(test_rtr_sol_send__dst_global),
new_TestFixture(test_rtr_sol_send__pktbuf_full1),
new_TestFixture(test_rtr_sol_send__pktbuf_full2),
new_TestFixture(test_rtr_sol_send__pktbuf_full3),
new_TestFixture(test_rtr_sol_send__pktbuf_full4),
#if IS_ACTIVE(CONFIG_GNRC_IPV6_NIB_ROUTER)
new_TestFixture(test_rtr_adv_send__src_NULL_dst_NULL_no_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_NULL_no_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_NULL_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_NULL_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_no_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_no_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_NULL_dst_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_NULL_no_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_NULL_no_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_NULL_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_NULL_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_no_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_no_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_fin_no_ext_opts),
new_TestFixture(test_rtr_adv_send__src_dst_fin_ext_opts),
new_TestFixture(test_rtr_adv_send__pktbuf_full1),
new_TestFixture(test_rtr_adv_send__pktbuf_full2),
new_TestFixture(test_rtr_adv_send__pktbuf_full3),
new_TestFixture(test_rtr_adv_send__pktbuf_full4),
#endif
};
EMB_UNIT_TESTCALLER(tests, set_up, NULL, fixtures);
return (Test *)&tests;
}
int main(void)
{
TESTS_START();
TESTS_RUN(tests_gnrc_ndp_build());
init_pkt_handler();
TESTS_RUN(tests_gnrc_ndp_send());
TESTS_END();
return 0;
}
#define MSG_QUEUE_SIZE (2)
static char test_netif_stack[THREAD_STACKSIZE_DEFAULT];
static msg_t msg_queue_main[MSG_QUEUE_SIZE];
static gnrc_netreg_entry_t netreg_entry;
static netdev_test_t dev;
static int _test_netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt)
{
(void)netif;
gnrc_pktbuf_release(pkt);
return 0;
}
static gnrc_pktsnip_t *_test_netif_recv(gnrc_netif_t *netif)
{
(void)netif;
return NULL;
}
static int _test_netif_set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt)
{
(void)netif;
(void)opt;
return -ENOTSUP;
}
static const gnrc_netif_ops_t _test_netif_ops = {
.init = gnrc_netif_default_init,
.send = _test_netif_send,
.recv = _test_netif_recv,
.get = gnrc_netif_get_from_netdev,
.set = _test_netif_set,
};
static int _netdev_test_address_long(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
expect(max_len >= sizeof(test_src_l2));
memcpy(value, test_src_l2, sizeof(test_src_l2));
return sizeof(test_src_l2);
}
static int _netdev_test_proto(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
expect(max_len == sizeof(gnrc_nettype_t));
*((gnrc_nettype_t *)value) = GNRC_NETTYPE_UNDEF;
return sizeof(gnrc_nettype_t);
}
static int _netdev_test_src_len(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
expect(max_len == sizeof(uint16_t));
*((uint16_t *)value) = sizeof(test_src_l2);
return sizeof(uint16_t);
}
static int _netdev_test_max_pdu_size(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
expect(max_len == sizeof(uint16_t));
*((uint16_t *)value) = 100U;
return sizeof(uint16_t);
}
static int _netdev_test_device_type(netdev_t *dev, void *value, size_t max_len)
{
(void)dev;
expect(max_len == sizeof(uint16_t));
*((uint16_t *)value) = NETDEV_TYPE_IEEE802154;
return sizeof(uint16_t);
}
static void init_pkt_handler(void)
{
msg_init_queue(msg_queue_main, MSG_QUEUE_SIZE);
gnrc_netreg_entry_init_pid(&netreg_entry, GNRC_NETREG_DEMUX_CTX_ALL,
thread_getpid());
gnrc_netreg_register(GNRC_NETTYPE_NDP, &netreg_entry);
netdev_test_setup(&dev, NULL);
netdev_test_set_get_cb(&dev, NETOPT_ADDRESS_LONG,
_netdev_test_address_long);
netdev_test_set_get_cb(&dev, NETOPT_PROTO, _netdev_test_proto);
netdev_test_set_get_cb(&dev, NETOPT_SRC_LEN, _netdev_test_src_len);
netdev_test_set_get_cb(&dev, NETOPT_MAX_PDU_SIZE,
_netdev_test_max_pdu_size);
netdev_test_set_get_cb(&dev, NETOPT_DEVICE_TYPE, _netdev_test_device_type);
int res = gnrc_netif_create(&_netif, test_netif_stack, sizeof(test_netif_stack),
GNRC_NETIF_PRIO, "test-netif",
&dev.netdev.netdev, &_test_netif_ops);
test_netif = &_netif;
TEST_ASSERT_MESSAGE(res == 0,
"Unable to start test interface");
memcpy(&test_netif->ipv6.addrs[0], &test_src,
sizeof(test_netif->ipv6.addrs[0]));
test_netif->ipv6.addrs_flags[0] = GNRC_NETIF_IPV6_ADDRS_FLAGS_STATE_VALID;
memcpy(test_netif->l2addr, test_src_l2, sizeof(test_netif->l2addr));
test_netif->l2addr_len = sizeof(test_src_l2);
}
static inline size_t ceil8(size_t size)
{
if (size % 8) {
return ((size / 8) + 1) * 8;
}
else {
return size;
}
}