Skip to content
Snippets Groups Projects
Commit 4a13324a authored by Martine Lenders's avatar Martine Lenders
Browse files

Merge pull request #5281 from authmillenon/gnrc_ipv6/fix/ext-fix-with-nhc

gnrc_ipv6: fix asserts for NHC
parents 9bac1013 655aa040
No related branches found
No related tags found
No related merge requests found
...@@ -89,6 +89,56 @@ static enum gnrc_ipv6_ext_demux_status _handle_rh(gnrc_pktsnip_t *current, gnrc_ ...@@ -89,6 +89,56 @@ static enum gnrc_ipv6_ext_demux_status _handle_rh(gnrc_pktsnip_t *current, gnrc_
#endif #endif
/**
* @brief marks IPv6 extension header if needed.
* updates pkt and returns next header.
* @param[in] current The current header
* @param[in,out] pkt The whole packet
* @return The next header
* @return NULL on error
*/
static gnrc_pktsnip_t *_mark_extension_header(gnrc_pktsnip_t *current,
gnrc_pktsnip_t **pkt)
{
gnrc_pktsnip_t *ext_snip, *tmp, *next;
ipv6_ext_t *ext = (ipv6_ext_t *) current->data;
size_t offset = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT);
if (current == *pkt) {
if ((tmp = gnrc_pktbuf_start_write(*pkt)) == NULL) {
DEBUG("ipv6: could not get a copy of pkt\n");
gnrc_pktbuf_release(*pkt);
return NULL;
}
*pkt = tmp;
ext_snip = gnrc_pktbuf_mark(*pkt, offset, GNRC_NETTYPE_IPV6_EXT);
next = *pkt;
if (ext_snip == NULL) {
gnrc_pktbuf_release(*pkt);
return NULL;
}
}
else {
/* the header is already marked */
next = NULL;
for (tmp = *pkt; tmp != NULL; tmp = tmp->next) {
if (tmp->next == current) {
next = tmp;
break;
}
}
assert(next != NULL);
}
return next;
}
/* /*
* current pkt * current pkt
* | | * | |
...@@ -100,86 +150,68 @@ void gnrc_ipv6_ext_demux(kernel_pid_t iface, ...@@ -100,86 +150,68 @@ void gnrc_ipv6_ext_demux(kernel_pid_t iface,
gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *pkt,
uint8_t nh) uint8_t nh)
{ {
gnrc_pktsnip_t *ext_snip, *tmp, *next;
ipv6_ext_t *ext; ipv6_ext_t *ext;
size_t offset = 0;
ext = (ipv6_ext_t *) current->data; while (true) {
ext = (ipv6_ext_t *) current->data;
switch (nh) { switch (nh) {
case PROTNUM_IPV6_EXT_RH: case PROTNUM_IPV6_EXT_RH:
#ifdef MODULE_GNRC_RPL_SRH #ifdef MODULE_GNRC_RPL_SRH
switch (_handle_rh(current, pkt)) { switch (_handle_rh(current, pkt)) {
case GNRC_IPV6_EXT_OK: case GNRC_IPV6_EXT_OK:
/* We are the final destination. So proceeds like normal packet. */ /* We are the final destination. So proceeds like normal packet. */
nh = ext->nh; nh = ext->nh;
DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh); DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh);
offset = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT);
break;
case GNRC_IPV6_EXT_ERROR:
/* already released by _handle_rh, so no release here */
return;
case GNRC_IPV6_EXT_FORWARDED: if ((current = _mark_extension_header(current, &pkt)) == NULL) {
return; return;
} }
break; gnrc_ipv6_demux(iface, current, pkt, nh); /* demultiplex next header */
#endif
case PROTNUM_IPV6_EXT_HOPOPT: return;
case PROTNUM_IPV6_EXT_DST:
case PROTNUM_IPV6_EXT_FRAG:
case PROTNUM_IPV6_EXT_AH:
case PROTNUM_IPV6_EXT_ESP:
case PROTNUM_IPV6_EXT_MOB:
/* TODO: add handling of types */
nh = ext->nh;
DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh);
offset = ((ext->len * IPV6_EXT_LEN_UNIT) + IPV6_EXT_LEN_UNIT);
break;
default:
DEBUG("ipv6_ext: unknown next header: %" PRIu8 "\n", nh);
gnrc_pktbuf_release(pkt);
return;
}
if (current == pkt) { case GNRC_IPV6_EXT_ERROR:
if ((tmp = gnrc_pktbuf_start_write(pkt)) == NULL) { /* already released by _handle_rh, so no release here */
DEBUG("ipv6: could not get a copy of pkt\n"); return;
gnrc_pktbuf_release(pkt);
return;
}
pkt = tmp;
ext_snip = gnrc_pktbuf_mark(pkt, offset, GNRC_NETTYPE_IPV6_EXT); case GNRC_IPV6_EXT_FORWARDED:
next = pkt; /* the packet is forwarded and released. finish processing */
return;
}
if (ext_snip == NULL) { break;
gnrc_pktbuf_release(pkt); #endif
return;
}
}
else {
/* the header is already marked */
next = NULL; case PROTNUM_IPV6_EXT_HOPOPT:
case PROTNUM_IPV6_EXT_DST:
case PROTNUM_IPV6_EXT_FRAG:
case PROTNUM_IPV6_EXT_AH:
case PROTNUM_IPV6_EXT_ESP:
case PROTNUM_IPV6_EXT_MOB:
/* TODO: add handling of types */
nh = ext->nh;
DEBUG("ipv6_ext: next header = %" PRIu8 "\n", nh);
if ((current = _mark_extension_header(current, &pkt)) == NULL) {
return;
}
gnrc_pktbuf_hold(pkt, 1); /* don't release on next dispatch */
if (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, nh, pkt) == 0) {
gnrc_pktbuf_release(pkt);
}
for (tmp = pkt; tmp != NULL; tmp = tmp->next) {
if (tmp->next == current) {
next = tmp;
break; break;
}
}
assert(next != NULL); default:
gnrc_ipv6_demux(iface, current, pkt, nh); /* demultiplex next header */
return;
}
} }
gnrc_ipv6_demux(iface, next, pkt, nh); /* demultiplex next header */ assert(false); /* never reaches here */
return;
} }
gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next, gnrc_pktsnip_t *gnrc_ipv6_ext_build(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *next,
......
...@@ -69,9 +69,6 @@ kernel_pid_t gnrc_ipv6_pid = KERNEL_PID_UNDEF; ...@@ -69,9 +69,6 @@ kernel_pid_t gnrc_ipv6_pid = KERNEL_PID_UNDEF;
/* handles GNRC_NETAPI_MSG_TYPE_RCV commands */ /* handles GNRC_NETAPI_MSG_TYPE_RCV commands */
static void _receive(gnrc_pktsnip_t *pkt); static void _receive(gnrc_pktsnip_t *pkt);
/* dispatches received IPv6 packet for upper layer */
static void _dispatch_rcv_pkt(gnrc_nettype_t type, uint32_t demux_ctx,
gnrc_pktsnip_t *pkt);
/* Sends packet over the appropriate interface(s). /* Sends packet over the appropriate interface(s).
* prep_hdr: prepare header for sending (call to _fill_ipv6_hdr()), otherwise * prep_hdr: prepare header for sending (call to _fill_ipv6_hdr()), otherwise
* assume it is already prepared */ * assume it is already prepared */
...@@ -100,6 +97,9 @@ kernel_pid_t gnrc_ipv6_init(void) ...@@ -100,6 +97,9 @@ kernel_pid_t gnrc_ipv6_init(void)
return gnrc_ipv6_pid; return gnrc_ipv6_pid;
} }
static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt,
uint8_t nh, bool interested);
/* /*
* current pkt * current pkt
* | | * | |
...@@ -108,10 +108,9 @@ kernel_pid_t gnrc_ipv6_init(void) ...@@ -108,10 +108,9 @@ 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) void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt, uint8_t nh)
{ {
int receiver_num;
bool interested = false; bool interested = false;
pkt->type = gnrc_nettype_from_protnum(nh); current->type = gnrc_nettype_from_protnum(nh);
switch (nh) { switch (nh) {
#ifdef MODULE_GNRC_ICMPV6 #ifdef MODULE_GNRC_ICMPV6
...@@ -139,76 +138,106 @@ void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *current, gnrc_pktsnip_t ...@@ -139,76 +138,106 @@ void gnrc_ipv6_demux(kernel_pid_t iface, gnrc_pktsnip_t *current, gnrc_pktsnip_t
break; break;
default: default:
(void)iface; (void)iface;
break; #ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
} /* second statement is true for small 6LoWPAN NHC decompressed frames
* since in this case it looks like
DEBUG("ipv6: forward nh = %u to other threads\n", nh); *
receiver_num = gnrc_netreg_num(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL) + * * GNRC_NETTYPE_UNDEF <- pkt
gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh); * v
* * GNRC_NETTYPE_UDP <- current
if (receiver_num == 0) { * v
DEBUG("ipv6: unable to forward packet as no one is interested in it\n"); * * GNRC_NETTYPE_EXT
* v
if (!interested) { * * GNRC_NETTYPE_IPV6
*/
assert((current == pkt) || (current == pkt->next));
#else
assert(current == pkt); assert(current == pkt);
gnrc_pktbuf_release(pkt); #endif
return; break;
}
} }
else {
if (!interested) {
assert(current == pkt);
/* IPv6 is not interested anymore so `- 1` */
receiver_num--;
}
gnrc_pktbuf_hold(current, receiver_num);
/* XXX can't use gnrc_netapi_dispatch_receive() twice here since a call to that function _dispatch_next_header(current, pkt, nh, interested);
* implicitly hands all rights to the packet to one of the receiving threads. As a
* result, the second call to gnrc_netapi_dispatch_receive() would be invalid */
_dispatch_rcv_pkt(current->type, GNRC_NETREG_DEMUX_CTX_ALL, current);
_dispatch_rcv_pkt(GNRC_NETTYPE_IPV6, nh, current);
if (!interested) { if (!interested) {
return; return;
}
} }
switch (nh) { switch (nh) {
#ifdef MODULE_GNRC_ICMPV6 #ifdef MODULE_GNRC_ICMPV6
case PROTNUM_ICMPV6: case PROTNUM_ICMPV6:
DEBUG("ipv6: handle ICMPv6 packet (nh = %u)\n", nh); DEBUG("ipv6: handle ICMPv6 packet (nh = %u)\n", nh);
gnrc_icmpv6_demux(iface, pkt); gnrc_icmpv6_demux(iface, pkt);
break; gnrc_pktbuf_release(pkt);
return;
#endif #endif
#ifdef MODULE_GNRC_IPV6_EXT #ifdef MODULE_GNRC_IPV6_EXT
case PROTNUM_IPV6_EXT_HOPOPT: case PROTNUM_IPV6_EXT_HOPOPT:
case PROTNUM_IPV6_EXT_DST: case PROTNUM_IPV6_EXT_DST:
case PROTNUM_IPV6_EXT_RH: case PROTNUM_IPV6_EXT_RH:
case PROTNUM_IPV6_EXT_FRAG: case PROTNUM_IPV6_EXT_FRAG:
case PROTNUM_IPV6_EXT_AH: case PROTNUM_IPV6_EXT_AH:
case PROTNUM_IPV6_EXT_ESP: case PROTNUM_IPV6_EXT_ESP:
case PROTNUM_IPV6_EXT_MOB: case PROTNUM_IPV6_EXT_MOB:
DEBUG("ipv6: handle extension header (nh = %u)\n", nh); DEBUG("ipv6: handle extension header (nh = %u)\n", nh);
gnrc_ipv6_ext_demux(iface, current, pkt, nh); gnrc_ipv6_ext_demux(iface, current, pkt, nh);
return; return;
#endif #endif
case PROTNUM_IPV6: case PROTNUM_IPV6:
DEBUG("ipv6: handle encapsulated IPv6 packet (nh = %u)\n", nh); DEBUG("ipv6: handle encapsulated IPv6 packet (nh = %u)\n", nh);
_decapsulate(pkt); _decapsulate(pkt);
return; return;
default: default:
break; assert(false);
break;
} }
assert(current == pkt); assert(false);
gnrc_pktbuf_release(pkt);
} }
/* internal functions */ /* internal functions */
static void _dispatch_next_header(gnrc_pktsnip_t *current, gnrc_pktsnip_t *pkt,
uint8_t nh, bool interested)
{
#ifdef MODULE_GNRC_IPV6_EXT
const bool should_dispatch_current_type = ((current->type != GNRC_NETTYPE_IPV6_EXT) ||
(current->next->type == GNRC_NETTYPE_IPV6));
#else
const bool should_dispatch_current_type = (current->next->type == GNRC_NETTYPE_IPV6);
#endif
DEBUG("ipv6: forward nh = %u to other threads\n", nh);
/* dispatch IPv6 extension header only once */
if (should_dispatch_current_type) {
bool should_release = (gnrc_netreg_num(GNRC_NETTYPE_IPV6, nh) == 0) &&
(!interested);
if (!should_release) {
gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in
* next dispatch */
}
if (gnrc_netapi_dispatch_receive(current->type,
GNRC_NETREG_DEMUX_CTX_ALL,
pkt) == 0) {
gnrc_pktbuf_release(pkt);
}
if (should_release) {
return;
}
}
if (interested) {
gnrc_pktbuf_hold(pkt, 1); /* don't remove from packet buffer in
* next dispatch */
}
if (gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, nh, pkt) == 0) {
gnrc_pktbuf_release(pkt);
}
}
static void *_event_loop(void *args) static void *_event_loop(void *args)
{ {
msg_t msg, reply, msg_q[GNRC_IPV6_MSG_QUEUE_SIZE]; msg_t msg, reply, msg_q[GNRC_IPV6_MSG_QUEUE_SIZE];
...@@ -747,22 +776,6 @@ static inline bool _pkt_not_for_me(kernel_pid_t *iface, ipv6_hdr_t *hdr) ...@@ -747,22 +776,6 @@ static inline bool _pkt_not_for_me(kernel_pid_t *iface, ipv6_hdr_t *hdr)
} }
} }
static void _dispatch_rcv_pkt(gnrc_nettype_t type, uint32_t demux_ctx,
gnrc_pktsnip_t *pkt)
{
gnrc_netreg_entry_t *entry = gnrc_netreg_lookup(type, demux_ctx);
while (entry) {
DEBUG("ipv6: Send receive command for %p to %" PRIu16 "\n", (void *)pkt,
entry->pid);
if (gnrc_netapi_receive(entry->pid, pkt) < 1) {
DEBUG("ipv6: unable to deliver packet\n");
gnrc_pktbuf_release(pkt);
}
entry = gnrc_netreg_getnext(entry);
}
}
static void _receive(gnrc_pktsnip_t *pkt) static void _receive(gnrc_pktsnip_t *pkt)
{ {
kernel_pid_t iface = KERNEL_PID_UNDEF; kernel_pid_t iface = KERNEL_PID_UNDEF;
...@@ -873,7 +886,7 @@ static void _receive(gnrc_pktsnip_t *pkt) ...@@ -873,7 +886,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
* links." * links."
*/ */
if ((ipv6_addr_is_link_local(&(hdr->src))) || (ipv6_addr_is_link_local(&(hdr->dst)))) { if ((ipv6_addr_is_link_local(&(hdr->src))) || (ipv6_addr_is_link_local(&(hdr->dst)))) {
DEBUG("ipv6: do not forward packets with link-local source or"\ DEBUG("ipv6: do not forward packets with link-local source or"
" destination address\n"); " destination address\n");
gnrc_pktbuf_release(pkt); gnrc_pktbuf_release(pkt);
return; return;
......
...@@ -21,9 +21,10 @@ USEMODULE += gnrc_ipv6_router_default ...@@ -21,9 +21,10 @@ USEMODULE += gnrc_ipv6_router_default
# IPv6 extension headers # IPv6 extension headers
USEMODULE += gnrc_ipv6_ext USEMODULE += gnrc_ipv6_ext
USEMODULE += gnrc_rpl_srh USEMODULE += gnrc_rpl_srh
USEMODULE += gnrc_sixlowpan_iphc_nhc
# UDP
USEMODULE += gnrc_udp
# Add also the shell, some shell commands # Add also the shell, some shell commands
USEMODULE += shell
USEMODULE += shell_commands
USEMODULE += ps USEMODULE += ps
# Comment this out to disable code in RIOT that does safety checking # Comment this out to disable code in RIOT that does safety checking
......
...@@ -30,11 +30,10 @@ ...@@ -30,11 +30,10 @@
#include "net/gnrc/netreg.h" #include "net/gnrc/netreg.h"
#include "net/gnrc/netapi.h" #include "net/gnrc/netapi.h"
#include "net/gnrc/netif.h" #include "net/gnrc/netif.h"
#include "net/gnrc/netif/hdr.h"
#define MAIN_QUEUE_SIZE (8) static void _init_interface(void)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE]; {
static void _send_packet(void) {
kernel_pid_t ifs[GNRC_NETIF_NUMOF]; kernel_pid_t ifs[GNRC_NETIF_NUMOF];
ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED; ipv6_addr_t addr = IPV6_ADDR_UNSPECIFIED;
...@@ -49,13 +48,102 @@ static void _send_packet(void) { ...@@ -49,13 +48,102 @@ static void _send_packet(void) {
addr.u8[15] = 0x03; addr.u8[15] = 0x03;
/* fd01::03 */ /* fd01::03 */
gnrc_ipv6_netif_add_addr(ifs[0], &addr, 64, GNRC_IPV6_NETIF_ADDR_FLAGS_UNICAST); 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[] = { uint8_t data[] = {
/* IPv6 Header */ /* IPv6 Header */
0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */ 0x60, 0x00, 0x00, 0x00, /* version, traffic class, flow label */
0x00, 0x28, /* payload length: 40 */ 0x00, 0x2a, /* payload length: 42 */
0x00, /* next header: Hop-by-Hop Option */ 0x00, /* next header: Hop-by-Hop Option */
0x10, /* hop limit: 16 */ 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 */ /* source address: fd01::1 */
0xfd, 0x01, 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
...@@ -66,39 +154,78 @@ static void _send_packet(void) { ...@@ -66,39 +154,78 @@ static void _send_packet(void) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02,
};
uint8_t hop_by_hop_options_data[] = {
/* Hop-by-Hop Options Header */ /* Hop-by-Hop Options Header */
/* https://tools.ietf.org/html/rfc6553 */ /* https://tools.ietf.org/html/rfc6553 */
0x2b, /* next header: IPv6-Route */ 0x2b, /* next header: IPv6-Route */
0x00, /* hdr ext len: 0 * 8 + 8 = 8 */ 0x00, /* hdr ext len: 0 * 8 + 8 = 8 */
0x63, /* option type: RPL Option */ 0x63, /* option type: RPL Option */
0x04, /* opt data len: 4 */ 0x04, /* opt data len: 4 */
0x80, /* flags, Down: 1, Rank-Error: 0, Forwarding-Error: 0 */ 0x80, /* flags, Down: 1, Rank-Error: 0, Forwarding-Error: 0 */
0x00, /* RPLInstanceID */ 0x00, /* RPLInstanceID */
0x80, 0x00, /* SenderRank */ 0x80, 0x00, /* SenderRank */
};
uint8_t rpl_routing_data[] = {
/* RPL Routing Header */ /* RPL Routing Header */
/* https://tools.ietf.org/html/rfc6554 */ /* https://tools.ietf.org/html/rfc6554 */
0x11, /* next header: UDP */ 0x11, /* next header: UDP */
0x02, /* hdr ext len: 2 * 8 + 8 = 24 */ 0x02, /* hdr ext len: 2 * 8 + 8 = 24 */
0x03, /* routing type: SRH */ 0x03, /* routing type: SRH */
0x02, /* segments left: 2 */ 0x02, /* segments left: 2 */
0xef, /* ComprI: 14, ComprE: 15 */ 0xef, /* ComprI: 14, ComprE: 15 */
0xd0, 0x00, 0x00, /* pad and reserved */ 0xd0, 0x00, 0x00, /* pad and reserved */
/* address: fd01::3, fd01::2 */ /* address: fd01::3, fd01::2 */
0x00, 0x03, 0x02, 0x00, 0x00, 0x03, 0x02, 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 udp_data[] = {
/* UDP (ignored) */ /* UDP (ignored) */
0x1f, 0x90, /* source port: 8080 */ 0x1f, 0x90, /* source port: 8080 */
0x1f, 0x90, /* destination port: 8080 */ 0x1f, 0x90, /* destination port: 8080 */
0x00, 0x08, /* length: 8 */ 0x00, 0x0a, /* length: 10 */
0xff, 0xff, /* checksum */ 0xff, 0xff, /* checksum */
}; };
gnrc_pktsnip_t *pkt = gnrc_pktbuf_add(NULL, data, sizeof(data), GNRC_NETTYPE_UNDEF); 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); gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt);
...@@ -106,19 +233,14 @@ static void _send_packet(void) { ...@@ -106,19 +233,14 @@ static void _send_packet(void) {
assert(pkt->users == 0); assert(pkt->users == 0);
} }
int main(void) int main(void)
{ {
/* we need a message queue for the thread running the shell in order to
* receive potentially fast incoming networking packets */
msg_init_queue(_main_msg_queue, MAIN_QUEUE_SIZE);
puts("RIOT network stack example application"); puts("RIOT network stack example application");
_send_packet(); _init_interface();
_send_packet_raw();
/* start shell */ _send_packet_parsed();
puts("All up, running the shell now");
char line_buf[SHELL_DEFAULT_BUFSIZE];
shell_run(NULL, line_buf, SHELL_DEFAULT_BUFSIZE);
/* should be never reached */ /* should be never reached */
return 0; return 0;
......
...@@ -21,16 +21,21 @@ def testfunc(child): ...@@ -21,16 +21,21 @@ def testfunc(child):
if index == 1: if index == 1:
# debug is disabled # debug is disabled
child.expect_exact("pkt->users: 0")
return return
child.expect_exact("ipv6: handle extension header (nh = 0)") child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: handle extension header (nh = 43)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 40)") child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 40)")
child.expect_exact("ipv6: handle extension header (nh = 0)") child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: handle extension header (nh = 43)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)") child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)")
child.expect_exact("ipv6: handle extension header (nh = 0)") child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: handle extension header (nh = 43)") child.expect_exact("ipv6: forward nh = 17 to other threads")
child.expect_exact("pkt->users: 0")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::3, next header = 0, length = 40)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: Received (src = fd01::1, dst = fd01::2, next header = 0, length = 40)")
child.expect_exact("ipv6: handle extension header (nh = 0)")
child.expect_exact("ipv6: forward nh = 17 to other threads") child.expect_exact("ipv6: forward nh = 17 to other threads")
child.expect_exact("pkt->users: 0") child.expect_exact("pkt->users: 0")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment