New mechanism for computing the 6lowpan header length dynamically, depending on how large header the framer creates. Also check the incoming packet for buffer overflow.
This commit is contained in:
parent
cb2336a322
commit
3efa84ecc8
1 changed files with 42 additions and 4 deletions
|
@ -163,7 +163,11 @@ void uip_log(char *msg);
|
||||||
|
|
||||||
|
|
||||||
/** \brief Size of the 802.15.4 payload (127byte - 25 for MAC header) */
|
/** \brief Size of the 802.15.4 payload (127byte - 25 for MAC header) */
|
||||||
|
#ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
|
||||||
|
#define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
|
||||||
|
#else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
||||||
#define MAC_MAX_PAYLOAD 102
|
#define MAC_MAX_PAYLOAD 102
|
||||||
|
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
||||||
|
|
||||||
|
|
||||||
/** \brief Some MAC layers need a minimum payload, which is
|
/** \brief Some MAC layers need a minimum payload, which is
|
||||||
|
@ -1355,6 +1359,8 @@ send_packet(rimeaddr_t *dest)
|
||||||
static uint8_t
|
static uint8_t
|
||||||
output(uip_lladdr_t *localdest)
|
output(uip_lladdr_t *localdest)
|
||||||
{
|
{
|
||||||
|
int framer_hdrlen;
|
||||||
|
|
||||||
/* The MAC address of the destination of the packet */
|
/* The MAC address of the destination of the packet */
|
||||||
rimeaddr_t dest;
|
rimeaddr_t dest;
|
||||||
|
|
||||||
|
@ -1422,7 +1428,24 @@ output(uip_lladdr_t *localdest)
|
||||||
}
|
}
|
||||||
PRINTFO("sicslowpan output: header of len %d\n", rime_hdr_len);
|
PRINTFO("sicslowpan output: header of len %d\n", rime_hdr_len);
|
||||||
|
|
||||||
if(uip_len - uncomp_hdr_len > MAC_MAX_PAYLOAD - rime_hdr_len) {
|
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_RDC.
|
||||||
|
* We calculate it here only to make a better decision of whether the outgoing packet
|
||||||
|
* needs to be fragmented or not. */
|
||||||
|
#define USE_FRAMER_HDRLEN 1
|
||||||
|
#if USE_FRAMER_HDRLEN
|
||||||
|
packetbuf_clear();
|
||||||
|
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||||
|
framer_hdrlen = NETSTACK_FRAMER.create();
|
||||||
|
if(framer_hdrlen < 0) {
|
||||||
|
/* Framing failed, we assume the maximum header length */
|
||||||
|
framer_hdrlen = 21;
|
||||||
|
}
|
||||||
|
packetbuf_clear();
|
||||||
|
#else /* USE_FRAMER_HDRLEN */
|
||||||
|
framer_hdrlen = 21;
|
||||||
|
#endif /* USE_FRAMER_HDRLEN */
|
||||||
|
|
||||||
|
if((int)uip_len - (int)uncomp_hdr_len > (int)MAC_MAX_PAYLOAD - framer_hdrlen - (int)rime_hdr_len) {
|
||||||
#if SICSLOWPAN_CONF_FRAG
|
#if SICSLOWPAN_CONF_FRAG
|
||||||
struct queuebuf *q;
|
struct queuebuf *q;
|
||||||
/*
|
/*
|
||||||
|
@ -1455,7 +1478,7 @@ output(uip_lladdr_t *localdest)
|
||||||
|
|
||||||
/* Copy payload and send */
|
/* Copy payload and send */
|
||||||
rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
|
rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
|
||||||
rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8;
|
rime_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - rime_hdr_len) & 0xf8;
|
||||||
PRINTFO("(len %d, tag %d)\n", rime_payload_len, my_tag);
|
PRINTFO("(len %d, tag %d)\n", rime_payload_len, my_tag);
|
||||||
memcpy(rime_ptr + rime_hdr_len,
|
memcpy(rime_ptr + rime_hdr_len,
|
||||||
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, rime_payload_len);
|
(uint8_t *)UIP_IP_BUF + uncomp_hdr_len, rime_payload_len);
|
||||||
|
@ -1491,7 +1514,7 @@ output(uip_lladdr_t *localdest)
|
||||||
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
|
/* uip_htons((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len); */
|
||||||
SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE,
|
SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE,
|
||||||
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
|
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
|
||||||
rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8;
|
rime_payload_len = (MAC_MAX_PAYLOAD - framer_hdrlen - rime_hdr_len) & 0xf8;
|
||||||
while(processed_ip_out_len < uip_len) {
|
while(processed_ip_out_len < uip_len) {
|
||||||
PRINTFO("sicslowpan output: fragment ");
|
PRINTFO("sicslowpan output: fragment ");
|
||||||
RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_out_len >> 3;
|
RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_out_len >> 3;
|
||||||
|
@ -1530,6 +1553,7 @@ output(uip_lladdr_t *localdest)
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* SICSLOWPAN_CONF_FRAG */
|
#endif /* SICSLOWPAN_CONF_FRAG */
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The packet does not need to be fragmented
|
* The packet does not need to be fragmented
|
||||||
* copy "payload" and send
|
* copy "payload" and send
|
||||||
|
@ -1709,6 +1733,20 @@ input(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rime_payload_len = packetbuf_datalen() - rime_hdr_len;
|
rime_payload_len = packetbuf_datalen() - rime_hdr_len;
|
||||||
|
|
||||||
|
/* Sanity-check size of incoming packet to avoid buffer overflow */
|
||||||
|
{
|
||||||
|
int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3)
|
||||||
|
+ rime_payload_len;
|
||||||
|
if(req_size > sizeof(sicslowpan_buf)) {
|
||||||
|
PRINTF(
|
||||||
|
"SICSLOWPAN: packet dropped, minimum required SICSLOWPAN_IP_BUF size: %d+%d+%d+%d=%d (current size: %d)\n",
|
||||||
|
UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3),
|
||||||
|
rime_payload_len, req_size, sizeof(sicslowpan_buf));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len);
|
memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len);
|
||||||
|
|
||||||
/* update processed_ip_in_len if fragment, sicslowpan_len otherwise */
|
/* update processed_ip_in_len if fragment, sicslowpan_len otherwise */
|
||||||
|
|
Loading…
Add table
Reference in a new issue