]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-802_15_4.c
Makefile.in: don't remove configure and config.h.in in make distclean.
[tcpdump] / print-802_15_4.c
index 3e1bc8a8b404d2478fed6bbc4e657d1e41c0192c..1895be7ca19b9a8a420ffb0fd3c4723088180d2a 100644 (file)
@@ -26,8 +26,9 @@
 #include <config.h>
 #endif
 
-#include <netdissect-stdinc.h>
+#include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "addrtoname.h"
 
@@ -256,7 +257,7 @@ static const char *p_mlme_short_names[] = {
        "CTM IE",                                       /* 0x32 */
        "Timestamp IE",                                 /* 0x33 */
        "Timestamp Difference IE",                      /* 0x34 */
-       "TMCTP Sepcification IE",                       /* 0x35 */
+       "TMCTP Specification IE",                       /* 0x35 */
        "RCC PHY Operating Mode IE",                    /* 0x36 */
        "Reserved 0x37",                                /* 0x37 */
        "Reserved 0x38",                                /* 0x38 */
@@ -419,19 +420,20 @@ static const char *mac_c_names[] = {
 /*
  * IEEE 802.15.4 CRC 16 function. This is using CCITT polynomical of 0x1021,
  * but the initial value is 0, and the bits are reversed for both in and out.
- * See secton 7.2.10 of 802.15.4-2015 for more information.
+ * See section 7.2.10 of 802.15.4-2015 for more information.
  */
 static uint16_t
-ieee802_15_4_crc16(const u_char *p,
-                  uint16_t data_len)
+ieee802_15_4_crc16(netdissect_options *ndo, const u_char *p,
+                  u_int data_len)
 {
        uint16_t crc;
        u_char x, y;
-       
+
        crc = 0x0000; /* Note, initial value is 0x0000 not 0xffff. */
-       
-       while (data_len--){
-               y = *p++;
+
+       while (data_len != 0){
+               y = GET_U_1(p);
+               p++;
                /* Reverse bits on input */
                y = (((y & 0xaa) >> 1) | ((y & 0x55) << 1));
                y = (((y & 0xcc) >> 2) | ((y & 0x33) << 2));
@@ -439,10 +441,11 @@ ieee802_15_4_crc16(const u_char *p,
                /* Update CRC */
                x = crc >> 8 ^ y;
                x ^= x >> 4;
-               crc = (crc << 8) ^
-                       ((unsigned short)(x << 12)) ^
-                       ((unsigned short)(x <<5)) ^
-                       ((unsigned short)x);
+               crc = ((uint16_t)(crc << 8)) ^
+                       ((uint16_t)(x << 12)) ^
+                       ((uint16_t)(x << 5)) ^
+                       ((uint16_t)x);
+               data_len--;
        }
        /* Reverse bits on output */
        crc = (((crc & 0xaaaa) >> 1) | ((crc & 0x5555) << 1));
@@ -469,20 +472,20 @@ ieee802_15_4_reverse32(uint32_t x)
 /*
  * IEEE 802.15.4 CRC 32 function. This is using ANSI X3.66-1979 polynomical of
  * 0x04C11DB7, but the initial value is 0, and the bits are reversed for both
- * in and out. See secton 7.2.10 of 802.15.4-2015 for more information.
+ * in and out. See section 7.2.10 of 802.15.4-2015 for more information.
  */
 static uint32_t
-ieee802_15_4_crc32(const u_char *p,
-                  uint16_t data_len)
+ieee802_15_4_crc32(netdissect_options *ndo, const u_char *p,
+                  u_int data_len)
 {
        uint32_t crc, byte;
-       u_char x;
        int b;
-       
+
        crc = 0x00000000; /* Note, initial value is 0x00000000 not 0xffffffff */
-       
-       while (data_len--){
-               byte = *p++;
+
+       while (data_len != 0){
+               byte = GET_U_1(p);
+               p++;
                /* Reverse bits on input */
                byte = ieee802_15_4_reverse32(byte);
                /* Update CRC */
@@ -493,6 +496,7 @@ ieee802_15_4_crc32(const u_char *p,
                    crc = crc << 1;
                  byte = byte << 1;
                }
+               data_len--;
        }
        /* Reverse bits on output */
        crc = ieee802_15_4_reverse32(crc);
@@ -539,13 +543,12 @@ ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p,
                ND_PRINT("none");
                break;
        case 2:
-               ND_PRINT("%04x", EXTRACT_LE_U_2(p));
+               ND_PRINT("%04x", GET_LE_U_2(p));
                break;
        case 8:
-               ND_PRINT("%s", le64addr_string(ndo, p));
+               ND_PRINT("%s", GET_LE64ADDR_STRING(p));
                break;
        }
-       return;
 }
 
 /*
@@ -566,7 +569,7 @@ ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
                 ((ss >> 8) & 0xf));
        if (CHECK_BIT(ss, 12)) { ND_PRINT(", BLE enabled"); }
        if (CHECK_BIT(ss, 14)) { ND_PRINT(", PAN Coordinator"); }
-       if (CHECK_BIT(ss, 15)) { ND_PRINT(", Assocation Permit"); }
+       if (CHECK_BIT(ss, 15)) { ND_PRINT(", Association Permit"); }
 }
 
 /*
@@ -578,14 +581,15 @@ ieee802_15_4_print_superframe_specification(netdissect_options *ndo,
 static int
 ieee802_15_4_print_gts_info(netdissect_options *ndo,
                            const u_char *p,
-                           uint16_t data_len)
+                           u_int data_len)
 {
        uint8_t gts_spec, gts_cnt;
-       int len, i;
-       
-       gts_spec = EXTRACT_U_1(p);
+       u_int len;
+       int i;
+
+       gts_spec = GET_U_1(p);
        gts_cnt = gts_spec & 0x7;
-       
+
        if (gts_cnt == 0) {
                if (ndo->ndo_vflag > 0) {
                        ND_PRINT("\n\tGTS Descriptor Count = %d, ", gts_cnt);
@@ -593,7 +597,7 @@ ieee802_15_4_print_gts_info(netdissect_options *ndo,
                return 1;
        }
        len = 1 + 1 + gts_cnt * 3;
-       
+
        if (data_len < len) {
                ND_PRINT(" [ERROR: Truncated GTS Info List]");
                return -1;
@@ -603,14 +607,14 @@ ieee802_15_4_print_gts_info(netdissect_options *ndo,
        }
        ND_PRINT("GTS Descriptor Count = %d, ", gts_cnt);
        ND_PRINT("GTS Directions Mask = %02x, [ ",
-                EXTRACT_U_1(p + 1) & 0x7f);
-       
+                GET_U_1(p + 1) & 0x7f);
+
        for(i = 0; i < gts_cnt; i++) {
                ND_PRINT("[ ");
                ieee802_15_4_print_addr(ndo, p + 2 + i * 3, 2);
                ND_PRINT(", Start slot = %d, Length = %d ] ",
-                        EXTRACT_U_1(p + 2 + i * 3 + 1) & 0x0f,
-                        (EXTRACT_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
+                        GET_U_1(p + 2 + i * 3 + 1) & 0x0f,
+                        (GET_U_1(p + 2 + i * 3 + 1) >> 4) & 0x0f);
        }
        ND_PRINT("]");
        return len;
@@ -625,11 +629,11 @@ ieee802_15_4_print_gts_info(netdissect_options *ndo,
 static int16_t
 ieee802_15_4_print_pending_addresses(netdissect_options *ndo,
                                     const u_char *p,
-                                    uint16_t data_len)
+                                    u_int data_len)
 {
        uint8_t pas, s_cnt, e_cnt, len, i;
-       
-       pas = EXTRACT_U_1(p);
+
+       pas = GET_U_1(p);
        s_cnt = pas & 0x7;
        e_cnt = (pas >> 4) & 0x7;
        len = 1 + s_cnt * 2 + e_cnt * 8;
@@ -653,11 +657,11 @@ ieee802_15_4_print_pending_addresses(netdissect_options *ndo,
                }
                ND_PRINT("]");
        }
-       if (s_cnt != 0) {
+       if (e_cnt != 0) {
                ND_PRINT(", Extended address list = [ ");
                for(i = 0; i < e_cnt; i++) {
                        ieee802_15_4_print_addr(ndo, p + 1 + s_cnt * 2 +
-                                               e_cnt * 8, 8);
+                                               i * 8, 8);
                        ND_PRINT(" ");
                }
                ND_PRINT("]");
@@ -675,17 +679,17 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                             int element_id)
 {
        int i;
-       
+
        switch (element_id) {
        case 0x00: /* Vendor Specific Header IE */
                if (ie_len < 3) {
                        ND_PRINT("[ERROR: Vendor OUI missing]");
                } else {
-                       ND_PRINT("OUI = 0x%02x%02x%02x, ", EXTRACT_U_1(p),
-                                EXTRACT_U_1(p + 1), EXTRACT_U_1(p + 2));
+                       ND_PRINT("OUI = 0x%02x%02x%02x, ", GET_U_1(p),
+                                GET_U_1(p + 1), GET_U_1(p + 2));
                        ND_PRINT("Data = ");
                        for(i = 3; i < ie_len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                               ND_PRINT("%02x ", GET_U_1(p + i));
                        }
                }
                break;
@@ -694,10 +698,10 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Truncated CSL IE]");
                } else {
                        ND_PRINT("CSL Phase = %d, CSL Period = %d",
-                                EXTRACT_LE_U_2(p), EXTRACT_LE_U_2(p + 2));
+                                GET_LE_U_2(p), GET_LE_U_2(p + 2));
                        if (ie_len >= 6) {
                                ND_PRINT(", Rendezvous time = %d",
-                                        EXTRACT_LE_U_2(p + 4));
+                                        GET_LE_U_2(p + 4));
                        }
                        if (ie_len != 4 && ie_len != 6) {
                                ND_PRINT(" [ERROR: CSL IE length wrong]");
@@ -709,23 +713,24 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Truncated RIT IE]");
                } else {
                        ND_PRINT("Time to First Listen = %d, # of Repeat Listen = %d, Repeat Listen Interval = %d",
-                                EXTRACT_U_1(p),
-                                EXTRACT_U_1(p + 1),
-                                EXTRACT_LE_U_2(p + 2));
+                                GET_U_1(p),
+                                GET_U_1(p + 1),
+                                GET_LE_U_2(p + 2));
                }
                break;
        case 0x1c: /* DSME PAN Descriptor IE */
                /*FALLTHROUGH*/
-       case 0x21: /* Extended DSME PAN descriptior IE */
+       case 0x21: /* Extended DSME PAN descriptor IE */
                if (ie_len < 2) {
                        ND_PRINT("[ERROR: Truncated DSME PAN IE]");
                } else {
-                       uint16_t ss, ptr, len;
+                       uint16_t ss, ptr, ulen;
+                       int16_t len;
                        int hopping_present;
-                       
+
                        hopping_present = 0;
-                       
-                       ss = EXTRACT_LE_U_2(p);
+
+                       ss = GET_LE_U_2(p);
                        ieee802_15_4_print_superframe_specification(ndo, ss);
                        if (ie_len < 3) {
                                ND_PRINT("[ERROR: Truncated before pending addresses field]");
@@ -740,14 +745,14 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                                break;
                        }
                        ptr += len;
-                       
+
                        if (element_id == 0x21) {
                                /* Extended version. */
                                if (ie_len < ptr + 2) {
                                        ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
                                        break;
                                }
-                               ss = EXTRACT_LE_U_2(p + ptr);
+                               ss = GET_LE_U_2(p + ptr);
                                ptr += 2;
                                ND_PRINT("Multi-superframe Order = %d", ss & 0xff);
                                ND_PRINT(", %s", ((ss & 0x100) ?
@@ -768,7 +773,7 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                                        ND_PRINT("[ERROR: Truncated before DSME Superframe Specification]");
                                        break;
                                }
-                               ss = EXTRACT_U_1(p + ptr);
+                               ss = GET_U_1(p + ptr);
                                ptr++;
                                ND_PRINT("Multi-superframe Order = %d",
                                         ss & 0x0f);
@@ -783,76 +788,77 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                                }
                        }
                        if (ie_len < ptr + 8) {
-                               ND_PRINT(" [ERROR: Truncated before Time syncronization specification]");
+                               ND_PRINT(" [ERROR: Truncated before Time synchronization specification]");
                                break;
                        }
                        ND_PRINT("Beacon timestamp = %" PRIu64 ", offset = %d",
-                                EXTRACT_LE_U_6(p + ptr),
-                                EXTRACT_LE_U_2(p + ptr + 6));
+                                GET_LE_U_6(p + ptr),
+                                GET_LE_U_2(p + ptr + 6));
                        ptr += 8;
                        if (ie_len < ptr + 4) {
                                ND_PRINT(" [ERROR: Truncated before Beacon Bitmap]");
                                break;
                        }
-                       
-                       len = EXTRACT_LE_U_2(p + ptr + 2);
+
+                       ulen = GET_LE_U_2(p + ptr + 2);
                        ND_PRINT("SD Index = %d, Bitmap len = %d, ",
-                                EXTRACT_LE_U_2(p + ptr), len);
+                                GET_LE_U_2(p + ptr), ulen);
                        ptr += 4;
-                       if (ie_len < ptr + len) {
+                       if (ie_len < ptr + ulen) {
                                ND_PRINT(" [ERROR: Truncated in SD bitmap]");
                                break;
                        }
                        ND_PRINT(" SD Bitmap = ");
-                       for(i = 0; i < len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + ptr + i));
+                       for(i = 0; i < ulen; i++) {
+                               ND_PRINT("%02x ", GET_U_1(p + ptr + i));
                        }
-                       ptr += len;
-                       
+                       ptr += ulen;
+
                        if (ie_len < ptr + 5) {
                                ND_PRINT(" [ERROR: Truncated before Channel hopping specification]");
                                break;
                        }
-                       
-                       len = EXTRACT_LE_U_2(p + ptr + 4);
+
+                       ulen = GET_LE_U_2(p + ptr + 4);
                        ND_PRINT("Hopping Seq ID = %d, PAN Coordinator BSN = %d, "
                                 "Channel offset = %d, Bitmap length = %d, ",
-                                EXTRACT_U_1(p + ptr),
-                                EXTRACT_U_1(p + ptr + 1),
-                                EXTRACT_LE_U_2(p + ptr + 2),
-                                len);
+                                GET_U_1(p + ptr),
+                                GET_U_1(p + ptr + 1),
+                                GET_LE_U_2(p + ptr + 2),
+                                ulen);
                        ptr += 5;
-                       if (ie_len < ptr + len) {
+                       if (ie_len < ptr + ulen) {
                                ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]");
                                break;
                        }
                        ND_PRINT(" Channel offset bitmap = ");
-                       for(i = 0; i < len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + ptr + i));
+                       for(i = 0; i < ulen; i++) {
+                               ND_PRINT("%02x ", GET_U_1(p + ptr + i));
                        }
-                       ptr += len;
+                       ptr += ulen;
                        if (hopping_present) {
                                if (ie_len < ptr + 1) {
                                        ND_PRINT(" [ERROR: Truncated in Hopping Sequence length]");
                                        break;
                                }
-                               len = EXTRACT_U_1(p + ptr);
+                               ulen = GET_U_1(p + ptr);
                                ptr++;
-                               ND_PRINT("Hopping Seq length = %d [ ", len);
-                               
+                               ND_PRINT("Hopping Seq length = %d [ ", ulen);
+
                                /* The specification is not clear how the
                                   hopping sequence is encoded, I assume two
                                   octet unsigned integers for each channel. */
-                               
-                               if (ie_len < ptr + len * 2) {
+
+                               if (ie_len < ptr + ulen * 2) {
                                        ND_PRINT(" [ERROR: Truncated in Channel offset bitmap]");
                                        break;
                                }
-                               for(i = 0; i < len; i++) {
-                                       ND_PRINT("%02x ", EXTRACT_LE_U_2(p + ptr + i * 2));
+                               for(i = 0; i < ulen; i++) {
+                                       ND_PRINT("%02x ",
+                                                GET_LE_U_2(p + ptr + i * 2));
                                }
                                ND_PRINT("]");
-                               ptr += len * 2;
+                               ptr += ulen * 2;
                        }
                }
                break;
@@ -861,9 +867,9 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Length != 2]");
                } else {
                        uint16_t r_time, w_u_interval;
-                       r_time = EXTRACT_LE_U_2(p);
-                       w_u_interval = EXTRACT_LE_U_2(p + 2);
-                       
+                       r_time = GET_LE_U_2(p);
+                       w_u_interval = GET_LE_U_2(p + 2);
+
                        ND_PRINT("Rendezvous time = %d, Wake-up Interval = %d",
                                 r_time, w_u_interval);
                }
@@ -874,18 +880,18 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                } else {
                        uint16_t val;
                        int16_t timecorr;
-                       
-                       val = EXTRACT_LE_U_2(p);
+
+                       val = GET_LE_U_2(p);
                        if (val & 0x8000) { ND_PRINT("Negative "); }
                        val &= 0xfff;
                        val <<= 4;
                        timecorr = val;
                        timecorr >>= 4;
-                       
+
                        ND_PRINT("Ack time correction = %d, ", timecorr);
                }
                break;
-       case 0x22: /* Frament Sequence Content Description IE */
+       case 0x22: /* Fragment Sequence Content Description IE */
                /* XXX Not implemented */
        case 0x23: /* Simplified Superframe Specification IE */
                /* XXX Not implemented */
@@ -906,7 +912,7 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
        default:
                ND_PRINT("IE Data = ");
                for(i = 0; i < ie_len; i++) {
-                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                       ND_PRINT("%02x ", GET_U_1(p + i));
                }
                break;
        }
@@ -921,12 +927,12 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
 static int
 ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                                  const u_char *p,
-                                 uint16_t caplen,
+                                 u_int caplen,
                                  int *payload_ie_present)
 {
        int len, ie, element_id, i;
        uint16_t ie_len;
-       
+
        *payload_ie_present = 0;
        len = 0;
        do {
@@ -935,7 +941,7 @@ ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                        return -1;
                }
                /* Extract IE Header */
-               ie = EXTRACT_LE_U_2(p);
+               ie = GET_LE_U_2(p);
                if (CHECK_BIT(ie, 15)) {
                        ND_PRINT("[ERROR: Header IE with type 1] ");
                }
@@ -953,13 +959,13 @@ ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                                         h_ie_names[element_id], ie_len);
                        }
                }
-               if (caplen < ie_len) {
+               if (caplen < 2U + ie_len) {
                        ND_PRINT("[ERROR: Truncated IE data]");
                        return -1;
                }
                /* Skip header */
                p += 2;
-               
+
                /* Parse and print content. */
                if (ndo->ndo_vflag > 3 && ie_len != 0) {
                        ieee802_15_4_print_header_ie(ndo, p,
@@ -968,7 +974,7 @@ ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                        if (ie_len != 0) {
                                ND_PRINT("IE Data = ");
                                for(i = 0; i < ie_len; i++) {
-                                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
                                }
                        }
                }
@@ -983,7 +989,7 @@ ieee802_15_4_print_header_ie_list(netdissect_options *ndo,
                if (element_id == 0x7f) {
                        break;
                }
-       } while (caplen > 0);
+       } while (caplen != 0);
        return len;
 }
 
@@ -996,8 +1002,9 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                           uint16_t sub_ie_len,
                           int sub_id)
 {
-       int i, j, len;
-       
+       int i, j;
+       uint16_t len;
+
        /* Note, as there is no overlap with the long and short
           MLME sub IDs, we can just use one switch here. */
        switch (sub_id) {
@@ -1006,12 +1013,12 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Vendor OUI missing]");
                } else {
                        ND_PRINT("OUI = 0x%02x%02x%02x, ",
-                                EXTRACT_U_1(p),
-                                EXTRACT_U_1(p + 1),
-                                EXTRACT_U_1(p + 2));
+                                GET_U_1(p),
+                                GET_U_1(p + 1),
+                                GET_U_1(p + 2));
                        ND_PRINT("Data = ");
                        for(i = 3; i < sub_ie_len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                               ND_PRINT("%02x ", GET_U_1(p + i));
                        }
                }
                break;
@@ -1019,25 +1026,25 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                if (sub_ie_len < 1) {
                        ND_PRINT("[ERROR: Hopping sequence ID missing]");
                } else if (sub_ie_len == 1) {
-                       ND_PRINT("Hopping Sequence ID = %d", EXTRACT_U_1(p));
+                       ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
                        p++;
                        sub_ie_len--;
                } else {
-                       int channel_page, number_of_channels;
-                       
-                       ND_PRINT("Hopping Sequence ID = %d", EXTRACT_U_1(p));
+                       uint16_t channel_page, number_of_channels;
+
+                       ND_PRINT("Hopping Sequence ID = %d", GET_U_1(p));
                        p++;
                        sub_ie_len--;
                        if (sub_ie_len < 7) {
                                ND_PRINT("[ERROR: IE truncated]");
                                break;
                        }
-                       channel_page = EXTRACT_U_1(p);
-                       number_of_channels = EXTRACT_LE_U_2(p + 1);
+                       channel_page = GET_U_1(p);
+                       number_of_channels = GET_LE_U_2(p + 1);
                        ND_PRINT("Channel Page = %d, Number of Channels = %d, ",
                                 channel_page, number_of_channels);
                        ND_PRINT("Phy Configuration = 0x%08x, ",
-                                EXTRACT_LE_U_4(p + 3));
+                                GET_LE_U_4(p + 3));
                        p += 7;
                        sub_ie_len -= 7;
                        if (channel_page == 9 || channel_page == 10) {
@@ -1048,7 +1055,7 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                                }
                                ND_PRINT("Extended bitmap = 0x");
                                for(i = 0; i < len; i++) {
-                                       ND_PRINT("%02x", EXTRACT_U_1(p + i));
+                                       ND_PRINT("%02x", GET_U_1(p + i));
                                }
                                ND_PRINT(", ");
                                p += len;
@@ -1058,17 +1065,17 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                                ND_PRINT("[ERROR: IE truncated]");
                                break;
                        }
-                       len = EXTRACT_LE_U_2(p);
+                       len = GET_LE_U_2(p);
                        p += 2;
                        sub_ie_len -= 2;
                        ND_PRINT("Hopping Seq length = %d [ ", len);
-                       
+
                        if (sub_ie_len < len * 2) {
                                ND_PRINT(" [ERROR: IE truncated]");
                                break;
                        }
                        for(i = 0; i < len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_LE_U_2(p + i * 2));
+                               ND_PRINT("%02x ", GET_LE_U_2(p + i * 2));
                        }
                        ND_PRINT("]");
                        p += len * 2;
@@ -1077,26 +1084,26 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                                ND_PRINT("[ERROR: IE truncated]");
                                break;
                        }
-                       ND_PRINT("Current hop = %d", EXTRACT_LE_U_2(p));
+                       ND_PRINT("Current hop = %d", GET_LE_U_2(p));
                }
-               
+
                break;
-       case 0x1a: /* TSCH Syncronization IE. */
+       case 0x1a: /* TSCH Synchronization IE. */
                if (sub_ie_len < 6) {
                        ND_PRINT("[ERROR: Length != 6]");
                }
                ND_PRINT("ASN = %010" PRIx64 ", Join Metric = %d ",
-                        EXTRACT_LE_U_5(p), EXTRACT_U_1(p + 5));
+                        GET_LE_U_5(p), GET_U_1(p + 5));
                break;
        case 0x1b: /* TSCH Slotframe and Link IE. */
                {
                        int sf_num, off, links, opts;
-                       
+
                        if (sub_ie_len < 1) {
                                ND_PRINT("[ERROR: Truncated IE]");
                                break;
                        }
-                       sf_num = EXTRACT_U_1(p);
+                       sf_num = GET_U_1(p);
                        ND_PRINT("Slotframes = %d ", sf_num);
                        off = 1;
                        for(i = 0; i < sf_num; i++) {
@@ -1104,10 +1111,10 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                                        ND_PRINT("[ERROR: Truncated IE before slotframes]");
                                        break;
                                }
-                               links = EXTRACT_U_1(p + off + 3);
+                               links = GET_U_1(p + off + 3);
                                ND_PRINT("\n\t\t\t[ Handle %d, size = %d, links = %d ",
-                                        EXTRACT_U_1(p + off),
-                                        EXTRACT_LE_U_2(p + off + 1),
+                                        GET_U_1(p + off),
+                                        GET_LE_U_2(p + off + 1),
                                         links);
                                off += 4;
                                for(j = 0; j < links; j++) {
@@ -1115,10 +1122,10 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                                                ND_PRINT("[ERROR: Truncated IE links]");
                                                break;
                                        }
-                                       opts = EXTRACT_U_1(p + off + 4);
+                                       opts = GET_U_1(p + off + 4);
                                        ND_PRINT("\n\t\t\t\t[ Timeslot =  %d, Offset = %d, Options = ",
-                                                EXTRACT_LE_U_2(p + off),
-                                                EXTRACT_LE_U_2(p + off + 2));
+                                                GET_LE_U_2(p + off),
+                                                GET_LE_U_2(p + off + 2));
                                        if (opts & 0x1) { ND_PRINT("TX "); }
                                        if (opts & 0x2) { ND_PRINT("RX "); }
                                        if (opts & 0x4) { ND_PRINT("Shared "); }
@@ -1137,42 +1144,42 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                break;
        case 0x1c: /* TSCH Timeslot IE. */
                if (sub_ie_len == 1) {
-                       ND_PRINT("Time slot ID = %d ", EXTRACT_U_1(p));
+                       ND_PRINT("Time slot ID = %d ", GET_U_1(p));
                } else if (sub_ie_len == 25) {
                        ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
-                                EXTRACT_U_1(p),
-                                EXTRACT_LE_U_2(p + 1),
-                                EXTRACT_LE_U_2(p + 3),
-                                EXTRACT_LE_U_2(p + 5),
-                                EXTRACT_LE_U_2(p + 7),
-                                EXTRACT_LE_U_2(p + 9),
-                                EXTRACT_LE_U_2(p + 11),
-                                EXTRACT_LE_U_2(p + 13),
-                                EXTRACT_LE_U_2(p + 15),
-                                EXTRACT_LE_U_2(p + 17),
-                                EXTRACT_LE_U_2(p + 19),
-                                EXTRACT_LE_U_2(p + 21),
-                                EXTRACT_LE_U_2(p + 23));
+                                GET_U_1(p),
+                                GET_LE_U_2(p + 1),
+                                GET_LE_U_2(p + 3),
+                                GET_LE_U_2(p + 5),
+                                GET_LE_U_2(p + 7),
+                                GET_LE_U_2(p + 9),
+                                GET_LE_U_2(p + 11),
+                                GET_LE_U_2(p + 13),
+                                GET_LE_U_2(p + 15),
+                                GET_LE_U_2(p + 17),
+                                GET_LE_U_2(p + 19),
+                                GET_LE_U_2(p + 21),
+                                GET_LE_U_2(p + 23));
                } else if (sub_ie_len == 27) {
                        ND_PRINT("Time slot ID = %d, CCA Offset = %d, CCA = %d, TX Offset = %d, RX Offset = %d, RX Ack Delay = %d, TX Ack Delay = %d, RX Wait = %d, Ack Wait = %d, RX TX = %d, Max Ack = %d, Max TX = %d, Time slot Length = %d ",
-                                EXTRACT_U_1(p),
-                                EXTRACT_LE_U_2(p + 1),
-                                EXTRACT_LE_U_2(p + 3),
-                                EXTRACT_LE_U_2(p + 5),
-                                EXTRACT_LE_U_2(p + 7),
-                                EXTRACT_LE_U_2(p + 9),
-                                EXTRACT_LE_U_2(p + 11),
-                                EXTRACT_LE_U_2(p + 13),
-                                EXTRACT_LE_U_2(p + 15),
-                                EXTRACT_LE_U_2(p + 17),
-                                EXTRACT_LE_U_2(p + 19),
-                                EXTRACT_LE_U_3(p + 21),
-                                EXTRACT_LE_U_3(p + 24));
+                                GET_U_1(p),
+                                GET_LE_U_2(p + 1),
+                                GET_LE_U_2(p + 3),
+                                GET_LE_U_2(p + 5),
+                                GET_LE_U_2(p + 7),
+                                GET_LE_U_2(p + 9),
+                                GET_LE_U_2(p + 11),
+                                GET_LE_U_2(p + 13),
+                                GET_LE_U_2(p + 15),
+                                GET_LE_U_2(p + 17),
+                                GET_LE_U_2(p + 19),
+                                GET_LE_U_3(p + 21),
+                                GET_LE_U_3(p + 24));
                } else {
                        ND_PRINT("[ERROR: Length not 1, 25, or 27]");
                        ND_PRINT("\n\t\t\tIE Data = ");
                        for(i = 0; i < sub_ie_len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                               ND_PRINT("%02x ", GET_U_1(p + i));
                        }
                }
                break;
@@ -1206,7 +1213,7 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                /* XXX Not implemented */
        case 0x2c: /* TVWS Device Capabilities IE */
                /* XXX Not implemented */
-       case 0x2d: /* TVWS Device Catagory IE */
+       case 0x2d: /* TVWS Device Category IE */
                /* XXX Not implemented */
        case 0x2e: /* TVWS Device Identification IE */
                /* XXX Not implemented */
@@ -1229,7 +1236,7 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
        default:
                ND_PRINT("IE Data = ");
                for(i = 0; i < sub_ie_len; i++) {
-                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                       ND_PRINT("%02x ", GET_U_1(p + i));
                }
                break;
        }
@@ -1246,14 +1253,14 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
 {
        int ie, sub_id, i, type;
        uint16_t sub_ie_len;
-       
+
        do {
                if (ie_len < 2) {
                        ND_PRINT("[ERROR: Truncated MLME IE]");
                        return;
                }
                /* Extract IE header */
-               ie = EXTRACT_LE_U_2(p);
+               ie = GET_LE_U_2(p);
                type = CHECK_BIT(ie, 15);
                if (type) {
                        /* Long type */
@@ -1263,10 +1270,10 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                        sub_ie_len = ie & 0xff;
                        sub_id = (ie >> 8) & 0x7f;
                }
-               
+
                /* Skip the IE header */
                p += 2;
-               
+
                if (type == 0) {
                        ND_PRINT("\n\t\t%s [ length = %d, ",
                                 p_mlme_short_names[sub_id], sub_ie_len);
@@ -1274,8 +1281,8 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                        ND_PRINT("\n\t\t%s [ length = %d, ",
                                 p_mlme_long_names[sub_id], sub_ie_len);
                }
-               
-               if (ie_len < sub_ie_len) {
+
+               if (ie_len < 2 + sub_ie_len) {
                        ND_PRINT("[ERROR: Truncated IE data]");
                        return;
                }
@@ -1285,7 +1292,7 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                        } else if (ndo->ndo_vflag > 2) {
                                ND_PRINT("IE Data = ");
                                for(i = 0; i < sub_ie_len; i++) {
-                                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
                                }
                        }
                }
@@ -1293,7 +1300,6 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                p += sub_ie_len;
                ie_len -= 2 + sub_ie_len;
        } while (ie_len > 0);
-       return;
 }
 
 /*
@@ -1315,9 +1321,9 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
                ND_PRINT("[ERROR: Transaction control byte missing]");
                return;
        }
-               
-       transfer_type = EXTRACT_U_1(p) & 0x7;
-       tid = EXTRACT_U_1(p) >> 3;
+
+       transfer_type = GET_U_1(p) & 0x7;
+       tid = GET_U_1(p) >> 3;
        switch (transfer_type) {
        case 0x00: /* Full upper layer frame. */
        case 0x01: /* Full upper layer frame with small Multiplex ID. */
@@ -1328,10 +1334,10 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
                        if (ie_len < 3) {
                                ND_PRINT("[ERROR: Multiplex ID missing]");
                                return;
-                       } 
+                       }
                        data_start = 3;
                        ND_PRINT("tid = 0x%02x, Multiplex ID = 0x%04x, ",
-                                tid, EXTRACT_LE_U_2(p + 1));
+                                tid, GET_LE_U_2(p + 1));
                } else {
                        data_start = 1;
                        ND_PRINT("Multiplex ID = 0x%04x, ", tid);
@@ -1343,8 +1349,8 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
                        ND_PRINT("[ERROR: fragment number missing]");
                        return;
                }
-               
-               fragment_number = EXTRACT_U_1(p + 1);
+
+               fragment_number = GET_U_1(p + 1);
                ND_PRINT("Type = %s, tid = 0x%02x, fragment = 0x%02x, ",
                         (transfer_type == 0x02 ?
                          (fragment_number == 0 ?
@@ -1354,13 +1360,13 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
                data_start = 2;
                if (fragment_number == 0) {
                        int total_size, multiplex_id;
-                       
+
                        if (ie_len < 6) {
                                ND_PRINT("[ERROR: Total upper layer size or multiplex ID missing]");
                                return;
                        }
-                       total_size = EXTRACT_LE_U_2(p + 2);
-                       multiplex_id = EXTRACT_LE_U_2(p + 4);
+                       total_size = GET_LE_U_2(p + 2);
+                       multiplex_id = GET_LE_U_2(p + 4);
                        ND_PRINT("Total upper layer size = 0x%04x, Multiplex ID = 0x%04x, ",
                                 total_size, multiplex_id);
                        data_start = 6;
@@ -1372,13 +1378,13 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
                                 tid);
                } else if (ie_len == 3) {
                        ND_PRINT("Type = Abort, tid = 0x%02x, max size = 0x%04x",
-                                tid, EXTRACT_LE_U_2(p + 1));
+                                tid, GET_LE_U_2(p + 1));
                } else {
                        ND_PRINT("Type = Abort, tid = 0x%02x, invalid length = %d (not 1 or 3)",
                                 tid, ie_len);
                        ND_PRINT("Abort data = ");
                        for(i = 1; i < ie_len; i++) {
-                               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                               ND_PRINT("%02x ", GET_U_1(p + i));
                        }
                }
                return;
@@ -1395,7 +1401,7 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
 
        ND_PRINT("Upper layer data = ");
        for(i = data_start; i < ie_len; i++) {
-               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+               ND_PRINT("%02x ", GET_U_1(p + i));
        }
 }
 
@@ -1408,11 +1414,11 @@ ieee802_15_4_print_mpx_ie(netdissect_options *ndo,
 static int
 ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                                   const u_char *p,
-                                  uint16_t caplen)
+                                  u_int caplen)
 {
        int len, ie, group_id, i;
        uint16_t ie_len;
-       
+
        len = 0;
        do {
                if (caplen < 2) {
@@ -1420,13 +1426,13 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                        return -1;
                }
                /* Extract IE header */
-               ie = EXTRACT_LE_U_2(p);
+               ie = GET_LE_U_2(p);
                if ((CHECK_BIT(ie, 15)) == 0) {
                        ND_PRINT("[ERROR: Payload IE with type 0] ");
                }
                ie_len = ie & 0x3ff;
                group_id = (ie >> 11) & 0x0f;
-               
+
                /* Skip the IE header */
                p += 2;
                if (ie_len == 0) {
@@ -1435,7 +1441,7 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                        ND_PRINT("\n\t%s [ length = %d, ",
                                 p_ie_names[group_id], ie_len);
                }
-               if (caplen < ie_len) {
+               if (caplen < 2U + ie_len) {
                        ND_PRINT("[ERROR: Truncated IE data]");
                        return -1;
                }
@@ -1449,13 +1455,13 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                                        ND_PRINT("[ERROR: Vendor OUI missing]");
                                } else {
                                        ND_PRINT("OUI = 0x%02x%02x%02x, ",
-                                                EXTRACT_U_1(p),
-                                                EXTRACT_U_1(p + 1),
-                                                EXTRACT_U_1(p + 2));
+                                                GET_U_1(p),
+                                                GET_U_1(p + 1),
+                                                GET_U_1(p + 2));
                                        ND_PRINT("Data = ");
                                        for(i = 3; i < ie_len; i++) {
                                                ND_PRINT("%02x ",
-                                                        EXTRACT_U_1(p + i));
+                                                        GET_U_1(p + i));
                                        }
                                }
                                break;
@@ -1465,18 +1471,19 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                        case 0x5: /* IETF IE */
                                if (ie_len < 1) {
                                        ND_PRINT("[ERROR: Subtype ID missing]");
-                               } else {        
+                               } else {
                                        ND_PRINT("Subtype ID = 0x%02x, Subtype content = ",
-                                                EXTRACT_U_1(p));
+                                                GET_U_1(p));
                                        for(i = 1; i < ie_len; i++) {
-                                               ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                                               ND_PRINT("%02x ",
+                                                        GET_U_1(p + i));
                                        }
                                }
                                break;
                        default:
                                ND_PRINT("IE Data = ");
                                for(i = 0; i < ie_len; i++) {
-                                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
                                }
                                break;
                        }
@@ -1484,7 +1491,7 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
                        if (ie_len != 0) {
                                ND_PRINT("IE Data = ");
                                for(i = 0; i < ie_len; i++) {
-                                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                                       ND_PRINT("%02x ", GET_U_1(p + i));
                                }
                        }
                }
@@ -1507,23 +1514,23 @@ ieee802_15_4_print_payload_ie_list(netdissect_options *ndo,
 static int
 ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                                  const u_char *p,
-                                 uint16_t caplen,
+                                 u_int caplen,
                                  int *security_level)
 {
        int sc, key_id_mode, len;
-       
+
        if (caplen < 1) {
                ND_PRINT("[ERROR: Truncated before Aux Security Header]");
                return -1;
        }
-       sc = EXTRACT_U_1(p);
+       sc = GET_U_1(p);
        len = 1;
        *security_level = sc & 0x7;
        key_id_mode = (sc >> 3) & 0x3;
-       
+
        caplen -= 1;
        p += 1;
-       
+
        if (ndo->ndo_vflag > 0) {
                ND_PRINT("\n\tSecurity Level %d, Key Id Mode %d, ",
                         *security_level, key_id_mode);
@@ -1533,13 +1540,13 @@ ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Truncated before Frame Counter]");
                        return -1;
                }
-               len += 4;
-               caplen -= 4;
-               p += 4;
                if (ndo->ndo_vflag > 1) {
                        ND_PRINT("Frame Counter 0x%08x ",
-                                EXTRACT_LE_U_4(p + 1));
+                                GET_LE_U_4(p));
                }
+               p += 4;
+               caplen -= 4;
+               len += 4;
        }
        switch (key_id_mode) {
        case 0x00: /* Implicit. */
@@ -1557,7 +1564,7 @@ ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                }
                if (ndo->ndo_vflag > 1) {
                        ND_PRINT("KeySource 0x%04x:%0x4x, ",
-                                EXTRACT_LE_U_2(p), EXTRACT_LE_U_2(p + 2));
+                                GET_LE_U_2(p), GET_LE_U_2(p + 2));
                }
                p += 4;
                caplen -= 4;
@@ -1569,7 +1576,7 @@ ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                        return -1;
                }
                if (ndo->ndo_vflag > 1) {
-                       ND_PRINT("KeySource %s, ", le64addr_string(ndo, p));
+                       ND_PRINT("KeySource %s, ", GET_LE64ADDR_STRING(p));
                }
                p += 4;
                caplen -= 4;
@@ -1581,7 +1588,7 @@ ieee802_15_4_print_aux_sec_header(netdissect_options *ndo,
                return -1;
        }
        if (ndo->ndo_vflag > 1) {
-               ND_PRINT("KeyIndex 0x%02x, ", EXTRACT_U_1(p));
+               ND_PRINT("KeyIndex 0x%02x, ", GET_U_1(p));
        }
        caplen -= 1;
        p += 1;
@@ -1601,15 +1608,15 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                                u_int caplen)
 {
        u_int i;
-       
+
        switch (command_id) {
-       case 0x01: /* Assocation Request */
+       case 0x01: /* Association Request */
                if (caplen != 1) {
-                       ND_PRINT("Invalid Assocation request command length");
+                       ND_PRINT("Invalid Association request command length");
                        return -1;
                } else {
                        uint8_t cap_info;
-                       cap_info = EXTRACT_U_1(p);
+                       cap_info = GET_U_1(p);
                        ND_PRINT("%s%s%s%s%s%s",
                                 ((cap_info & 0x02) ?
                                  "FFD, " : "RFD, "),
@@ -1626,14 +1633,14 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                        return caplen;
                }
                break;
-       case 0x02: /* Assocation Response */
+       case 0x02: /* Association Response */
                if (caplen != 3) {
-                       ND_PRINT("Invalid Assocation response command length");
+                       ND_PRINT("Invalid Association response command length");
                        return -1;
                } else {
                        ND_PRINT("Short address = ");
                        ieee802_15_4_print_addr(ndo, p, 2);
-                       switch (EXTRACT_U_1(p + 2)) {
+                       switch (GET_U_1(p + 2)) {
                        case 0x00:
                                ND_PRINT(", Association successful");
                                break;
@@ -1651,7 +1658,7 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                                break;
                        default:
                                ND_PRINT(", Status = 0x%02x",
-                                        EXTRACT_U_1(p + 2));
+                                        GET_U_1(p + 2));
                                break;
                        }
                        return caplen;
@@ -1662,7 +1669,7 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                        ND_PRINT("Invalid Disassociation Notification command length");
                        return -1;
                } else {
-                       switch (EXTRACT_U_1(p)) {
+                       switch (GET_U_1(p)) {
                        case 0x00:
                                ND_PRINT("Reserved");
                                break;
@@ -1673,12 +1680,12 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                                ND_PRINT("Reason = The device wishes to leave the PAN");
                                break;
                        default:
-                               ND_PRINT("Reason = 0x%02x", EXTRACT_U_1(p + 2));
+                               ND_PRINT("Reason = 0x%02x", GET_U_1(p + 2));
                                break;
                        }
                        return caplen;
                }
-               
+
                /* Following ones do not have any data. */
        case 0x04: /* Data Request command */
        case 0x05: /* PAN ID Conflict Notification command */
@@ -1692,14 +1699,14 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                        return -1;
                } else {
                        uint16_t channel, page;
-                       
+
                        ND_PRINT("Pan ID = 0x%04x, Coordinator short address = ",
-                                EXTRACT_LE_U_2(p));
+                                GET_LE_U_2(p));
                        ieee802_15_4_print_addr(ndo, p + 2, 2);
-                       channel = EXTRACT_U_1(p + 4);
-                       
+                       channel = GET_U_1(p + 4);
+
                        if (caplen == 8) {
-                               page = EXTRACT_U_1(p + 7);
+                               page = GET_U_1(p + 7);
                        } else {
                                page = 0x80;
                        }
@@ -1723,8 +1730,8 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                        return -1;
                } else {
                        uint8_t gts;
-                       
-                       gts = EXTRACT_U_1(p);
+
+                       gts = GET_U_1(p);
                        ND_PRINT("GTS Length = %d, %s, %s",
                                 gts & 0xf,
                                 (CHECK_BIT(gts, 4) ?
@@ -1742,7 +1749,7 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
                /* XXX Not implemented */
        case 0x16: /* DSME GTS Response command */
                /* XXX Not implemented */
-       case 0x17: /* DSME GTS GTS Notify command */
+       case 0x17: /* DSME GTS Notify command */
                /* XXX Not implemented */
        case 0x18: /* DSME Information Request command */
                /* XXX Not implemented */
@@ -1771,7 +1778,7 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
        default:
                ND_PRINT("Command Data = ");
                for(i = 0; i < caplen; i++) {
-                       ND_PRINT("%02x ", EXTRACT_U_1(p + i));
+                       ND_PRINT("%02x ", GET_U_1(p + i));
                }
                break;
        }
@@ -1779,7 +1786,7 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
 }
 
 /*
- * Parse and print frames folloing standard format.
+ * Parse and print frames following standard format.
  *
  * Returns FALSE in case of error.
  */
@@ -1791,12 +1798,13 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        int len, frame_version, pan_id_comp;
        int frame_type;
        int src_pan, dst_pan, src_addr_len, dst_addr_len;
-       int security_level, miclen = 0;
+       int security_level;
+       u_int miclen = 0;
        int payload_ie_present;
        uint8_t seq;
        uint32_t fcs, crc_check;
        const u_char *mic_start = NULL;
-       
+
        payload_ie_present = 0;
 
        crc_check = 0;
@@ -1807,15 +1815,15 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                fcs = 0;
        } else {
                /* Test for 4 octet FCS. */
-               fcs = EXTRACT_LE_U_4(p + caplen - 4);
-               crc_check = ieee802_15_4_crc32(p, caplen - 4);
+               fcs = GET_LE_U_4(p + caplen - 4);
+               crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
                if (crc_check == fcs) {
                        /* Remove FCS */
                        caplen -= 4;
                } else {
                        /* Test for 2 octet FCS. */
-                       fcs = EXTRACT_LE_U_2(p + caplen - 2);
-                       crc_check = ieee802_15_4_crc16(p, caplen - 2);
+                       fcs = GET_LE_U_2(p + caplen - 2);
+                       crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
                        if (crc_check == fcs) {
                                /* Remove FCS */
                                caplen -= 2;
@@ -1825,12 +1833,12 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                        }
                }
        }
-       
+
        /* Frame version. */
        frame_version = FC_FRAME_VERSION(fc);
        frame_type = FC_FRAME_TYPE(fc);
        ND_PRINT("v%d ", frame_version);
-       
+
        if (ndo->ndo_vflag > 2) {
                if (CHECK_BIT(fc, 3)) { ND_PRINT("Security Enabled, "); }
                if (CHECK_BIT(fc, 4)) { ND_PRINT("Frame Pending, "); }
@@ -1839,27 +1847,35 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                if (CHECK_BIT(fc, 8)) { ND_PRINT("Sequence Number Suppression, "); }
                if (CHECK_BIT(fc, 9)) { ND_PRINT("IE present, "); }
        }
-       
-       /* Check for the sequence number supression. */
+
+       /* Check for the sequence number suppression. */
        if (CHECK_BIT(fc, 8)) {
                /* Sequence number is suppressed. */
                if (frame_version < 2) {
-                       /* Sequence number can only be supressed for frame
+                       /* Sequence number can only be suppressed for frame
                           version 2 or higher, this is invalid frame. */
                        ND_PRINT("[ERROR: Sequence number suppressed on frames where version < 2]");
                }
                if (ndo->ndo_vflag)
                        ND_PRINT("seq suppressed ");
+               if (caplen < 2) {
+                       nd_print_trunc(ndo);
+                       return 0;
+               }
                p += 2;
                caplen -= 2;
        } else {
-               seq = EXTRACT_U_1(p + 2);
-               p += 3;
-               caplen -= 3;
+               seq = GET_U_1(p + 2);
                if (ndo->ndo_vflag)
                        ND_PRINT("seq %02x ", seq);
+               if (caplen < 3) {
+                       nd_print_trunc(ndo);
+                       return 0;
+               }
+               p += 3;
+               caplen -= 3;
        }
-       
+
        /* See which parts of addresses we have. */
        dst_addr_len = ieee802_15_4_addr_len((fc >> 10) & 0x3);
        src_addr_len = ieee802_15_4_addr_len((fc >> 14) & 0x3);
@@ -1874,9 +1890,9 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        src_pan = 0;
        dst_pan = 0;
        pan_id_comp = CHECK_BIT(fc, 6);
-       
+
        /* The PAN ID Compression rules are complicated. */
-       
+
        /* First check old versions, where the rules are simple. */
        if (frame_version < 2) {
                if (pan_id_comp) {
@@ -1958,14 +1974,14 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
 #endif /* BROKEN_6TISCH_PAN_ID_COMPRESSION */
                }
        }
-       
+
        /* Print dst PAN and address. */
        if (dst_pan) {
                if (caplen < 2) {
                        ND_PRINT("[ERROR: Truncated before dst_pan]");
                        return 0;
                }
-               ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+               ND_PRINT("%04x:", GET_LE_U_2(p));
                p += 2;
                caplen -= 2;
        } else {
@@ -1978,16 +1994,16 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        ieee802_15_4_print_addr(ndo, p, dst_addr_len);
        p += dst_addr_len;
        caplen -= dst_addr_len;
-       
+
        ND_PRINT(" < ");
-       
+
        /* Print src PAN and address. */
        if (src_pan) {
                if (caplen < 2) {
                        ND_PRINT("[ERROR: Truncated before dst_pan]");
                        return 0;
                }
-               ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+               ND_PRINT("%04x:", GET_LE_U_2(p));
                p += 2;
                caplen -= 2;
        } else {
@@ -2002,17 +2018,25 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        p += src_addr_len;
        caplen -= src_addr_len;
        if (CHECK_BIT(fc, 3)) {
+               /*
+                * XXX - if frame_version is 0, this is the 2003
+                * spec, and you don't have the auxiliary security
+                * header, you have a frame counter and key index
+                * for the AES-CTR and AES-CCM security suites but
+                * not for the AES-CBC-MAC security suite.
+                */
                len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
                                                        &security_level);
                if (len < 0) {
                        return 0;
                }
+               ND_TCHECK_LEN(p, len);
                p += len;
                caplen -= len;
        } else {
                security_level = 0;
        }
-       
+
        switch (security_level) {
        case 0: /*FALLTHOUGH */
        case 4:
@@ -2031,17 +2055,17 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                miclen = 16;
                break;
        }
-       
+
        /* Remove MIC */
-       if (miclen > 0) {
-               if (caplen < (u_int) miclen) {
+       if (miclen != 0) {
+               if (caplen < miclen) {
                        ND_PRINT("[ERROR: Truncated before MIC]");
                        return 0;
                }
                caplen -= miclen;
                mic_start = p + caplen;
        }
-       
+
        /* Parse Information elements if present */
        if (CHECK_BIT(fc, 9)) {
                /* Yes we have those. */
@@ -2053,7 +2077,7 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                p += len;
                caplen -= len;
        }
-       
+
        if (payload_ie_present) {
                if (security_level >= 4) {
                        ND_PRINT("Payload IEs present, but encrypted, cannot print ");
@@ -2066,17 +2090,17 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                        caplen -= len;
                }
        }
-       
+
        /* Print MIC */
        if (ndo->ndo_vflag > 2 && miclen != 0) {
                ND_PRINT("\n\tMIC ");
-               
-               for(len = 0; len < miclen; len++) {
-                       ND_PRINT("%02x", EXTRACT_U_1(mic_start + len));
+
+               for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+                       ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
                }
                ND_PRINT(" ");
        }
-       
+
        /* Print FCS */
        if (ndo->ndo_vflag > 2) {
                if (crc_check == fcs) {
@@ -2086,7 +2110,7 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                                 fcs, crc_check);
                }
        }
-       
+
        /* Payload print */
        switch (frame_type) {
        case 0x00: /* Beacon */
@@ -2096,26 +2120,26 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                                break;
                        } else {
                                uint16_t ss;
-                               
-                               ss = EXTRACT_LE_U_2(p);
+
+                               ss = GET_LE_U_2(p);
                                ieee802_15_4_print_superframe_specification(ndo, ss);
                                p += 2;
                                caplen -= 2;
-                               
+
                                /* GTS */
                                if (caplen < 1) {
                                        ND_PRINT("[ERROR: Truncated before GTS info]");
                                        break;
                                }
-                               
+
                                len = ieee802_15_4_print_gts_info(ndo, p, caplen);
                                if (len < 0) {
                                        break;
                                }
-                               
+
                                p += len;
                                caplen -= len;
-                               
+
                                /* Pending Addresses */
                                if (caplen < 1) {
                                        ND_PRINT("[ERROR: Truncated before pending addresses]");
@@ -2125,13 +2149,14 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                                if (len < 0) {
                                        break;
                                }
+                               ND_TCHECK_LEN(p, len);
                                p += len;
                                caplen -= len;
                        }
                }
                if (!ndo->ndo_suppress_default_print)
                        ND_DEFAULTPRINT(p, caplen);
-               
+
                break;
        case 0x01: /* Data */
        case 0x02: /* Acknowledgement */
@@ -2143,8 +2168,8 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                        ND_PRINT("[ERROR: Truncated before Command ID]");
                } else {
                        uint8_t command_id;
-                       
-                       command_id = EXTRACT_U_1(p);
+
+                       command_id = GET_U_1(p);
                        if (command_id >= 0x30) {
                                ND_PRINT("Command ID = Reserved 0x%02x ",
                                         command_id);
@@ -2181,18 +2206,19 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
 {
        int len, frame_version, pan_id_present;
        int src_addr_len, dst_addr_len;
-       int security_level, miclen = 0;
+       int security_level;
+       u_int miclen = 0;
        int ie_present, payload_ie_present, security_enabled;
        uint8_t seq;
        uint32_t fcs, crc_check;
        const u_char *mic_start = NULL;
-       
+
        pan_id_present = 0;
        ie_present = 0;
        payload_ie_present = 0;
        security_enabled = 0;
        crc_check = 0;
-       
+
        /* Assume 2 octet FCS, the FCS length depends on the PHY, and we do not
           know about that. */
        if (caplen < 3) {
@@ -2201,40 +2227,40 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
        } else {
                if (caplen > 4) {
                        /* Test for 4 octet FCS. */
-                       fcs = EXTRACT_LE_U_4(p + caplen - 4);
-                       crc_check = ieee802_15_4_crc32(p, caplen - 4);
+                       fcs = GET_LE_U_4(p + caplen - 4);
+                       crc_check = ieee802_15_4_crc32(ndo, p, caplen - 4);
                        if (crc_check == fcs) {
                                /* Remove FCS */
                                caplen -= 4;
                        } else {
-                               fcs = EXTRACT_LE_U_2(p + caplen - 2);
-                               crc_check = ieee802_15_4_crc16(p, caplen - 2);
+                               fcs = GET_LE_U_2(p + caplen - 2);
+                               crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
                                if (crc_check == fcs) {
                                        /* Remove FCS */
                                        caplen -= 2;
                                }
                        }
                } else {
-                       fcs = EXTRACT_LE_U_2(p + caplen - 2);
-                       crc_check = ieee802_15_4_crc16(p, caplen - 2);
+                       fcs = GET_LE_U_2(p + caplen - 2);
+                       crc_check = ieee802_15_4_crc16(ndo, p, caplen - 2);
                        if (crc_check == fcs) {
                                /* Remove FCS */
                                caplen -= 2;
                        }
                }
        }
-       
+
        if (CHECK_BIT(fc, 3)) {
                /* Long Frame Control */
-               
+
                /* Frame version. */
                frame_version = FC_FRAME_VERSION(fc);
                ND_PRINT("v%d ", frame_version);
-               
+
                pan_id_present = CHECK_BIT(fc, 8);
                ie_present = CHECK_BIT(fc, 15);
                security_enabled = CHECK_BIT(fc, 9);
-               
+
                if (ndo->ndo_vflag > 2) {
                        if (security_enabled) { ND_PRINT("Security Enabled, "); }
                        if (CHECK_BIT(fc, 11)) { ND_PRINT("Frame Pending, "); }
@@ -2245,28 +2271,36 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                        }
                        if (ie_present) { ND_PRINT("IE present, "); }
                }
-               
-               /* Check for the sequence number supression. */
+
+               /* Check for the sequence number suppression. */
                if (CHECK_BIT(fc, 10)) {
                        /* Sequence number is suppressed, but long version. */
+                       if (caplen < 2) {
+                               nd_print_trunc(ndo);
+                               return 0;
+                       }
                        p += 2;
                        caplen -= 2;
                } else {
-                       seq = EXTRACT_U_1(p + 2);
-                       p += 3;
-                       caplen -= 3;
+                       seq = GET_U_1(p + 2);
                        if (ndo->ndo_vflag)
                                ND_PRINT("seq %02x ", seq);
+                       if (caplen < 3) {
+                               nd_print_trunc(ndo);
+                               return 0;
+                       }
+                       p += 3;
+                       caplen -= 3;
                }
        } else {
                /* Short format of header, but with seq no */
-               seq = EXTRACT_U_1(p + 1);
+               seq = GET_U_1(p + 1);
                p += 2;
                caplen -= 2;
                if (ndo->ndo_vflag)
                        ND_PRINT("seq %02x ", seq);
        }
-       
+
        /* See which parts of addresses we have. */
        dst_addr_len = ieee802_15_4_addr_len((fc >> 4) & 0x3);
        src_addr_len = ieee802_15_4_addr_len((fc >> 6) & 0x3);
@@ -2278,14 +2312,14 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                ND_PRINT("[ERROR: Invalid dst address mode]");
                return 0;
        }
-       
+
        /* Print dst PAN and address. */
        if (pan_id_present) {
                if (caplen < 2) {
                        ND_PRINT("[ERROR: Truncated before dst_pan]");
                        return 0;
                }
-               ND_PRINT("%04x:", EXTRACT_LE_U_2(p));
+               ND_PRINT("%04x:", GET_LE_U_2(p));
                p += 2;
                caplen -= 2;
        } else {
@@ -2298,9 +2332,9 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
        ieee802_15_4_print_addr(ndo, p, dst_addr_len);
        p += dst_addr_len;
        caplen -= dst_addr_len;
-       
+
        ND_PRINT(" < ");
-       
+
        /* Print src PAN and address. */
        ND_PRINT(" -:");
        if (caplen < (u_int) src_addr_len) {
@@ -2311,19 +2345,20 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
        ND_PRINT(" ");
        p += src_addr_len;
        caplen -= src_addr_len;
-       
+
        if (security_enabled) {
                len = ieee802_15_4_print_aux_sec_header(ndo, p, caplen,
                                                        &security_level);
                if (len < 0) {
                        return 0;
                }
+               ND_TCHECK_LEN(p, len);
                p += len;
                caplen -= len;
        } else {
                security_level = 0;
        }
-       
+
        switch (security_level) {
        case 0: /*FALLTHOUGH */
        case 4:
@@ -2342,17 +2377,17 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                miclen = 16;
                break;
        }
-       
+
        /* Remove MIC */
-       if (miclen > 0) {
-               if (caplen < (u_int) miclen) {
+       if (miclen != 0) {
+               if (caplen < miclen) {
                        ND_PRINT("[ERROR: Truncated before MIC]");
                        return 0;
                }
                caplen -= miclen;
                mic_start = p + caplen;
        }
-       
+
        /* Parse Information elements if present */
        if (ie_present) {
                /* Yes we have those. */
@@ -2364,12 +2399,13 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                p += len;
                caplen -= len;
        }
-       
+
        if (payload_ie_present) {
                if (security_level >= 4) {
                        ND_PRINT("Payload IEs present, but encrypted, cannot print ");
                } else {
-                       len = ieee802_15_4_print_payload_ie_list(ndo, p, caplen);
+                       len = ieee802_15_4_print_payload_ie_list(ndo, p,
+                                                                caplen);
                        if (len < 0) {
                                return 0;
                        }
@@ -2377,18 +2413,18 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                        caplen -= len;
                }
        }
-       
+
        /* Print MIC */
        if (ndo->ndo_vflag > 2 && miclen != 0) {
                ND_PRINT("\n\tMIC ");
-               
-               for(len = 0; len < miclen; len++) {
-                       ND_PRINT("%02x", EXTRACT_U_1(mic_start + len));
+
+               for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+                       ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
                }
                ND_PRINT(" ");
        }
-       
-       
+
+
        /* Print FCS */
        if (ndo->ndo_vflag > 2) {
                if (crc_check == fcs) {
@@ -2398,10 +2434,10 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                                 fcs, crc_check);
                }
        }
-       
+
        if (!ndo->ndo_suppress_default_print)
                ND_DEFAULTPRINT(p, caplen);
-       
+
        return 1;
 }
 
@@ -2424,7 +2460,7 @@ ieee802_15_4_frag_frame(netdissect_options *ndo _U_,
 }
 
 /*
- * Interal call to dissector taking packet + len instead of pcap_pkthdr.
+ * Internal call to dissector taking packet + len instead of pcap_pkthdr.
  *
  * Returns FALSE in case of error.
  */
@@ -2434,23 +2470,23 @@ ieee802_15_4_print(netdissect_options *ndo,
 {
        int frame_type;
        uint16_t fc;
-       
-       ndo->ndo_protocol ="802.15.4";
+
+       ndo->ndo_protocol = "802.15.4";
 
        if (caplen < 2) {
                nd_print_trunc(ndo);
                return caplen;
        }
-       
-       fc = EXTRACT_LE_U_2(p);
-       
+
+       fc = GET_LE_U_2(p);
+
        /* First we need to check the frame type to know how to parse the rest
           of the FC. Frame type is the first 3 bit of the frame control field.
        */
-       
+
        frame_type = FC_FRAME_TYPE(fc);
        ND_PRINT("IEEE 802.15.4 %s packet ", ftypes[frame_type]);
-       
+
        switch (frame_type) {
        case 0x00: /* Beacon */
        case 0x01: /* Data */
@@ -2478,18 +2514,43 @@ ieee802_15_4_print(netdissect_options *ndo,
  * Main function to print packets.
  */
 
-u_int
+void
 ieee802_15_4_if_print(netdissect_options *ndo,
                       const struct pcap_pkthdr *h, const u_char *p)
 {
        u_int caplen = h->caplen;
-       ndo->ndo_protocol ="802.15.4_if";
-       return ieee802_15_4_print(ndo, p, caplen);
+       ndo->ndo_protocol = "802.15.4";
+       ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p, caplen);
 }
 
-/*
- * Local Variables:
- * c-style: whitesmith
- * c-basic-offset: 8
- * End:
- */
+/* For DLT_IEEE802_15_4_TAP */
+/* https://github.com/jkcko/ieee802.15.4-tap */
+void
+ieee802_15_4_tap_if_print(netdissect_options *ndo,
+                          const struct pcap_pkthdr *h, const u_char *p)
+{
+       uint8_t version;
+       uint16_t length;
+
+       ndo->ndo_protocol = "802.15.4_tap";
+       if (h->caplen < 4) {
+               nd_print_trunc(ndo);
+               ndo->ndo_ll_hdr_len += h->caplen;
+               return;
+       }
+
+       version = GET_U_1(p);
+       length = GET_LE_U_2(p + 2);
+       if (version != 0 || length < 4) {
+               nd_print_invalid(ndo);
+               return;
+       }
+
+       if (h->caplen < length) {
+               nd_print_trunc(ndo);
+               ndo->ndo_ll_hdr_len += h->caplen;
+               return;
+       }
+
+       ndo->ndo_ll_hdr_len += ieee802_15_4_print(ndo, p+length, h->caplen-length) + length;
+}