]> The Tcpdump Group git mirrors - tcpdump/commitdiff
EIGRP: Modernize packet parsing style.
authorDenis Ovsienko <[email protected]>
Sun, 10 Jan 2021 00:53:43 +0000 (00:53 +0000)
committerDenis Ovsienko <[email protected]>
Sun, 10 Jan 2021 01:07:16 +0000 (01:07 +0000)
Enable ND_LONGJMP_FROM_TCHECK. Report invalid packets as invalid. Remove
two redundant ND_TCHECK_*() instances. When giving up on a packet for
whatever reason, test that the rest of it is within the buffer. Do the
header length check before accessing any header data and refine the TLV
length checks. Update a test.

print-eigrp.c
tests/eigrp-tlv-oobr.out

index 1bcdf1793e36bf0341152e18c5c1e3ea38d2b754..7e374aa5c9f7c95d97c97c8b77fa9f56e595de0e 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <string.h>
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
@@ -232,16 +233,22 @@ eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
 
     ndo->ndo_protocol = "eigrp";
     tptr=pptr;
+    tlen = len;
     eigrp_com_header = (const struct eigrp_common_header *)pptr;
-    ND_TCHECK_SIZE(eigrp_com_header);
 
     /*
      * Sanity checking of the header.
      */
+    if (len < sizeof(struct eigrp_common_header)) {
+        ND_PRINT("EIGRP %s, length: %u (too short, < %zu)",
+               tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)),
+               len, sizeof(struct eigrp_common_header));
+        goto check_remainder;
+    }
     if (GET_U_1(eigrp_com_header->version) != EIGRP_VERSION) {
         ND_PRINT("EIGRP version %u packet not supported",
                  GET_U_1(eigrp_com_header->version));
-        return;
+        goto check_remainder;
     }
 
     /* in non-verbose mode just lets print the basic Message Type*/
@@ -249,18 +256,11 @@ eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
         ND_PRINT("EIGRP %s, length: %u",
                tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)),
                len);
-        return;
+        goto check_remainder;
     }
 
     /* ok they seem to want to know everything - lets fully decode it */
-
-    if (len < sizeof(struct eigrp_common_header)) {
-        ND_PRINT("EIGRP %s, length: %u (too short, < %zu)",
-               tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)),
-               len, sizeof(struct eigrp_common_header));
-        return;
-    }
-    tlen=len-sizeof(struct eigrp_common_header);
+    tlen -= sizeof(struct eigrp_common_header);
 
     ND_PRINT("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]"
              "\n\tseq: 0x%08x, ack: 0x%08x, VRID: %u, AS: %u, length: %u",
@@ -280,20 +280,14 @@ eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
     tptr+=sizeof(struct eigrp_common_header);
 
     while(tlen>0) {
-        /* did we capture enough for fully decoding the object header ? */
-        ND_TCHECK_LEN(tptr, sizeof(struct eigrp_tlv_header));
-
+        if (tlen < sizeof(struct eigrp_tlv_header)) {
+            ND_PRINT("\n\t  (only %u bytes of data)", tlen);
+            goto invalid;
+        }
         eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
         eigrp_tlv_len=GET_BE_U_2(eigrp_tlv_header->length);
         eigrp_tlv_type=GET_BE_U_2(eigrp_tlv_header->type);
 
-
-        if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
-            eigrp_tlv_len > tlen) {
-            print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t    ",tlen);
-            return;
-        }
-
         ND_PRINT("\n\t  %s TLV (0x%04x), length: %u",
                tok2str(eigrp_tlv_values,
                        "Unknown",
@@ -301,10 +295,9 @@ eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
                eigrp_tlv_type,
                eigrp_tlv_len);
 
-        if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
-                ND_PRINT(" (too short, < %zu)",
-                         sizeof(struct eigrp_tlv_header));
-                break;
+        if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
+            eigrp_tlv_len > tlen) {
+            goto invalid;
         }
         tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
         tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
@@ -527,6 +520,8 @@ eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
         tlen-=eigrp_tlv_len;
     }
     return;
-trunc:
-    nd_print_trunc(ndo);
+invalid:
+    nd_print_invalid(ndo);
+check_remainder:
+    ND_TCHECK_LEN(tptr, tlen);
 }
index b84a3be7d96215f34660dde2881448aae6e7d1b3..ad69e47696869d4e065b9efa102d6f7bc40df388 100644 (file)
          Software Version TLV (0x0004), length: 4 (too short, < 8)
          Software Version TLV (0x0004), length: 4 (too short, < 8)
          Software Version TLV (0x0004), length: 4 (too short, < 8)
-         Software Version TLV (0x0004), length: 4 (too short, < 8) [|eigrp]
+         Software Version TLV (0x0004), length: 4 (too short, < 8)
+         (only 1 bytes of data) (invalid)