6LoWPAN: Correct an error in uncompressing multicast address.

This commit is contained in:
Gregory Nutt 2017-09-08 09:23:40 -06:00
parent b725f1bb2f
commit 9cc85aadf6
3 changed files with 65 additions and 28 deletions

View File

@ -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

View File

@ -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

View File

@ -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
****************************************************************************/
@ -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 */
@ -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;
@ -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);
@ -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 */
@ -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 */
@ -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 */
@ -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 };