Stateless decompression mode 3 combines the MAC address from the MAC header with link-local prefix FE80::/64 to reconstruct the original IPv6 address. This patch corrects comments, variable llconf and lowpan_uncompress_addr to be compatible with RFC 4644.
Signed-off-by: Ralph Droms <rdr...@cisco.com> --- net/ieee802154/6lowpan.c | 50 +++++++++++++++++++++++++++------------------ 1 files changed, 30 insertions(+), 20 deletions(-) diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c index 55e1fd5..a7bac63 100644 --- a/net/ieee802154/6lowpan.c +++ b/net/ieee802154/6lowpan.c @@ -68,32 +68,32 @@ static const u8 lowpan_ttl_values[] = {0, 1, 64, 255}; static LIST_HEAD(lowpan_devices); /* - * Uncompression of linklocal: + * Uncompression of stateless unicast: * 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 - * 3 -> 2 bytes from prefix - infer 8 bytes from lladdr + * 3 -> 2 bytes from prefix - IID == MAC * * NOTE: => the uncompress function does change 0xf to 0x10 * NOTE: 0x00 => no-autoconfig => unspecified */ -static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20}; +static const u8 lowpan_unc_slconf[] = {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 - * 3 -> 8 bytes from prefix - infer 8 bytes from lladdr + * 3 -> 8 bytes from prefix - IID == MAC */ static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80}; /* - * Uncompression of ctx-base + * Uncompression of stateless multicast: * 0 -> 0 bits from packet * 1 -> 2 bytes from prefix - bunch of zeroes 5 from packet * 2 -> 2 bytes from prefix - zeroes + 3 from packet - * 3 -> 2 bytes from prefix - infer 1 bytes from lladdr + * 3 -> 2 bytes from prefix - infer 1 bytes from MAC */ static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21}; @@ -208,7 +208,7 @@ lowpan_uip_ds6_set_addr_iid(struct in6_addr *ipaddr, unsigned char *lladdr) */ static int lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, - u8 const *prefix, u8 pref_post_count, unsigned char *lladdr) + u8 const *prefix, u8 pref_post_count, unsigned char *macaddr) { u8 prefcount = pref_post_count >> 4; u8 postcount = pref_post_count & 0x0f; @@ -217,9 +217,9 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, prefcount = (prefcount == 15 ? 16 : prefcount); postcount = (postcount == 15 ? 16 : postcount); - if (lladdr) + if (macaddr) lowpan_raw_dump_inline(__func__, "linklocal address", - lladdr, IEEE802154_ADDR_LEN); + macaddr, IEEE802154_ADDR_LEN); if (prefcount > 0) memcpy(ipaddr, prefix, prefcount); @@ -231,11 +231,11 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr, memcpy(&ipaddr->s6_addr[16 - postcount], skb->data, postcount); skb_pull(skb, postcount); } else if (prefcount > 0) { - if (lladdr == NULL) + if (macaddr == NULL) return -EINVAL; /* no IID based configuration if no prefix and no data */ - lowpan_uip_ds6_set_addr_iid(ipaddr, lladdr); + lowpan_uip_ds6_set_addr_iid(ipaddr, macaddr); } pr_debug("uncompressing %d + %d => ", prefcount, postcount); @@ -916,24 +916,34 @@ lowpan_process_data(struct sk_buff *skb) tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03; /* Source address uncompression */ - pr_debug("source address stateless compression\n"); - err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, - lowpan_unc_llconf[tmp], skb->data); - if (err) + pr_debug("source address uncompression - SAM %d\n", tmp); + if (iphc1 & LOWPAN_IPHC_SAC) { + pr_debug("stateful source uncompression not implemented\n"); goto drop; + } else { + pr_debug("stateless source uncompression\n"); + err = lowpan_uncompress_addr(skb, &hdr.saddr, lowpan_llprefix, + lowpan_unc_slconf[tmp], skb->data); + if (err) + goto drop; + } /* Extract DAM to the tmp variable */ tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03; + /* destination address uncompression */ + pr_debug("source address uncompression - M %d, DAM %d\n", + iphc1 & LOWPAN_IPHC_M, tmp); + /* check for Multicast Compression */ if (iphc1 & LOWPAN_IPHC_M) { if (iphc1 & LOWPAN_IPHC_DAC) { - pr_debug("dest: context-based mcast compression\n"); - /* TODO: implement this */ + pr_debug("context-based mcast uncompression not implemented\n"); + /* TODO: implement this; does not depend on contex distribution */ } else { u8 prefix[] = {0xff, 0x02}; - pr_debug("dest: non context-based mcast compression\n"); + pr_debug("stateless mcast uncompression\n"); if (0 < tmp && tmp < 3) { if (lowpan_fetch_skb_u8(skb, &prefix[1])) goto drop; @@ -945,9 +955,9 @@ lowpan_process_data(struct sk_buff *skb) goto drop; } } else { - pr_debug("dest: stateless compression\n"); + pr_debug("stateless compression\n"); err = lowpan_uncompress_addr(skb, &hdr.daddr, lowpan_llprefix, - lowpan_unc_llconf[tmp], skb->data); + lowpan_unc_slconf[tmp], skb->data); if (err) goto drop; } -- 1.7.7.6 ------------------------------------------------------------------------------ Precog is a next-generation analytics platform capable of advanced analytics on semi-structured data. The platform includes APIs for building apps and a phenomenal toolset for data science. Developers can use our toolset for easy data analysis & visualization. Get a free account! http://www2.precog.com/precogplatform/slashdotnewsletter _______________________________________________ Linux-zigbee-devel mailing list Linux-zigbee-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel