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
+48 -19
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 };