Skip to content

Commit

Permalink
6LoWPAN: Correct an error in uncompressing multicast address.
Browse files Browse the repository at this point in the history
  • Loading branch information
gregory-nutt committed Sep 8, 2017
1 parent b725f1b commit 9cc85aa
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 28 deletions.
2 changes: 1 addition & 1 deletion configs/sim/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,7 @@ pf_ieee802154
pktradio

This configuration is identical to the 'sixlowpan configuration
described below EXCEPT that is uses the genericl packet radio
described below EXCEPT that is uses the generic packet radio
loopback network device.

sixlowpan
Expand Down
24 changes: 16 additions & 8 deletions include/nuttx/net/sixlowpan.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,25 @@
#define SIXLOWPAN_IPHC_CID 0x80 /* Bit 8: Context identifier extension */
#define SIXLOWPAN_IPHC_SAC 0x40 /* Bit 9: Source address compression */
#define SIXLOWPAN_IPHC_SAM_MASK 0x30 /* Bits 10-11: Source address mode */
# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
# define SIXLOWPAN_IPHC_SAM_128 0x00 /* 128-bits */
# define SIXLOWPAN_IPHC_SAM_64 0x10 /* 64-bits */
# define SIXLOWPAN_IPHC_SAM_16 0x20 /* 16-bits */
# define SIXLOWPAN_IPHC_SAM_0 0x30 /* 0-bits */
#define SIXLOWPAN_IPHC_M 0x08 /* Bit 12: Multicast compression */
#define SIXLOWPAN_IPHC_DAC 0x04 /* Bit 13: Destination address compression */
#define SIXLOWPAN_IPHC_DAM_MASK 0x03 /* Bits 14-15: Destination address mode */
# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
/* M=0 DAC=0/1: */
# define SIXLOWPAN_IPHC_DAM_128 0x00 /* 128-bits */
# define SIXLOWPAN_IPHC_DAM_64 0x01 /* 64-bits */
# define SIXLOWPAN_IPHC_DAM_16 0x02 /* 16-bits */
# define SIXLOWPAN_IPHC_DAM_0 0x03 /* 0-bits */
/* M=1 DAC=0: */
# define SIXLOWPAN_IPHC_MDAM_128 0x00 /* 128-bits */
# define SIXLOWPAN_IPHC_MDAM_48 0x01 /* 48-bits: ffxx::00xx:xxxx:xxxx */
# define SIXLOWPAN_IPHC_MDAM_32 0x02 /* 16-bits: ffxx::00xx:xxxx */
# define SIXLOWPAN_IPHC_MDAM_8 0x03 /* 8-bits: ff02::00xx */
/* M=1 DAC=1: */
# define SIXLOWPAN_IPHC_MDDAM_48 0x00 /* 48-bits: ffxx:xxll:pppp:pppp:pppp:pppp:xxxx:xxxx */

#define SIXLOWPAN_IPHC_SAM_BIT 4
#define SIXLOWPAN_IPHC_DAM_BIT 0
Expand Down
67 changes: 48 additions & 19 deletions net/sixlowpan/sixlowpan_hc06.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,21 @@

#ifdef CONFIG_NET_6LOWPAN_COMPRESSION_HC06

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

/* Used in the encoding of address uncompress rules */

#define UNCOMPRESS_POSTLEN_SHIFT 0
#define UNCOMPRESS_POSTLEN_MASK (0x0f << UNCOMPRESS_POSTLEN_SHIFT)
# define UNCOMPRESS_POSTLEN(n) (((n) & UNCOMPRESS_POSTLEN_MASK) >> UNCOMPRESS_POSTLEN_SHIFT)
#define UNCOMPRESS_PREFLEN_SHIFT 4
#define UNCOMPRESS_PREFLEN_MASK (0x0f << UNCOMPRESS_PREFLEN_SHIFT)
# define UNCOMPRESS_PREFLEN(n) (((n) & UNCOMPRESS_PREFLEN_MASK) >> UNCOMPRESS_PREFLEN_SHIFT)
#define UNCOMPRESS_MACBASED (1 << 8)
#define UNCOMPRESS_ZEROPAD (1 << 9)

/****************************************************************************
* Private Types
****************************************************************************/
Expand Down Expand Up @@ -139,15 +154,17 @@ static const uint16_t g_unc_ctxconf[] =

/* Uncompression of mx-based
*
* 0 -> 0 bits from packet
* 1 -> 2 bytes from prefix - Bunch of zeroes 5 bytes from packet
* 2 -> 2 bytes from prefix - Zeroes + 3 bytes from packet
* 3 -> 2 bytes from prefix - Infer 1 bytes from MAC address
* 0 -> 0 bits from prefix / 16 bytes inline
* 1 -> 2 bytes from prefix / 5 bytes inline: ffxx::00xx:xxxx:xxxx
* 2 -> 2 bytes from prefix / 3 bytes inline: ffxx::00xx:xxxx
* 3 -> 2 bytes from prefix / 1 byte inline: ff02::00xx
*
* All other bits required zero padding.
*/

static const uint16_t g_unc_mxconf[] =
{
0x000f, 0x0025, 0x0023, 0x0121
0x020f, 0x0225, 0x0223, 0x0221
};

/* Link local prefix */
Expand Down Expand Up @@ -391,9 +408,9 @@ static void uncompress_addr(FAR const struct netdev_varaddr_s *addr,
{
FAR const uint8_t *srcptr;
bool fullmac = false;
bool usemac = (prefpost & 0x0100) != 0;
uint8_t prefcount = (prefpost >> 4) & 0xf;
uint8_t postcount = prefpost & 0x0f;
bool usemac = (prefpost & UNCOMPRESS_MACBASED) != 0;
uint8_t prefcount = UNCOMPRESS_PREFLEN(prefpost);
uint8_t postcount = UNCOMPRESS_POSTLEN(prefpost);
int destndx;
int endndx;
int i;
Expand Down Expand Up @@ -448,9 +465,15 @@ static void uncompress_addr(FAR const struct netdev_varaddr_s *addr,

if (postcount > 0)
{
if (postcount <= 2 && prefcount < 11)
/* If there is space for the ...:00ff:fe00:... and if we were not
* asked t specifically zero pad the address, then add these magic
* bits to the decoded address.
*/

if (postcount <= 2 && prefcount < 11 &&
(prefpost & UNCOMPRESS_ZEROPAD) == 0)
{
/* 16 bits uncompression ipaddr=0000:00ff:fe00:XXXX */
/* 16 bit uncompression ipaddr=0000:00ff:fe00:xxxx */

ipaddr[5] = HTONS(0x00ff);
ipaddr[6] = HTONS(0xfe00);
Expand Down Expand Up @@ -833,18 +856,24 @@ int sixlowpan_compresshdr_hc06(FAR struct radio_driver_s *radio,
iphc1 |= SIXLOWPAN_IPHC_M;
if (SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE8(ipv6->destipaddr))
{
iphc1 |= SIXLOWPAN_IPHC_DAM_0;
iphc1 |= SIXLOWPAN_IPHC_MDAM_8;

/* Use last byte */
/* Use "last" byte ("last" meaning the LS byte in host order.
* destipaddr is in big-endian network order).
*/

*g_hc06ptr = ipv6->destipaddr[7] & 0x00ff;
#ifdef CONFIG_ENDIAN_BIG
*g_hc06ptr = (ipv6->destipaddr[7] & 0xff);
#else
*g_hc06ptr = (ipv6->destipaddr[7] >> 8);
#endif
g_hc06ptr += 1;
}
else if (SIXLOWPAN_IS_MCASTADDR_COMPRESSABLE32(ipv6->destipaddr))
{
FAR uint8_t *iptr = (FAR uint8_t *)ipv6->destipaddr;

iphc1 |= SIXLOWPAN_IPHC_DAM_16;
iphc1 |= SIXLOWPAN_IPHC_MDAM_32;

/* Second byte + the last three */

Expand All @@ -856,7 +885,7 @@ int sixlowpan_compresshdr_hc06(FAR struct radio_driver_s *radio,
{
FAR uint8_t *iptr = (FAR uint8_t *)ipv6->destipaddr;

iphc1 |= SIXLOWPAN_IPHC_DAM_64;
iphc1 |= SIXLOWPAN_IPHC_MDAM_48;

/* Second byte + the last five */

Expand All @@ -866,7 +895,7 @@ int sixlowpan_compresshdr_hc06(FAR struct radio_driver_s *radio,
}
else
{
iphc1 |= SIXLOWPAN_IPHC_DAM_128;
iphc1 |= SIXLOWPAN_IPHC_MDAM_128;

/* Full address */

Expand Down Expand Up @@ -1233,9 +1262,9 @@ void sixlowpan_uncompresshdr_hc06(FAR struct radio_driver_s *radio,
/* Non-address context based multicast compression
*
* DAM 00: 128 bits
* DAM 01: 48 bits FFXX::00XX:XXXX:XXXX
* DAM 10: 32 bits FFXX::00XX:XXXX
* DAM 11: 8 bits FF02::00XX
* DAM 01: 48 bits ffxx::00xx:xxxx:xxxx
* DAM 10: 32 bits ffxx::00xx:xxxx
* DAM 11: 8 bits ff02::00xx
*/

uint8_t prefix[] = { 0xff, 0x02 };
Expand Down

0 comments on commit 9cc85aa

Please sign in to comment.