You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
7.5 KiB
247 lines
7.5 KiB
/* |
|
* 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" |
|
#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; |
|
}
|
|
|