mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
gnrc_sixlowpan: Fix IPHC/NHC packet order problem
This commit is contained in:
parent
b7a7578e21
commit
d342d35dd8
@ -32,11 +32,11 @@ extern "C" {
|
|||||||
/**
|
/**
|
||||||
* @brief Decompresses a received 6LoWPAN IPHC frame.
|
* @brief Decompresses a received 6LoWPAN IPHC frame.
|
||||||
*
|
*
|
||||||
* @pre (ipv6 != NULL) && (ipv6->size >= sizeof(gnrc_ipv6_hdr_t))
|
* @pre (dec_hdr != NULL) && (*dec_hdr != NULL) && ((*dec_hdr)->size >= sizeof(gnrc_ipv6_hdr_t))
|
||||||
*
|
*
|
||||||
* @param[out] ipv6 A pre-allocated IPv6 header. Will not be inserted into
|
* @param[out] dec_hdr A pre-allocated IPv6 header. Will not be inserted into
|
||||||
* @p pkt
|
* @p pkt. May change due to next headers being added in NHC.
|
||||||
* @param[in,out] pkt A received 6LoWPAN IPHC frame. IPHC dispatch will not
|
* @param[in] pkt A received 6LoWPAN IPHC frame. IPHC dispatch will not
|
||||||
* be marked.
|
* be marked.
|
||||||
* @param[in] datagram_size Size of the full uncompressed IPv6 datagram. May be 0, if @p pkt
|
* @param[in] datagram_size Size of the full uncompressed IPv6 datagram. May be 0, if @p pkt
|
||||||
* contains the full (unfragmented) IPv6 datagram.
|
* contains the full (unfragmented) IPv6 datagram.
|
||||||
@ -45,8 +45,8 @@ extern "C" {
|
|||||||
* @return length of the HC dispatches + inline values on success.
|
* @return length of the HC dispatches + inline values on success.
|
||||||
* @return 0 on error.
|
* @return 0 on error.
|
||||||
*/
|
*/
|
||||||
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *pkt, size_t datagram_size,
|
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||||
size_t offset);
|
size_t datagram_size, size_t offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Compresses a 6LoWPAN for IPHC.
|
* @brief Compresses a 6LoWPAN for IPHC.
|
||||||
|
@ -92,7 +92,7 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
|||||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
||||||
else if (sixlowpan_iphc_is(data)) {
|
else if (sixlowpan_iphc_is(data)) {
|
||||||
size_t iphc_len;
|
size_t iphc_len;
|
||||||
iphc_len = gnrc_sixlowpan_iphc_decode(entry->pkt, pkt, entry->pkt->size,
|
iphc_len = gnrc_sixlowpan_iphc_decode(&entry->pkt, pkt, entry->pkt->size,
|
||||||
sizeof(sixlowpan_frag_t));
|
sizeof(sixlowpan_frag_t));
|
||||||
if (iphc_len == 0) {
|
if (iphc_len == 0) {
|
||||||
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
|
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
|
||||||
|
@ -118,6 +118,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pkt = gnrc_pktbuf_remove_snip(pkt, sixlowpan);
|
pkt = gnrc_pktbuf_remove_snip(pkt, sixlowpan);
|
||||||
|
payload->type = GNRC_NETTYPE_IPV6;
|
||||||
}
|
}
|
||||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
||||||
else if (sixlowpan_frag_is((sixlowpan_frag_t *)dispatch)) {
|
else if (sixlowpan_frag_is((sixlowpan_frag_t *)dispatch)) {
|
||||||
@ -129,14 +130,14 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
||||||
else if (sixlowpan_iphc_is(dispatch)) {
|
else if (sixlowpan_iphc_is(dispatch)) {
|
||||||
size_t dispatch_size;
|
size_t dispatch_size;
|
||||||
gnrc_pktsnip_t *sixlowpan;
|
gnrc_pktsnip_t *sixlowpan, *tmp;
|
||||||
gnrc_pktsnip_t *ipv6 = gnrc_pktbuf_add(NULL, NULL, sizeof(ipv6_hdr_t),
|
gnrc_pktsnip_t *dec_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(ipv6_hdr_t),
|
||||||
GNRC_NETTYPE_IPV6);
|
GNRC_NETTYPE_IPV6);
|
||||||
if ((ipv6 == NULL) ||
|
if ((dec_hdr == NULL) ||
|
||||||
(dispatch_size = gnrc_sixlowpan_iphc_decode(ipv6, pkt, 0, 0)) == 0) {
|
(dispatch_size = gnrc_sixlowpan_iphc_decode(&dec_hdr, pkt, 0, 0)) == 0) {
|
||||||
DEBUG("6lo: error on IPHC decoding\n");
|
DEBUG("6lo: error on IPHC decoding\n");
|
||||||
if (ipv6 != NULL) {
|
if (dec_hdr != NULL) {
|
||||||
gnrc_pktbuf_release(ipv6);
|
gnrc_pktbuf_release(dec_hdr);
|
||||||
}
|
}
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return;
|
return;
|
||||||
@ -144,21 +145,18 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
sixlowpan = gnrc_pktbuf_mark(pkt, dispatch_size, GNRC_NETTYPE_SIXLOWPAN);
|
sixlowpan = gnrc_pktbuf_mark(pkt, dispatch_size, GNRC_NETTYPE_SIXLOWPAN);
|
||||||
if (sixlowpan == NULL) {
|
if (sixlowpan == NULL) {
|
||||||
DEBUG("6lo: error on marking IPHC dispatch\n");
|
DEBUG("6lo: error on marking IPHC dispatch\n");
|
||||||
gnrc_pktbuf_release(ipv6);
|
gnrc_pktbuf_release(dec_hdr);
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove IPHC dispatch */
|
/* Remove IPHC dispatches */
|
||||||
gnrc_pktbuf_remove_snip(pkt, sixlowpan);
|
gnrc_pktbuf_remove_snip(pkt, sixlowpan);
|
||||||
/* Insert IPv6 header instead */
|
/* Insert decoded header instead */
|
||||||
if (ipv6->next != NULL) {
|
LL_SEARCH_SCALAR(dec_hdr, tmp, next, NULL); /* search last decoded header */
|
||||||
ipv6->next->next = pkt->next;
|
tmp->next = pkt->next;
|
||||||
}
|
pkt->next = dec_hdr;
|
||||||
else {
|
payload->type = GNRC_NETTYPE_UNDEF;
|
||||||
ipv6->next = pkt->next;
|
|
||||||
}
|
|
||||||
pkt->next = ipv6;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else {
|
else {
|
||||||
@ -167,9 +165,6 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
|||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
payload->type = GNRC_NETTYPE_IPV6;
|
|
||||||
|
|
||||||
if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
|
if (!gnrc_netapi_dispatch_receive(GNRC_NETTYPE_IPV6, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
|
||||||
DEBUG("6lo: No receivers for this packet found\n");
|
DEBUG("6lo: No receivers for this packet found\n");
|
||||||
gnrc_pktbuf_release(pkt);
|
gnrc_pktbuf_release(pkt);
|
||||||
|
@ -111,16 +111,18 @@ static inline bool _context_overlaps_iid(gnrc_sixlowpan_ctx_t *ctx,
|
|||||||
(iid->uint8[(ctx->prefix_len / 8) - 8] & byte_mask[ctx->prefix_len % 8])));
|
(iid->uint8[(ctx->prefix_len / 8) - 8] & byte_mask[ctx->prefix_len % 8])));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_UDP
|
#if defined(MODULE_GNRC_UDP) && defined(MODULE_GNRC_SIXLOWPAN_IPHC_NHC)
|
||||||
inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *ipv6, size_t offset)
|
inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t **dec_hdr,
|
||||||
|
size_t offset)
|
||||||
{
|
{
|
||||||
uint8_t *payload = pkt->data;
|
uint8_t *payload = pkt->data;
|
||||||
uint8_t udp_nhc = payload[offset++];
|
gnrc_pktsnip_t *ipv6 = *dec_hdr;
|
||||||
ipv6_hdr_t *ipv6_hdr = ipv6->data;
|
ipv6_hdr_t *ipv6_hdr = ipv6->data;
|
||||||
uint8_t tmp;
|
|
||||||
|
|
||||||
gnrc_pktsnip_t *udp = gnrc_pktbuf_add(NULL, NULL, sizeof(udp_hdr_t),
|
gnrc_pktsnip_t *udp = gnrc_pktbuf_add(NULL, NULL, sizeof(udp_hdr_t),
|
||||||
GNRC_NETTYPE_UDP);
|
GNRC_NETTYPE_UDP);
|
||||||
|
uint8_t udp_nhc = payload[offset++];
|
||||||
|
uint8_t tmp;
|
||||||
|
|
||||||
if (udp == NULL) {
|
if (udp == NULL) {
|
||||||
DEBUG("6lo: error on IPHC NHC UDP decoding\n");
|
DEBUG("6lo: error on IPHC NHC UDP decoding\n");
|
||||||
return 0;
|
return 0;
|
||||||
@ -178,21 +180,25 @@ inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t *ip
|
|||||||
ipv6_hdr->nh = PROTNUM_UDP;
|
ipv6_hdr->nh = PROTNUM_UDP;
|
||||||
ipv6_hdr->len = udp_hdr->length;
|
ipv6_hdr->len = udp_hdr->length;
|
||||||
|
|
||||||
ipv6->next = udp;
|
udp->next = ipv6;
|
||||||
|
*dec_hdr = udp;
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *pkt, size_t datagram_size,
|
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||||
size_t offset)
|
size_t datagram_size, size_t offset)
|
||||||
{
|
{
|
||||||
|
gnrc_pktsnip_t *ipv6;
|
||||||
gnrc_netif_hdr_t *netif_hdr = pkt->next->data;
|
gnrc_netif_hdr_t *netif_hdr = pkt->next->data;
|
||||||
ipv6_hdr_t *ipv6_hdr;
|
ipv6_hdr_t *ipv6_hdr;
|
||||||
uint8_t *iphc_hdr = pkt->data;
|
uint8_t *iphc_hdr = pkt->data;
|
||||||
size_t payload_offset = SIXLOWPAN_IPHC_HDR_LEN;
|
size_t payload_offset = SIXLOWPAN_IPHC_HDR_LEN;
|
||||||
gnrc_sixlowpan_ctx_t *ctx = NULL;
|
gnrc_sixlowpan_ctx_t *ctx = NULL;
|
||||||
|
|
||||||
|
assert(dec_hdr != NULL);
|
||||||
|
ipv6 = *dec_hdr;
|
||||||
assert(ipv6 != NULL);
|
assert(ipv6 != NULL);
|
||||||
assert(ipv6->size >= sizeof(ipv6_hdr_t));
|
assert(ipv6->size >= sizeof(ipv6_hdr_t));
|
||||||
|
|
||||||
@ -472,7 +478,7 @@ size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *pkt, siz
|
|||||||
switch (iphc_hdr[payload_offset] & NHC_ID_MASK) {
|
switch (iphc_hdr[payload_offset] & NHC_ID_MASK) {
|
||||||
#ifdef MODULE_GNRC_UDP
|
#ifdef MODULE_GNRC_UDP
|
||||||
case NHC_UDP_ID:
|
case NHC_UDP_ID:
|
||||||
payload_offset = iphc_nhc_udp_decode(pkt, ipv6, payload_offset);
|
payload_offset = iphc_nhc_udp_decode(pkt, dec_hdr, payload_offset);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -485,7 +491,7 @@ size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t *ipv6, gnrc_pktsnip_t *pkt, siz
|
|||||||
return payload_offset;
|
return payload_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MODULE_GNRC_UDP
|
#if defined(MODULE_GNRC_UDP) && defined(MODULE_GNRC_SIXLOWPAN_IPHC_NHC)
|
||||||
inline static size_t iphc_nhc_udp_encode(gnrc_pktsnip_t *udp, ipv6_hdr_t *ipv6_hdr)
|
inline static size_t iphc_nhc_udp_encode(gnrc_pktsnip_t *udp, ipv6_hdr_t *ipv6_hdr)
|
||||||
{
|
{
|
||||||
udp_hdr_t *udp_hdr = udp->data;
|
udp_hdr_t *udp_hdr = udp->data;
|
||||||
|
Loading…
Reference in New Issue
Block a user