]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ether.c
CI: Add warning exemptions for Sun C (suncc-5.14) on Solaris 10
[tcpdump] / print-ether.c
index f8399b402c42ab4068ffd68d7d8fb339196a458d..324d089fc3138836b663bbe185cad7a7752c488e 100644 (file)
 
 /* \summary: Ethernet printer */
 
-#ifdef HAVE_CONFIG_H
 #include <config.h>
-#endif
 
 #include "netdissect-stdinc.h"
 
+#define ND_LONGJMP_FROM_TCHECK
 #include "netdissect.h"
 #include "extract.h"
 #include "addrtoname.h"
@@ -36,8 +35,8 @@
  * Structure of an Ethernet header.
  */
 struct ether_header {
-       nd_mac_addr     ether_dhost;
-       nd_mac_addr     ether_shost;
+       nd_mac48        ether_dhost;
+       nd_mac48        ether_shost;
        nd_uint16_t     ether_length_type;
 };
 
@@ -85,7 +84,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" },
@@ -111,7 +110,7 @@ ether_addresses_print(netdissect_options *ndo, const u_char *src,
                      const u_char *dst)
 {
        ND_PRINT("%s > %s, ",
-                GET_ETHERADDR_STRING(src), GET_ETHERADDR_STRING(dst));
+                GET_MAC48_STRING(src), GET_MAC48_STRING(dst));
 }
 
 static void
@@ -149,13 +148,14 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length,
        int llc_hdrlen;
        struct lladdr_info src, dst;
 
-       if (caplen < ETHER_HDRLEN + switch_tag_len) {
-               nd_print_trunc(ndo);
-               return (caplen);
+       if (length < caplen) {
+               ND_PRINT("[length %u < caplen %u]", length, caplen);
+               nd_print_invalid(ndo);
+               return length;
        }
-       if (length < ETHER_HDRLEN + switch_tag_len) {
+       if (caplen < ETHER_HDRLEN + switch_tag_len) {
                nd_print_trunc(ndo);
-               return (length);
+               return caplen;
        }
 
        if (print_encap_header != NULL)
@@ -169,14 +169,14 @@ ether_common_print(netdissect_options *ndo, const u_char *p, u_int length,
         */
        ehp = (const struct ether_header *)p;
        src.addr = ehp->ether_shost;
-       src.addr_string = etheraddr_string;
+       src.addr_string = mac48_string;
        dst.addr = ehp->ether_dhost;
-       dst.addr_string = etheraddr_string;
+       dst.addr_string = mac48_string;
 
-       length -= 2*MAC_ADDR_LEN;
-       caplen -= 2*MAC_ADDR_LEN;
-       p += 2*MAC_ADDR_LEN;
-       hdrlen = 2*MAC_ADDR_LEN;
+       length -= 2*MAC48_LEN;
+       caplen -= 2*MAC48_LEN;
+       p += 2*MAC48_LEN;
+       hdrlen = 2*MAC48_LEN;
 
        if (ndo->ndo_eflag)
                ether_addresses_print(ndo, src.addr, dst.addr);
@@ -219,22 +219,24 @@ recurse:
                        printed_length = 1;
                }
 
-               int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen);
+               int ret = macsec_print(ndo, &p, &length, &caplen, &hdrlen,
+                                      &src, &dst);
 
                if (ret == 0) {
                        /* Payload is encrypted; print it as raw data. */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(p, caplen);
-                       return (hdrlen);
+                       return hdrlen;
                } else if (ret > 0) {
                        /* Problem printing the header; just quit. */
-                       return (ret);
+                       return ret;
                } else {
                        /*
                         * Keep processing type/length fields.
                         */
                        length_type = GET_BE_U_2(p);
 
+                       ND_ICHECK_U(caplen, <, 2);
                        length -= 2;
                        caplen -= 2;
                        p += 2;
@@ -257,12 +259,12 @@ recurse:
                if (caplen < 4) {
                        ndo->ndo_protocol = "vlan";
                        nd_print_trunc(ndo);
-                       return (hdrlen + caplen);
+                       return hdrlen + caplen;
                }
                if (length < 4) {
                        ndo->ndo_protocol = "vlan";
                        nd_print_trunc(ndo);
-                       return (hdrlen + length);
+                       return hdrlen + length;
                }
                if (ndo->ndo_eflag) {
                        uint16_t tag = GET_BE_U_2(p);
@@ -302,7 +304,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");
@@ -345,11 +350,11 @@ recurse:
        } else if (length_type == ETHERTYPE_ARISTA) {
                if (caplen < 2) {
                        ND_PRINT("[|arista]");
-                       return (hdrlen + caplen);
+                       return hdrlen + caplen;
                }
                if (length < 2) {
                        ND_PRINT("[|arista]");
-                       return (hdrlen + length);
+                       return hdrlen + length;
                }
                ether_type_print(ndo, length_type);
                ND_PRINT(", length %u: ", orig_length);
@@ -400,11 +405,12 @@ recurse:
                                ND_DEFAULTPRINT(p, caplen);
                }
        }
-       return (hdrlen);
+invalid:
+       return hdrlen;
 }
 
 /*
- * Print an Ethernet frame while specyfing a non-standard Ethernet header
+ * Print an Ethernet frame while specifying a non-standard Ethernet header
  * length.
  * This might be encapsulated within another frame; we might be passed
  * a pointer to a function that can print header information for that
@@ -418,8 +424,8 @@ ether_switch_tag_print(netdissect_options *ndo, const u_char *p, u_int length,
     void (*print_switch_tag)(netdissect_options *, const u_char *),
     u_int switch_tag_len)
 {
-       return (ether_common_print(ndo, p, length, caplen, print_switch_tag,
-                                  switch_tag_len, NULL, NULL));
+       return ether_common_print(ndo, p, length, caplen, print_switch_tag,
+                                 switch_tag_len, NULL, NULL);
 }
 
 /*
@@ -437,8 +443,8 @@ ether_print(netdissect_options *ndo,
            const u_char *encap_header_arg)
 {
        ndo->ndo_protocol = "ether";
-       return (ether_common_print(ndo, p, length, caplen, NULL, 0,
-                                  print_encap_header, encap_header_arg));
+       return ether_common_print(ndo, p, length, caplen, NULL, 0,
+                                 print_encap_header, encap_header_arg);
 }
 
 /*
@@ -447,12 +453,13 @@ ether_print(netdissect_options *ndo,
  * of the packet off the wire, and 'h->caplen' is the number
  * of bytes actually captured.
  */
-u_int
+void
 ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
               const u_char *p)
 {
-       ndo->ndo_protocol = "ether_if";
-       return (ether_print(ndo, p, h->len, h->caplen, NULL, NULL));
+       ndo->ndo_protocol = "ether";
+       ndo->ndo_ll_hdr_len +=
+               ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
 }
 
 /*
@@ -464,21 +471,20 @@ ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
  * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header
  * before the Ethernet header.
  */
-u_int
+void
 netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
                     const u_char *p)
 {
        /*
         * Fail if we don't have enough data for the Hilscher pseudo-header.
         */
-       ndo->ndo_protocol = "netanalyzer_if";
-       if (h->caplen < 4) {
-               nd_print_trunc(ndo);
-               return (h->caplen);
-       }
+       ndo->ndo_protocol = "netanalyzer";
+       ND_TCHECK_4(p);
 
        /* Skip the pseudo-header. */
-       return (4 + ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL));
+       ndo->ndo_ll_hdr_len += 4;
+       ndo->ndo_ll_hdr_len +=
+               ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL);
 }
 
 /*
@@ -491,7 +497,7 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
  * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF
  * before the Ethernet header.
  */
-u_int
+void
 netanalyzer_transparent_if_print(netdissect_options *ndo,
                                 const struct pcap_pkthdr *h,
                                 const u_char *p)
@@ -500,14 +506,13 @@ netanalyzer_transparent_if_print(netdissect_options *ndo,
         * Fail if we don't have enough data for the Hilscher pseudo-header,
         * preamble, and SOF.
         */
-       ndo->ndo_protocol = "netanalyzer_transparent_if";
-       if (h->caplen < 12) {
-               nd_print_trunc(ndo);
-               return (h->caplen);
-       }
+       ndo->ndo_protocol = "netanalyzer_transparent";
+       ND_TCHECK_LEN(p, 12);
 
        /* Skip the pseudo-header, preamble, and SOF. */
-       return (12 + ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL));
+       ndo->ndo_ll_hdr_len += 12;
+       ndo->ndo_ll_hdr_len +=
+               ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL);
 }
 
 /*
@@ -563,6 +568,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_1(p);
                isoclns_print(ndo, p + 1, length - 1);
                return(1);
 
@@ -574,11 +582,11 @@ ethertype_print(netdissect_options *ndo,
                return (1);
 
        case ETHERTYPE_EAPOL:
-               eap_print(ndo, p, length);
+               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: