mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-27 15:31:17 +01:00
gnrc_sixlowpan_iphc_nhc: fix NHC UDP decoding for fragmented packets
This commit is contained in:
parent
367d8af649
commit
ae52bf9a12
@ -46,7 +46,8 @@ extern "C" {
|
||||
* @return 0 on error.
|
||||
*/
|
||||
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||
size_t datagram_size, size_t offset);
|
||||
size_t datagram_size, size_t offset,
|
||||
size_t *nh_len);
|
||||
|
||||
/**
|
||||
* @brief Compresses a 6LoWPAN for IPHC.
|
||||
|
||||
@ -101,9 +101,9 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
||||
}
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
||||
else if (sixlowpan_iphc_is(data)) {
|
||||
size_t iphc_len;
|
||||
size_t iphc_len, nh_len = 0;
|
||||
iphc_len = gnrc_sixlowpan_iphc_decode(&entry->pkt, pkt, entry->pkt->size,
|
||||
sizeof(sixlowpan_frag_t));
|
||||
sizeof(sixlowpan_frag_t), &nh_len);
|
||||
if (iphc_len == 0) {
|
||||
DEBUG("6lo rfrag: could not decode IPHC dispatch\n");
|
||||
gnrc_pktbuf_release(entry->pkt);
|
||||
@ -112,8 +112,10 @@ void rbuf_add(gnrc_netif_hdr_t *netif_hdr, gnrc_pktsnip_t *pkt,
|
||||
}
|
||||
data += iphc_len; /* take remaining data as data */
|
||||
frag_size -= iphc_len; /* and reduce frag size by IPHC dispatch length */
|
||||
frag_size += sizeof(ipv6_hdr_t); /* but add IPv6 header length */
|
||||
data_offset += sizeof(ipv6_hdr_t); /* start copying after IPv6 header */
|
||||
/* but add IPv6 header + next header lengths */
|
||||
frag_size += sizeof(ipv6_hdr_t) + nh_len;
|
||||
/* start copying after IPv6 header and next headers */
|
||||
data_offset += sizeof(ipv6_hdr_t) + nh_len;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -129,12 +129,13 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
#endif
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC
|
||||
else if (sixlowpan_iphc_is(dispatch)) {
|
||||
size_t dispatch_size;
|
||||
size_t dispatch_size, nh_len;
|
||||
gnrc_pktsnip_t *sixlowpan, *tmp;
|
||||
gnrc_pktsnip_t *dec_hdr = gnrc_pktbuf_add(NULL, NULL, sizeof(ipv6_hdr_t),
|
||||
GNRC_NETTYPE_IPV6);
|
||||
if ((dec_hdr == NULL) ||
|
||||
(dispatch_size = gnrc_sixlowpan_iphc_decode(&dec_hdr, pkt, 0, 0)) == 0) {
|
||||
(dispatch_size = gnrc_sixlowpan_iphc_decode(&dec_hdr, pkt, 0, 0,
|
||||
&nh_len)) == 0) {
|
||||
DEBUG("6lo: error on IPHC decoding\n");
|
||||
if (dec_hdr != NULL) {
|
||||
gnrc_pktbuf_release(dec_hdr);
|
||||
|
||||
@ -112,7 +112,7 @@ static inline bool _context_overlaps_iid(gnrc_sixlowpan_ctx_t *ctx,
|
||||
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_IPHC_NHC
|
||||
inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t **dec_hdr,
|
||||
size_t offset)
|
||||
size_t datagram_size, size_t offset)
|
||||
{
|
||||
uint8_t *payload = pkt->data;
|
||||
gnrc_pktsnip_t *ipv6 = *dec_hdr;
|
||||
@ -122,16 +122,25 @@ inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t **d
|
||||
#else
|
||||
const gnrc_nettype_t snip_type = GNRC_NETTYPE_UNDEF;
|
||||
#endif
|
||||
gnrc_pktsnip_t *udp = gnrc_pktbuf_add(NULL, NULL, sizeof(udp_hdr_t),
|
||||
snip_type);
|
||||
gnrc_pktsnip_t *udp = NULL;
|
||||
uint8_t udp_nhc = payload[offset++];
|
||||
uint8_t tmp;
|
||||
udp_hdr_t *udp_hdr;
|
||||
|
||||
if (udp == NULL) {
|
||||
DEBUG("6lo: error on IPHC NHC UDP decoding\n");
|
||||
return 0;
|
||||
if (datagram_size == 0) { /* received packet is not fragmented */
|
||||
udp = gnrc_pktbuf_add(NULL, NULL, sizeof(udp_hdr_t),
|
||||
snip_type);
|
||||
if (udp == NULL) {
|
||||
DEBUG("6lo: error on IPHC NHC UDP decoding\n");
|
||||
return 0;
|
||||
}
|
||||
udp_hdr = udp->data;
|
||||
}
|
||||
else { /* received packet is fragmented */
|
||||
/* reassembly is in-place => don't allocate new packet snip */
|
||||
/* TODO: account for extension headers */
|
||||
udp_hdr = (udp_hdr_t *)(ipv6_hdr + 1);
|
||||
}
|
||||
udp_hdr_t *udp_hdr = udp->data;
|
||||
network_uint16_t *src_port = &(udp_hdr->src_port);
|
||||
network_uint16_t *dst_port = &(udp_hdr->dst_port);
|
||||
|
||||
@ -180,19 +189,28 @@ inline static size_t iphc_nhc_udp_decode(gnrc_pktsnip_t *pkt, gnrc_pktsnip_t **d
|
||||
udp_hdr->checksum.u8[1] = payload[offset++];
|
||||
}
|
||||
|
||||
udp_hdr->length = byteorder_htons(pkt->size - offset + sizeof(udp_hdr_t));
|
||||
/* TODO subtract extension header length */
|
||||
if (udp != NULL) {
|
||||
udp_hdr->length = byteorder_htons(pkt->size - offset + sizeof(udp_hdr_t));
|
||||
}
|
||||
else {
|
||||
udp_hdr->length = byteorder_htons(datagram_size - sizeof(ipv6_hdr_t));
|
||||
}
|
||||
ipv6_hdr->nh = PROTNUM_UDP;
|
||||
ipv6_hdr->len = udp_hdr->length;
|
||||
|
||||
udp->next = ipv6;
|
||||
*dec_hdr = udp;
|
||||
if (udp != NULL) { /* prepend udp header in case of packet not being fragmented */
|
||||
udp->next = ipv6;
|
||||
*dec_hdr = udp;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||
size_t datagram_size, size_t offset)
|
||||
size_t datagram_size, size_t offset,
|
||||
size_t *nh_len)
|
||||
{
|
||||
gnrc_pktsnip_t *ipv6;
|
||||
gnrc_netif_hdr_t *netif_hdr = pkt->next->data;
|
||||
@ -457,7 +475,6 @@ size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||
memcpy(ipv6_hdr->dst.u8 + 12, iphc_hdr + payload_offset + 2, 4);
|
||||
|
||||
payload_offset += 4;
|
||||
|
||||
ctx->prefix_len = orig_ctx_len;
|
||||
} while (0); /* ANSI-C compatible block creation for orig_ctx_len allocation */
|
||||
break;
|
||||
@ -481,13 +498,17 @@ size_t gnrc_sixlowpan_iphc_decode(gnrc_pktsnip_t **dec_hdr, gnrc_pktsnip_t *pkt,
|
||||
if (iphc_hdr[IPHC1_IDX] & SIXLOWPAN_IPHC1_NH) {
|
||||
switch (iphc_hdr[payload_offset] & NHC_ID_MASK) {
|
||||
case NHC_UDP_ID:
|
||||
payload_offset = iphc_nhc_udp_decode(pkt, dec_hdr, payload_offset);
|
||||
payload_offset = iphc_nhc_udp_decode(pkt, dec_hdr, datagram_size,
|
||||
payload_offset + offset) - offset;
|
||||
*nh_len += sizeof(udp_hdr_t);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)nh_len;
|
||||
#endif
|
||||
|
||||
return payload_offset;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user