/* * 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" static void _init_interface(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); } static void _send_packet_raw(void) { kernel_pid_t ifs[GNRC_NETIF_NUMOF]; gnrc_netif_get(ifs); gnrc_netif_hdr_t netif_hdr; gnrc_netif_hdr_init(&netif_hdr, 8, 8); netif_hdr.if_pid = ifs[0]; uint8_t data[] = { /* IPv6 Header */ 0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */ 0x00, 0x2a, /* payload length: 42 */ 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, 0x0a, /* length: 10 */ 0xff, 0xff, /* checksum */ 0x00, 0x00, /* payload */ }; gnrc_pktsnip_t *netif = gnrc_pktbuf_add(NULL, &netif_hdr, sizeof(netif_hdr), GNRC_NETTYPE_NETIF); gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(netif, 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); } static void _send_packet_parsed(void) { kernel_pid_t ifs[GNRC_NETIF_NUMOF]; gnrc_netif_get(ifs); gnrc_netif_hdr_t netif_hdr; gnrc_netif_hdr_init(&netif_hdr, 8, 8); netif_hdr.if_pid = ifs[0]; uint8_t ipv6_data[] = { /* IPv6 Header */ 0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */ 0x00, 0x2a, /* payload length: 42 */ 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, }; uint8_t hop_by_hop_options_data[] = { /* 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 */ }; uint8_t rpl_routing_data[] = { /* 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, }; uint8_t udp_data[] = { /* UDP (ignored) */ 0x1f, 0x90, /* source port: 8080 */ 0x1f, 0x90, /* destination port: 8080 */ 0x00, 0x0a, /* length: 10 */ 0xff, 0xff, /* checksum */ }; uint8_t udp_payload[] = { 0x00, 0x00, }; gnrc_pktsnip_t *netif = gnrc_pktbuf_add(NULL, &netif_hdr, sizeof(netif_hdr), GNRC_NETTYPE_NETIF); gnrc_pktsnip_t *ipv6 = gnrc_pktbuf_add(netif, &ipv6_data, sizeof(ipv6_data), GNRC_NETTYPE_IPV6); gnrc_pktsnip_t *hop_by_hop_options = gnrc_pktbuf_add(ipv6, &hop_by_hop_options_data, sizeof(hop_by_hop_options_data), GNRC_NETTYPE_IPV6_EXT); gnrc_pktsnip_t *rpl_routing = gnrc_pktbuf_add(hop_by_hop_options, &rpl_routing_data, sizeof(rpl_routing_data), GNRC_NETTYPE_IPV6_EXT); gnrc_pktsnip_t *udp = gnrc_pktbuf_add(rpl_routing, udp_data, sizeof(udp_data), GNRC_NETTYPE_UDP); gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(udp, &udp_payload, sizeof(udp_payload), 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) { puts("RIOT network stack example application"); _init_interface(); _send_packet_raw(); _send_packet_parsed(); /* should be never reached */ return 0; }