]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ether.c
Fail if nd_push_buffer() or nd_push_snaplen() fails.
[tcpdump] / print-ether.c
index 7a1b42e0b0c65e9e8fbe03df9bd23a9f0a80b2da..cd623f9025687a95bb7e166bdf98e516cb0ea30d 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
@@ -85,7 +86,7 @@ const struct tok ethertype_values[] = {
     { ETHERTYPE_PPPOED,         "PPPoE D" },
     { ETHERTYPE_PPPOES,         "PPPoE S" },
     { ETHERTYPE_EAPOL,          "EAPOL" },
-    { ETHERTYPE_RRCP,           "RRCP" },
+    { ETHERTYPE_REALTEK,        "Realtek protocols" },
     { ETHERTYPE_MS_NLB_HB,      "MS NLB heartbeat" },
     { ETHERTYPE_JUMBO,          "Jumbo" },
     { ETHERTYPE_NSH,            "NSH" },
@@ -149,14 +150,15 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length,
        int llc_hdrlen;
        struct lladdr_info src, dst;
 
+       if (length < caplen) {
+               ND_PRINT("[length %u < caplen %u]", length, caplen);
+               nd_print_invalid(ndo);
+               return length;
+       }
        if (caplen < ETHER_HDRLEN + switch_tag_len) {
                nd_print_trunc(ndo);
                return caplen;
        }
-       if (length < ETHER_HDRLEN + switch_tag_len) {
-               nd_print_trunc(ndo);
-               return length;
-       }
 
        if (print_encap_header != NULL)
                (*print_encap_header)(ndo, encap_header_arg);
@@ -220,7 +222,7 @@ recurse:
                }
 
                int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen,
-                   &src, &dst);
+                                      &src, &dst);
 
                if (ret == 0) {
                        /* Payload is encrypted; print it as raw data. */
@@ -236,6 +238,7 @@ recurse:
                         */
                        length_type = GET_BE_U_2(p);
 
+                       ND_LCHECK_U(caplen, 2);
                        length -= 2;
                        caplen -= 2;
                        p += 2;
@@ -303,7 +306,10 @@ recurse:
                 * Cut off the snapshot length to the end of the
                 * payload.
                 */
-               nd_push_snapend(ndo, p + length);
+               if (!nd_push_snaplen(ndo, p, length)) {
+                       (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
+                               "%s: can't push snaplen on buffer stack", __func__);
+               }
 
                if (ndo->ndo_eflag) {
                        ND_PRINT("802.3");
@@ -401,6 +407,7 @@ recurse:
                                ND_DEFAULTPRINT(p, caplen);
                }
        }
+invalid:
        return hdrlen;
 }
 
@@ -474,11 +481,7 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
         * Fail if we don't have enough data for the Hilscher pseudo-header.
         */
        ndo->ndo_protocol = "netanalyzer";
-       if (h->caplen < 4) {
-               ndo->ndo_ll_hdr_len += h->caplen;
-               nd_print_trunc(ndo);
-               return;
-       }
+       ND_TCHECK_LEN(p, 4);
 
        /* Skip the pseudo-header. */
        ndo->ndo_ll_hdr_len += 4;
@@ -506,11 +509,7 @@ netanalyzer_transparent_if_print(netdissect_options *ndo,
         * preamble, and SOF.
         */
        ndo->ndo_protocol = "netanalyzer_transparent";
-       if (h->caplen < 12) {
-               ndo->ndo_ll_hdr_len += h->caplen;
-               nd_print_trunc(ndo);
-               return;
-       }
+       ND_TCHECK_LEN(p, 12);
 
        /* Skip the pseudo-header, preamble, and SOF. */
        ndo->ndo_ll_hdr_len += 12;
@@ -571,6 +570,9 @@ ethertype_print(netdissect_options *ndo,
                        nd_print_trunc(ndo);
                        return (1);
                }
+               /* At least one byte is required */
+               /* FIXME: Reference for this byte? */
+               ND_TCHECK_LEN(p, 1);
                isoclns_print(ndo, p + 1, length - 1);
                return(1);
 
@@ -585,8 +587,8 @@ ethertype_print(netdissect_options *ndo,
                eapol_print(ndo, p);
                return (1);
 
-       case ETHERTYPE_RRCP:
-               rrcp_print(ndo, p, length, src, dst);
+       case ETHERTYPE_REALTEK:
+               rtl_print(ndo, p, length, src, dst);
                return (1);
 
        case ETHERTYPE_PPP: