diff --git a/os/net/rpl-classic/rpl-ext-header.c b/os/net/rpl-classic/rpl-ext-header.c index 0c1f8076a..8fab6d165 100644 --- a/os/net/rpl-classic/rpl-ext-header.c +++ b/os/net/rpl-classic/rpl-ext-header.c @@ -592,9 +592,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -602,17 +604,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - PRINTF("RPL: Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /* diff --git a/os/net/rpl-lite/rpl-ext-header.c b/os/net/rpl-lite/rpl-ext-header.c index e71e6c1f6..ee0e2a2db 100644 --- a/os/net/rpl-lite/rpl-ext-header.c +++ b/os/net/rpl-lite/rpl-ext-header.c @@ -531,9 +531,11 @@ rpl_ext_header_remove(void) { uint8_t temp_len; uint8_t rpl_ext_hdr_len; + int uip_ext_opt_offset; uint8_t *uip_next_hdr; uip_ext_len = 0; + uip_ext_opt_offset = 2; uip_next_hdr = &UIP_IP_BUF->proto; /* Look for hop-by-hop and routing headers */ @@ -541,17 +543,22 @@ rpl_ext_header_remove(void) switch(*uip_next_hdr) { case UIP_PROTO_HBHO: case UIP_PROTO_ROUTING: - /* Remove hop-by-hop and routing headers */ - *uip_next_hdr = UIP_EXT_BUF->next; - rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; - temp_len = UIP_IP_BUF->len[1]; - uip_len -= rpl_ext_hdr_len; - UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; - if(UIP_IP_BUF->len[1] > temp_len) { - UIP_IP_BUF->len[0]--; + if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) { + /* Remove hop-by-hop and routing headers */ + *uip_next_hdr = UIP_EXT_BUF->next; + rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8; + temp_len = UIP_IP_BUF->len[1]; + uip_len -= rpl_ext_hdr_len; + UIP_IP_BUF->len[1] -= rpl_ext_hdr_len; + if(UIP_IP_BUF->len[1] > temp_len) { + UIP_IP_BUF->len[0]--; + } + LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); + memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); + } else { + uip_next_hdr = &UIP_EXT_BUF->next; + uip_ext_len += (UIP_EXT_BUF->len << 3) + 8; } - LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len); - memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN); break; case UIP_PROTO_DESTO: /*