]> 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 db09ef367e44fc0bbc61a9df7cc479f04152ec9a..1895be7ca19b9a8a420ffb0fd3c4723088180d2a 100644 (file)
@@ -28,6 +28,7 @@
 
 #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,7 +420,7 @@ 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(netdissect_options *ndo, const u_char *p,
@@ -471,7 +472,7 @@ 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(netdissect_options *ndo, const u_char *p,
@@ -548,7 +549,6 @@ ieee802_15_4_print_addr(netdissect_options *ndo, const u_char *p,
                ND_PRINT("%s", GET_LE64ADDR_STRING(p));
                break;
        }
-       return;
 }
 
 /*
@@ -569,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"); }
 }
 
 /*
@@ -720,7 +720,7 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                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 {
@@ -788,7 +788,7 @@ 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",
@@ -891,7 +891,7 @@ ieee802_15_4_print_header_ie(netdissect_options *ndo,
                        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 */
@@ -959,7 +959,7 @@ 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;
                }
@@ -989,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;
 }
 
@@ -1088,7 +1088,7 @@ ieee802_15_4_print_mlme_ie(netdissect_options *ndo,
                }
 
                break;
-       case 0x1a: /* TSCH Syncronization IE. */
+       case 0x1a: /* TSCH Synchronization IE. */
                if (sub_ie_len < 6) {
                        ND_PRINT("[ERROR: Length != 6]");
                }
@@ -1213,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 */
@@ -1282,7 +1282,7 @@ ieee802_15_4_print_mlme_ie_list(netdissect_options *ndo,
                                 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;
                }
@@ -1300,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;
 }
 
 /*
@@ -1442,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;
                }
@@ -1611,9 +1610,9 @@ ieee802_15_4_print_command_data(netdissect_options *ndo,
        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;
@@ -1634,9 +1633,9 @@ 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 = ");
@@ -1787,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.
  */
@@ -1799,7 +1798,8 @@ 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;
@@ -1848,24 +1848,32 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                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 = GET_U_1(p + 2);
-               p += 3;
-               caplen -= 3;
                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. */
@@ -2022,6 +2030,7 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                if (len < 0) {
                        return 0;
                }
+               ND_TCHECK_LEN(p, len);
                p += len;
                caplen -= len;
        } else {
@@ -2048,8 +2057,8 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        }
 
        /* Remove MIC */
-       if (miclen > 0) {
-               if (caplen < (u_int) miclen) {
+       if (miclen != 0) {
+               if (caplen < miclen) {
                        ND_PRINT("[ERROR: Truncated before MIC]");
                        return 0;
                }
@@ -2086,8 +2095,8 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
        if (ndo->ndo_vflag > 2 && miclen != 0) {
                ND_PRINT("\n\tMIC ");
 
-               for(len = 0; len < miclen; len++) {
-                       ND_PRINT("%02x", GET_U_1(mic_start + len));
+               for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+                       ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
                }
                ND_PRINT(" ");
        }
@@ -2140,6 +2149,7 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                                if (len < 0) {
                                        break;
                                }
+                               ND_TCHECK_LEN(p, len);
                                p += len;
                                caplen -= len;
                        }
@@ -2196,7 +2206,8 @@ 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;
@@ -2261,17 +2272,25 @@ 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 = GET_U_1(p + 2);
-                       p += 3;
-                       caplen -= 3;
                        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 */
@@ -2333,6 +2352,7 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                if (len < 0) {
                        return 0;
                }
+               ND_TCHECK_LEN(p, len);
                p += len;
                caplen -= len;
        } else {
@@ -2359,8 +2379,8 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
        }
 
        /* Remove MIC */
-       if (miclen > 0) {
-               if (caplen < (u_int) miclen) {
+       if (miclen != 0) {
+               if (caplen < miclen) {
                        ND_PRINT("[ERROR: Truncated before MIC]");
                        return 0;
                }
@@ -2398,8 +2418,8 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
        if (ndo->ndo_vflag > 2 && miclen != 0) {
                ND_PRINT("\n\tMIC ");
 
-               for(len = 0; len < miclen; len++) {
-                       ND_PRINT("%02x", GET_U_1(mic_start + len));
+               for (u_int micoffset = 0; micoffset < miclen; micoffset++) {
+                       ND_PRINT("%02x", GET_U_1(mic_start + micoffset));
                }
                ND_PRINT(" ");
        }
@@ -2440,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.
  */