diff --git a/core/net/sicslowpan.c b/core/net/sicslowpan.c index 2a795d09d..e58724126 100644 --- a/core/net/sicslowpan.c +++ b/core/net/sicslowpan.c @@ -268,7 +268,7 @@ static uint8_t *hc06_ptr; /* Uncompression of linklocal */ /* 0 -> 16 bytes from packet */ /* 1 -> 2 bytes from prefix - bunch of zeroes and 8 from packet */ -/* 2 -> 2 bytes from prefix - zeroes + 2 from packet */ +/* 2 -> 2 bytes from prefix - 0000::00ff:fe00:XXXX from packet */ /* 3 -> 2 bytes from prefix - infer 8 bytes from lladdr */ /* NOTE: => the uncompress function does change 0xf to 0x10 */ /* NOTE: 0x00 => no-autoconfig => unspecified */ @@ -277,7 +277,7 @@ const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20}; /* Uncompression of ctx-based */ /* 0 -> 0 bits from packet [unspecified / reserved] */ /* 1 -> 8 bytes from prefix - bunch of zeroes and 8 from packet */ -/* 2 -> 8 bytes from prefix - zeroes + 2 from packet */ +/* 2 -> 8 bytes from prefix - 0000::00ff:fe00:XXXX + 2 from packet */ /* 3 -> 8 bytes from prefix - infer 8 bytes from lladdr */ const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80}; @@ -338,7 +338,7 @@ compress_addr_64(uint8_t bitpos, uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr) if(uip_is_addr_mac_addr_based(ipaddr, lladdr)) { return 3 << bitpos; /* 0-bits */ } else if(sicslowpan_is_iid_16_bit_compressable(ipaddr)) { - /* compress IID to 16 bits xxxx::XXXX */ + /* compress IID to 16 bits xxxx::0000:00ff:fe00:XXXX */ memcpy(hc06_ptr, &ipaddr->u16[7], 2); hc06_ptr += 2; return 2 << bitpos; /* 16-bits */ @@ -377,6 +377,11 @@ uncompress_addr(uip_ipaddr_t *ipaddr, uint8_t const prefix[], } if(postcount > 0) { memcpy(&ipaddr->u8[16 - postcount], hc06_ptr, postcount); + if(postcount == 2 && prefcount < 11) { + /* 16 bits uncompression => 0000:00ff:fe00:XXXX */ + ipaddr->u8[11] = 0xff; + ipaddr->u8[12] = 0xfe; + } hc06_ptr += postcount; } else if (prefcount > 0) { /* no IID based configuration if no prefix and no data => unspec */ diff --git a/core/net/sicslowpan.h b/core/net/sicslowpan.h index 49488bcc2..33bcc1078 100644 --- a/core/net/sicslowpan.h +++ b/core/net/sicslowpan.h @@ -233,13 +233,14 @@ struct sicslowpan_addr_context { * \brief check whether we can compress the IID in * address 'a' to 16 bits. * This is used for unicast addresses only, and is true - * if first 49 bits of IID are 0 + * the address is on the format ::0000:00ff:fe00:XXXX */ #define sicslowpan_is_iid_16_bit_compressable(a) \ ((((a)->u16[4]) == 0) && \ - (((a)->u16[5]) == 0) && \ - (((a)->u16[6]) == 0) && \ - ((((a)->u8[14]) & 0x80) == 0)) + (((a)->u8[10]) == 0) && \ + (((a)->u8[11]) == 0xff) && \ + (((a)->u8[12]) == 0xfe) && \ + (((a)->u8[13]) == 0)) /** * \brief check whether the 9-bit group-id of the