Skip to content

Commit

Permalink
6lowpan: add function to uncompress multicast addr
Browse files Browse the repository at this point in the history
Add function to uncompress multicast address.
This function split the uncompress function for a multicast address
in a seperate function.

To uncompress a multicast address is different than a other
non-multicasts addresses according to rfc6282.

Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Reviewed-by: Werner Almesberger <werner@almesberger.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Alexander Aring authored and David S. Miller committed Aug 20, 2013
1 parent 4666669 commit 84c2e7b
Showing 1 changed file with 59 additions and 19 deletions.
78 changes: 59 additions & 19 deletions net/ieee802154/6lowpan.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,6 @@ static const u8 lowpan_unc_llconf[] = {0x0f, 0x28, 0x22, 0x20};
*/
static const u8 lowpan_unc_ctxconf[] = {0x00, 0x88, 0x82, 0x80};

/*
* Uncompression of ctx-base
* 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
*/
static const u8 lowpan_unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};

/* Link local prefix */
static const u8 lowpan_llprefix[] = {0xfe, 0x80};

Expand Down Expand Up @@ -240,6 +231,63 @@ lowpan_uncompress_addr(struct sk_buff *skb, struct in6_addr *ipaddr,
return 0;
}

/* Uncompress function for multicast destination address,
* when M bit is set.
*/
static int
lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
struct in6_addr *ipaddr,
const u8 dam)
{
bool fail;

switch (dam) {
case LOWPAN_IPHC_DAM_00:
/* 00: 128 bits. The full address
* is carried in-line.
*/
fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16);
break;
case LOWPAN_IPHC_DAM_01:
/* 01: 48 bits. The address takes
* the form ffXX::00XX:XXXX:XXXX.
*/
ipaddr->s6_addr[0] = 0xFF;
fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5);
break;
case LOWPAN_IPHC_DAM_10:
/* 10: 32 bits. The address takes
* the form ffXX::00XX:XXXX.
*/
ipaddr->s6_addr[0] = 0xFF;
fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3);
break;
case LOWPAN_IPHC_DAM_11:
/* 11: 8 bits. The address takes
* the form ff02::00XX.
*/
ipaddr->s6_addr[0] = 0xFF;
ipaddr->s6_addr[1] = 0x02;
fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1);
break;
default:
pr_debug("DAM value has a wrong value: 0x%x\n", dam);
return -EINVAL;
}

if (fail) {
pr_debug("Failed to fetch skb data\n");
return -EIO;
}

lowpan_raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is:\n",
ipaddr->s6_addr, 16);

return 0;
}

static void
lowpan_compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
{
Expand Down Expand Up @@ -927,16 +975,8 @@ lowpan_process_data(struct sk_buff *skb)
pr_debug("dest: context-based mcast compression\n");
/* TODO: implement this */
} else {
u8 prefix[] = {0xff, 0x02};

pr_debug("dest: non context-based mcast compression\n");
if (0 < tmp && tmp < 3) {
if (lowpan_fetch_skb_u8(skb, &prefix[1]))
goto drop;
}

err = lowpan_uncompress_addr(skb, &hdr.daddr, prefix,
lowpan_unc_mxconf[tmp], NULL);
err = lowpan_uncompress_multicast_daddr(
skb, &hdr.daddr, tmp);
if (err)
goto drop;
}
Expand Down

0 comments on commit 84c2e7b

Please sign in to comment.