]> 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 d3371641c21974377db3652d50c3ced371ad8ea3..1895be7ca19b9a8a420ffb0fd3c4723088180d2a 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "addrtoname.h"
 
@@ -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,
@@ -890,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 */
@@ -958,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;
                }
@@ -988,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;
 }
 
@@ -1281,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;
                }
@@ -1440,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;
                }
@@ -1797,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;
@@ -1856,14 +1858,22 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                }
                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. */
@@ -2020,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 {
@@ -2046,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;
                }
@@ -2084,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(" ");
        }
@@ -2138,6 +2149,7 @@ ieee802_15_4_std_frames(netdissect_options *ndo,
                                if (len < 0) {
                                        break;
                                }
+                               ND_TCHECK_LEN(p, len);
                                p += len;
                                caplen -= len;
                        }
@@ -2194,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;
@@ -2262,14 +2275,22 @@ ieee802_15_4_mp_frame(netdissect_options *ndo,
                /* 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 */
@@ -2331,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 {
@@ -2357,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;
                }
@@ -2396,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(" ");
        }