]> The Tcpdump Group git mirrors - tcpdump/commitdiff
CVE-2016-7985,7986/Change the way protocols print link-layer addresses.
authorGuy Harris <[email protected]>
Fri, 3 Jul 2015 22:54:14 +0000 (15:54 -0700)
committerFrancois-Xavier Le Bail <[email protected]>
Wed, 18 Jan 2017 08:16:36 +0000 (09:16 +0100)
If a protocol that runs under a link-layer protocol would print the
link-layer addresses for the packet as source and destination addresses
for the packet, don't have it blithely assume those link-layer addresses
are present or are at a particular offset from the beginning of that
protocol's data; Ethertypes, for example, are used by a number of
protocols, not all of which have Ethernet headers and not all of which
have any MAC headers.

Instead, pass the printers for those protocols structures with a pointer
to the address data and a pointer to a routine that prints the address.

Fixes some heap overflows found with American Fuzzy Lop by Hanno Böck.

22 files changed:
netdissect.h
print-802_11.c
print-ap1394.c
print-calm-fast.c
print-ether.c
print-fddi.c
print-fr.c
print-geneve.c
print-geonet.c
print-ipfc.c
print-juniper.c
print-llc.c
print-medsa.c
print-rrcp.c
print-sll.c
print-symantec.c
print-token.c
tests/TESTLIST
tests/calm-fast-mac-lookup-heapoverflow.out [new file with mode: 0644]
tests/calm-fast-mac-lookup-heapoverflow.pcap [new file with mode: 0644]
tests/geonet-mac-lookup-heapoverflow.out [new file with mode: 0644]
tests/geonet-mac-lookup-heapoverflow.pcap [new file with mode: 0644]

index 902bf1b2334cdf63f3b8a354434f0ab7b372a461..a855e87a863da0f61fbc51e37f5ffbf408207f56 100644 (file)
@@ -449,6 +449,21 @@ extern u_int token_if_print IF_PRINTER_ARGS;
 extern u_int usb_linux_48_byte_print IF_PRINTER_ARGS;
 extern u_int usb_linux_64_byte_print IF_PRINTER_ARGS;
 
+/*
+ * Structure passed to some printers to allow them to print
+ * link-layer address information if ndo_eflag isn't set
+ * (because they are for protocols that don't have their
+ * own addresses, so that we'd want to report link-layer
+ * address information).
+ *
+ * This contains a pointer to an address and a pointer to a routine
+ * to which we pass that pointer in order to get a string.
+ */
+struct lladdr_info {
+       const char *(*addr_string)(netdissect_options *, const u_char *);
+       const u_char *addr;
+};
+
 /* The printer routines. */
 
 extern void aarp_print(netdissect_options *, const u_char *, u_int);
@@ -466,7 +481,7 @@ extern void bfd_print(netdissect_options *, const u_char *, u_int, u_int);
 extern void bgp_print(netdissect_options *, const u_char *, int);
 extern char *bgp_vpn_rd_print (netdissect_options *, const u_char *);
 extern void bootp_print(netdissect_options *, const u_char *, u_int);
-extern void calm_fast_print(netdissect_options *, const u_char *, const u_char *, u_int);
+extern void calm_fast_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *);
 extern void carp_print(netdissect_options *, const u_char *, u_int, int);
 extern void cdp_print(netdissect_options *, const u_char *, u_int, u_int);
 extern void cfm_print(netdissect_options *, const u_char *, u_int);
@@ -484,14 +499,14 @@ extern void egp_print(netdissect_options *, const u_char *, u_int);
 extern void eigrp_print(netdissect_options *, const u_char *, u_int);
 extern int esp_print(netdissect_options *, const u_char *, const int, const u_char *, int *, int *);
 extern u_int ether_print(netdissect_options *, const u_char *, u_int, u_int, void (*)(netdissect_options *, const u_char *), const u_char *);
-extern int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int);
+extern int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *);
 extern u_int fddi_print(netdissect_options *, const u_char *, u_int, u_int);
 extern void forces_print(netdissect_options *, const u_char *, u_int);
 extern u_int fr_print(netdissect_options *, register const u_char *, u_int);
 extern int frag6_print(netdissect_options *, const u_char *, const u_char *);
 extern void ftp_print(netdissect_options *, const u_char *, u_int);
 extern void geneve_print(netdissect_options *, const u_char *, u_int);
-extern void geonet_print(netdissect_options *, const u_char *, const u_char *, u_int);
+extern void geonet_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *);
 extern void gre_print(netdissect_options *, const u_char *, u_int);
 extern int hbhopt_print(netdissect_options *, const u_char *);
 extern void hex_and_ascii_print(netdissect_options *, const char *, const u_char *, u_int);
@@ -521,7 +536,7 @@ extern void lane_print(netdissect_options *, const u_char *, u_int, u_int);
 extern void ldp_print(netdissect_options *, const u_char *, u_int);
 extern void lisp_print(netdissect_options *, const u_char *, u_int);
 extern u_int llap_print(netdissect_options *, const u_char *, u_int);
-extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *);
+extern int llc_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *);
 extern void lldp_print(netdissect_options *, const u_char *, u_int);
 extern void lmp_print(netdissect_options *, const u_char *, u_int);
 extern void loopback_print(netdissect_options *, const u_char *, const u_int);
@@ -572,7 +587,7 @@ extern void resp_print(netdissect_options *, const u_char *, u_int);
 extern void rip_print(netdissect_options *, const u_char *, u_int);
 extern void ripng_print(netdissect_options *, const u_char *, unsigned int);
 extern void rpki_rtr_print(netdissect_options *, const u_char *, u_int);
-extern void rrcp_print(netdissect_options *, const u_char *, u_int);
+extern void rrcp_print(netdissect_options *, const u_char *, u_int, const struct lladdr_info *, const struct lladdr_info *);
 extern void rsvp_print(netdissect_options *, const u_char *, u_int);
 extern int rt6_print(netdissect_options *, const u_char *, const u_char *);
 extern void rtsp_print(netdissect_options *, const u_char *, u_int);
@@ -584,7 +599,7 @@ extern void slow_print(netdissect_options *, const u_char *, u_int);
 extern void smb_print_data(netdissect_options *, const unsigned char *, int);
 extern void smb_tcp_print(netdissect_options *, const u_char *, int);
 extern void smtp_print(netdissect_options *, const u_char *, u_int);
-extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, const u_char *, const u_char *, u_int);
+extern int snap_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *, u_int);
 extern void snmp_print(netdissect_options *, const u_char *, u_int);
 extern void stp_print(netdissect_options *, const u_char *, u_int);
 extern void sunrpcrequest_print(netdissect_options *, const u_char *, u_int, const u_char *);
index 7721524b0c7231496f24ac9756ccd6abb456453a..78a57b186564f8076db36a77ebeabf4dd6e87b84 100644 (file)
@@ -2039,7 +2039,7 @@ ieee802_11_print(netdissect_options *ndo,
 {
        uint16_t fc;
        u_int caplen, hdrlen, meshdrlen;
-       const uint8_t *src, *dst;
+       struct lladdr_info src, dst;
        int llc_hdrlen;
 
        caplen = orig_caplen;
@@ -2091,10 +2091,12 @@ ieee802_11_print(netdissect_options *ndo,
        caplen -= hdrlen;
        p += hdrlen;
 
+       src.addr_string = etheraddr_string;
+       dst.addr_string = etheraddr_string;
        switch (FC_TYPE(fc)) {
        case T_MGMT:
-               get_mgmt_src_dst_mac(p - hdrlen, &src, &dst);
-               if (!mgmt_body_print(ndo, fc, src, p, length)) {
+               get_mgmt_src_dst_mac(p - hdrlen, &src.addr, &dst.addr);
+               if (!mgmt_body_print(ndo, fc, src.addr, p, length)) {
                        ND_PRINT((ndo, "%s", tstr));
                        return hdrlen;
                }
@@ -2116,8 +2118,8 @@ ieee802_11_print(netdissect_options *ndo,
                                return hdrlen;
                        }
                } else {
-                       get_data_src_dst_mac(fc, p - hdrlen, &src, &dst);
-                       llc_hdrlen = llc_print(ndo, p, length, caplen, src, dst);
+                       get_data_src_dst_mac(fc, p - hdrlen, &src.addr, &dst.addr);
+                       llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
                        if (llc_hdrlen < 0) {
                                /*
                                 * Some kinds of LLC packet we cannot
index 1e6bbd98b5a87f543958daeee20b704a057bacc8..79401cba0ef71c45904911c762406ddb7c53f671 100644 (file)
@@ -49,6 +49,12 @@ struct firewire_header {
  */
 #define FIREWIRE_HDRLEN                18
 
+static const char *
+fwaddr_string(netdissect_options *ndo, const u_char *addr)
+{
+       return (linkaddr_string(ndo, addr, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN));
+}
+
 static inline void
 ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int length)
 {
@@ -58,8 +64,8 @@ ap1394_hdr_print(netdissect_options *ndo, register const u_char *bp, u_int lengt
        fp = (const struct firewire_header *)bp;
 
        ND_PRINT((ndo, "%s > %s",
-                    linkaddr_string(ndo, fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN),
-                    linkaddr_string(ndo, fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN)));
+                    fwaddr_string(ndo, fp->firewire_shost),
+                    fwaddr_string(ndo, fp->firewire_dhost)));
 
        firewire_type = EXTRACT_16BITS(&fp->firewire_type);
        if (!ndo->ndo_qflag) {
@@ -86,6 +92,7 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch
        u_int caplen = h->caplen;
        const struct firewire_header *fp;
        u_short ether_type;
+       struct lladdr_info src, dst;
 
        if (caplen < FIREWIRE_HDRLEN) {
                ND_PRINT((ndo, "[|ap1394]"));
@@ -101,7 +108,11 @@ ap1394_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_ch
        p += FIREWIRE_HDRLEN;
 
        ether_type = EXTRACT_16BITS(&fp->firewire_type);
-       if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
+       src.addr = fp->firewire_shost;
+       src.addr_string = fwaddr_string;
+       dst.addr = fp->firewire_dhost;
+       dst.addr_string = fwaddr_string;
+       if (ethertype_print(ndo, ether_type, p, length, caplen, &src, &dst) == 0) {
                /* ether_type not known, print raw packet */
                if (!ndo->ndo_eflag)
                        ap1394_hdr_print(ndo, (const u_char *)fp, length + FIREWIRE_HDRLEN);
index 4e4e51af2ab4c8292b45307398f269141f63a83e..c9be008cc29fc497ac41db6e5959a538d230c967 100644 (file)
  * to the calm header of the packet.
  */
 void
-calm_fast_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length)
+calm_fast_print(netdissect_options *ndo, const u_char *bp, u_int length, const struct lladdr_info *src)
 {
-       int srcNwref = bp[0];
-       int dstNwref = bp[1];
+       int srcNwref;
+       int dstNwref;
+
+       ND_TCHECK2(*bp, 2);
+       if (length < 2)
+               goto trunc;
+       srcNwref = bp[0];
+       dstNwref = bp[1];
        length -= 2;
        bp += 2;
 
-       ND_PRINT((ndo, "CALM FAST src:%s; ", etheraddr_string(ndo, eth+6)));
+       ND_PRINT((ndo, "CALM FAST"));
+       if (src != NULL)
+               ND_PRINT((ndo, " src:%s", (src->addr_string)(ndo, src->addr)));
+       ND_PRINT((ndo, "; "));
        ND_PRINT((ndo, "SrcNwref:%d; ", srcNwref));
        ND_PRINT((ndo, "DstNwref:%d; ", dstNwref));
 
        if (ndo->ndo_vflag)
                ND_DEFAULTPRINT(bp, length);
+       return;
+
+trunc:
+       ND_PRINT((ndo, "[|calm fast]"));
+       return;
 }
 
 
index 0f8c7dc56f3aa85e38faf3a679b1b4a777c0f8f3..59d15c24481a509f5c27fb9682fded67fca65a11 100644 (file)
@@ -137,6 +137,7 @@ ether_print(netdissect_options *ndo,
        u_short length_type;
        u_int hdrlen;
        int llc_hdrlen;
+       struct lladdr_info src, dst;
 
        if (caplen < ETHER_HDRLEN) {
                ND_PRINT((ndo, "[|ether]"));
@@ -160,6 +161,10 @@ ether_print(netdissect_options *ndo,
        p += ETHER_HDRLEN;
        hdrlen = ETHER_HDRLEN;
 
+       src.addr = ESRC(ep);
+       src.addr_string = etheraddr_string;
+       dst.addr = EDST(ep);
+       dst.addr_string = etheraddr_string;
        length_type = EXTRACT_16BITS(&ep->ether_length_type);
 
 recurse:
@@ -168,7 +173,7 @@ recurse:
         */
        if (length_type <= ETHERMTU) {
                /* Try to print the LLC-layer header & higher layers */
-               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep));
+               llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
                if (llc_hdrlen < 0) {
                        /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
@@ -217,7 +222,7 @@ recurse:
                 * there's an LLC header and payload.
                 */
                /* Try to print the LLC-layer header & higher layers */
-               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep));
+               llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
                if (llc_hdrlen < 0) {
                        /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
@@ -226,7 +231,7 @@ recurse:
                }
                hdrlen += llc_hdrlen;
        } else {
-               if (ethertype_print(ndo, length_type, p, length, caplen) == 0) {
+               if (ethertype_print(ndo, length_type, p, length, caplen, &src, &dst) == 0) {
                        /* type not known, print raw packet */
                        if (!ndo->ndo_eflag) {
                                if (print_encap_header != NULL)
@@ -317,7 +322,8 @@ netanalyzer_transparent_if_print(netdissect_options *ndo,
 int
 ethertype_print(netdissect_options *ndo,
                 u_short ether_type, const u_char *p,
-                u_int length, u_int caplen)
+                u_int length, u_int caplen,
+                const struct lladdr_info *src, const struct lladdr_info *dst)
 {
        switch (ether_type) {
 
@@ -369,7 +375,7 @@ ethertype_print(netdissect_options *ndo,
                return (1);
 
        case ETHERTYPE_RRCP:
-               rrcp_print(ndo, p - 14 , length + 14);
+               rrcp_print(ndo, p, length, src, dst);
                return (1);
 
        case ETHERTYPE_PPP:
@@ -415,11 +421,11 @@ ethertype_print(netdissect_options *ndo,
 
         case ETHERTYPE_GEONET_OLD:
         case ETHERTYPE_GEONET:
-                geonet_print(ndo, p-14, p, length);
+                geonet_print(ndo, p, length, src);
                 return (1);
 
         case ETHERTYPE_CALM_FAST:
-                calm_fast_print(ndo, p-14, p, length);
+                calm_fast_print(ndo, p, length, src);
                 return (1);
 
        case ETHERTYPE_AOE:
index 93f6ccd8be1430f3d3b2f39f1c972a6a27d6dcc4..27803783b7d8e70b1b09df75554d5237391391bf 100644 (file)
@@ -278,6 +278,7 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 {
        const struct fddi_header *fddip = (const struct fddi_header *)p;
        struct ether_header ehdr;
+       struct lladdr_info src, dst;
        int llc_hdrlen;
 
        if (caplen < FDDI_HDRLEN) {
@@ -293,6 +294,11 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
        if (ndo->ndo_eflag)
                fddi_hdr_print(ndo, fddip, length, ESRC(&ehdr), EDST(&ehdr));
 
+       src.addr = ESRC(&ehdr);
+       src.addr_string = etheraddr_string;
+       dst.addr = EDST(&ehdr);
+       dst.addr_string = etheraddr_string;
+
        /* Skip over FDDI MAC header */
        length -= FDDI_HDRLEN;
        p += FDDI_HDRLEN;
@@ -301,7 +307,7 @@ fddi_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
        /* Frame Control field determines interpretation of packet */
        if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
                /* Try to print the LLC-layer header & higher layers */
-               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr));
+               llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
                if (llc_hdrlen < 0) {
                        /*
                         * Some kinds of LLC packet we cannot
index 3ee46551360bc9b90fae20981957f0ccfdff1359..9c97bcb4a6746ef904f2d580066a84b2127faa19 100644 (file)
@@ -276,7 +276,8 @@ fr_print(netdissect_options *ndo,
                         if (ethertype_print(ndo, extracted_ethertype,
                                             p+addr_len+ETHERTYPE_LEN,
                                             length-addr_len-ETHERTYPE_LEN,
-                                            length-addr_len-ETHERTYPE_LEN) == 0)
+                                            length-addr_len-ETHERTYPE_LEN,
+                                            NULL, NULL) == 0)
                                 /* ether_type not known, probably it wasn't one */
                                 ND_PRINT((ndo, "UI %02x! ", p[addr_len]));
                         else
index d565103d48aa90374e7f2ee93dc031dc86c44556..f0319636690787bbbd9b6be562b2cda70678ec21 100644 (file)
@@ -223,7 +223,7 @@ geneve_print(netdissect_options *ndo, const u_char *bp, u_int len)
     else
         ND_PRINT((ndo, "\n\t"));
 
-    if (ethertype_print(ndo, prot, bp, len, len) == 0) {
+    if (ethertype_print(ndo, prot, bp, len, len, NULL, NULL) == 0) {
         if (prot == ETHERTYPE_TEB)
             ether_print(ndo, bp, len, len, NULL, NULL);
         else
index 61441a0bf3b484961ec62f1562441cd75f5e9d98..9da89bfe81dc8b4e443cfe8ff3422e2cee7c1dce 100644 (file)
@@ -86,6 +86,8 @@ print_long_pos_vector(netdissect_options *ndo,
 {
        uint32_t lat, lon;
 
+       if (!ND_TTEST2(*bp, GEONET_ADDR_LEN))
+               return (-1);
        ND_PRINT((ndo, "GN_ADDR:%s ", linkaddr_string (ndo, bp, 0, GEONET_ADDR_LEN)));
 
        if (!ND_TTEST2(*(bp+12), 8))
@@ -103,7 +105,8 @@ print_long_pos_vector(netdissect_options *ndo,
  * to the geonet header of the packet.
  */
 void
-geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int length)
+geonet_print(netdissect_options *ndo, const u_char *bp, u_int length,
+            const struct lladdr_info *src)
 {
        int version;
        int next_hdr;
@@ -115,13 +118,16 @@ geonet_print(netdissect_options *ndo, const u_char *eth, const u_char *bp, u_int
        const char *hdr_type_txt = "Unknown";
        int hdr_size = -1;
 
-       ND_PRINT((ndo, "GeoNet src:%s; ", etheraddr_string(ndo, eth+6)));
+       ND_PRINT((ndo, "GeoNet "));
+       if (src != NULL)
+               ND_PRINT((ndo, "src:%s", (src->addr_string)(ndo, src->addr)));
+       ND_PRINT((ndo, "; "));
 
        /* Process Common Header */
        if (length < 36)
                goto invalid;
 
-       ND_TCHECK2(*bp, 7);
+       ND_TCHECK2(*bp, 8);
        version = bp[0] >> 4;
        next_hdr = bp[0] & 0x0f;
        hdr_type = bp[1] >> 4;
index fc204652cc7657697bcfb5c3129cf7cb0ac78f7c..b8a08e9626e733225888c388f37825b290e42cf6 100644 (file)
@@ -93,6 +93,7 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
 {
        const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
        struct ether_header ehdr;
+       struct lladdr_info src, dst;
        int llc_hdrlen;
 
        if (caplen < IPFC_HDRLEN) {
@@ -107,13 +108,18 @@ ipfc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
        if (ndo->ndo_eflag)
                ipfc_hdr_print(ndo, ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
 
+       src.addr = ESRC(&ehdr);
+       src.addr_string = etheraddr_string;
+       dst.addr = EDST(&ehdr);
+       dst.addr_string = etheraddr_string;
+
        /* Skip over Network_Header */
        length -= IPFC_HDRLEN;
        p += IPFC_HDRLEN;
        caplen -= IPFC_HDRLEN;
 
        /* Try to print the LLC-layer header & higher layers */
-       llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr), EDST(&ehdr));
+       llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
        if (llc_hdrlen < 0) {
                /*
                 * Some kinds of LLC packet we cannot
index 2fc5bea6de198d96ff17b34ea61e8315ad95814d..4fb5453c991a13d45ca6922f8122217ce7f93ec4 100644 (file)
@@ -746,7 +746,8 @@ juniper_pppoe_atm_print(netdissect_options *ndo,
         if (ethertype_print(ndo, extracted_ethertype,
                               p+ETHERTYPE_LEN,
                               l2info.length-ETHERTYPE_LEN,
-                              l2info.caplen-ETHERTYPE_LEN) == 0)
+                              l2info.caplen-ETHERTYPE_LEN,
+                              NULL, NULL) == 0)
             /* ether_type not known, probably it wasn't one */
             ND_PRINT((ndo, "unknown ethertype 0x%04x", extracted_ethertype));
 
index 99d74c11fe9a172ba6dc3cd6cc8428e4f20b54ca..bca9b5021150c45b36865f8f2ba9cabed25345be 100644 (file)
@@ -148,7 +148,7 @@ static const struct oui_tok oui_to_tok[] = {
  */
 int
 llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
-         const u_char *esrc, const u_char *edst)
+         const struct lladdr_info *src, const struct lladdr_info *dst)
 {
        uint8_t dsap_field, dsap, ssap_field, ssap;
        uint16_t control;
@@ -262,7 +262,7 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * Does anybody ever bridge one form of LAN traffic
                 * over a networking type that uses 802.2 LLC?
                 */
-               if (!snap_print(ndo, p, length, caplen, esrc, edst, 2)) {
+               if (!snap_print(ndo, p, length, caplen, src, dst, 2)) {
                        /*
                         * Unknown packet type; tell our caller, by
                         * returning a negative value, so they
@@ -330,23 +330,23 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
 
        if (!ndo->ndo_eflag) {
                if (ssap == dsap) {
-                       if (esrc == NULL || edst == NULL)
+                       if (src == NULL || dst == NULL)
                                ND_PRINT((ndo, "%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)));
                        else
                                ND_PRINT((ndo, "%s > %s %s ",
-                                               etheraddr_string(ndo, esrc),
-                                               etheraddr_string(ndo, edst),
+                                               (src->addr_string)(ndo, src->addr),
+                                               (dst->addr_string)(ndo, dst->addr),
                                                tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)));
                } else {
-                       if (esrc == NULL || edst == NULL)
+                       if (src == NULL || dst == NULL)
                                ND_PRINT((ndo, "%s > %s ",
                                         tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
                                        tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)));
                        else
                                ND_PRINT((ndo, "%s %s > %s %s ",
-                                       etheraddr_string(ndo, esrc),
+                                       (src->addr_string)(ndo, src->addr),
                                         tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
-                                       etheraddr_string(ndo, edst),
+                                       (dst->addr_string)(ndo, dst->addr),
                                        tok2str(llc_values, "Unknown DSAP 0x%02x", dsap)));
                }
        }
@@ -399,7 +399,8 @@ oui_to_struct_tok(uint32_t orgcode)
 
 int
 snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
-       const u_char *esrc, const u_char *edst, u_int bridge_pad)
+       const struct lladdr_info *src, const struct lladdr_info *dst,
+       u_int bridge_pad)
 {
        uint32_t orgcode;
        register u_short et;
@@ -437,7 +438,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                 * Cisco hardware; the protocol ID is
                 * an Ethernet protocol type.
                 */
-               ret = ethertype_print(ndo, et, p, length, caplen);
+               ret = ethertype_print(ndo, et, p, length, caplen, src, dst);
                if (ret)
                        return (ret);
                break;
@@ -452,7 +453,7 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
                         * but used 0x000000 and an Ethernet
                         * packet type for AARP packets.
                         */
-                       ret = ethertype_print(ndo, et, p, length, caplen);
+                       ret = ethertype_print(ndo, et, p, length, caplen, src, dst);
                        if (ret)
                                return (ret);
                }
@@ -553,13 +554,13 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
        }
        if (!ndo->ndo_eflag) {
                /*
-                * Nobody printed the MAC addresses, so print them, if
+                * Nobody printed the link-layer addresses, so print them, if
                 * we have any.
                 */
-               if (esrc != NULL && edst != NULL) {
+               if (src != NULL && dst != NULL) {
                        ND_PRINT((ndo, "%s > %s ",
-                               etheraddr_string(ndo, esrc),
-                               etheraddr_string(ndo, edst)));
+                               (src->addr_string)(ndo, src->addr),
+                               (dst->addr_string)(ndo, dst->addr)));
                }
                /*
                 * Print the SNAP header, but if the OUI is 000000, don't
index 1266c9c89613d5fbdc262dab2791597dc2f32312..005416f06f1ab7c08480ede1fb30c1585f2cb92e 100644 (file)
@@ -30,6 +30,7 @@
 #include "netdissect.h"
 #include "ether.h"
 #include "ethertype.h"
+#include "addrtoname.h"
 #include "extract.h"
 
 static const char tstr[] = "[|MEDSA]";
@@ -141,6 +142,7 @@ medsa_print(netdissect_options *ndo,
 {
        register const struct ether_header *ep;
        const struct medsa_pkthdr *medsa;
+       struct lladdr_info src, dst;
        u_short ether_type;
 
        medsa = (const struct medsa_pkthdr *)bp;
@@ -157,10 +159,14 @@ medsa_print(netdissect_options *ndo,
        length -= 8;
        caplen -= 8;
 
+       src.addr = ESRC(ep);
+       src.addr_string = etheraddr_string;
+       dst.addr = EDST(ep);
+       dst.addr_string = etheraddr_string;
        ether_type = EXTRACT_16BITS(&medsa->ether_type);
        if (ether_type <= ETHERMTU) {
                /* Try to print the LLC-layer header & higher layers */
-               if (llc_print(ndo, bp, length, caplen, ESRC(ep), EDST(ep)) < 0) {
+               if (llc_print(ndo, bp, length, caplen, &src, &dst) < 0) {
                        /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
                                ND_DEFAULTPRINT(bp, caplen);
@@ -172,7 +178,7 @@ medsa_print(netdissect_options *ndo,
                                          ether_type),
                                  ether_type));
 
-               if (ethertype_print(ndo, ether_type, bp, length, caplen) == 0) {
+               if (ethertype_print(ndo, ether_type, bp, length, caplen, &src, &dst) == 0) {
                        /* ether_type not known, print raw packet */
                        if (!ndo->ndo_eflag)
                                ND_PRINT((ndo, "ethertype %s (0x%04x) ",
index ee3a858d97355f9c94b10ddd831f3ac59946d0ad..936b3ea72cedfc2e023e5c9857b8bf97c4a562e8 100644 (file)
@@ -73,54 +73,54 @@ static const struct tok opcode_values[] = {
 void
 rrcp_print(netdissect_options *ndo,
          register const u_char *cp,
-         u_int length _U_)
+         u_int length _U_,
+         const struct lladdr_info *src,
+         const struct lladdr_info *dst)
 {
-       const u_char *rrcp;
        uint8_t rrcp_proto;
        uint8_t rrcp_opcode;
-       register const struct ether_header *ep;
 
-       ep = (const struct ether_header *)cp;
-       rrcp = cp + ETHER_HDRLEN;
-
-       ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET));
-       rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET);
-       ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET));
-       rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK;
-       ND_PRINT((ndo, "%s > %s, %s %s",
-               etheraddr_string(ndo, ESRC(ep)),
-               etheraddr_string(ndo, EDST(ep)),
+       ND_TCHECK(*(cp + RRCP_PROTO_OFFSET));
+       rrcp_proto = *(cp + RRCP_PROTO_OFFSET);
+       ND_TCHECK(*(cp + RRCP_OPCODE_ISREPLY_OFFSET));
+       rrcp_opcode = (*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK;
+       if (src != NULL && dst != NULL) {
+               ND_PRINT((ndo, "%s > %s, ",
+                       (src->addr_string)(ndo, src->addr),
+                       (dst->addr_string)(ndo, dst->addr)));
+       }
+       ND_PRINT((ndo, "%s %s",
                tok2str(proto_values,"RRCP-0x%02x",rrcp_proto),
-               ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"));
+               ((*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"));
        if (rrcp_proto==1){
            ND_PRINT((ndo, ": %s",
                     tok2str(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode)));
        }
        if (rrcp_opcode==1 || rrcp_opcode==2){
-           ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6);
+           ND_TCHECK2(*(cp + RRCP_REG_ADDR_OFFSET), 6);
            ND_PRINT((ndo, " addr=0x%04x, data=0x%08x",
-                    EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET),
-                    EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET)));
+                    EXTRACT_LE_16BITS(cp + RRCP_REG_ADDR_OFFSET),
+                    EXTRACT_LE_32BITS(cp + RRCP_REG_DATA_OFFSET)));
        }
        if (rrcp_proto==1){
-           ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2);
+           ND_TCHECK2(*(cp + RRCP_AUTHKEY_OFFSET), 2);
            ND_PRINT((ndo, ", auth=0x%04x",
-                 EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET)));
+                 EXTRACT_16BITS(cp + RRCP_AUTHKEY_OFFSET)));
        }
        if (rrcp_proto==1 && rrcp_opcode==0 &&
-            ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){
-           ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4);
+            ((*(cp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){
+           ND_TCHECK2(*(cp + RRCP_VENDOR_ID_OFFSET), 4);
            ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ",
-                    *(rrcp + RRCP_DOWNLINK_PORT_OFFSET),
-                    *(rrcp + RRCP_UPLINK_PORT_OFFSET),
-                    etheraddr_string(ndo, rrcp + RRCP_UPLINK_MAC_OFFSET),
-                    EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET),
-                    EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET)));
+                    *(cp + RRCP_DOWNLINK_PORT_OFFSET),
+                    *(cp + RRCP_UPLINK_PORT_OFFSET),
+                    etheraddr_string(ndo, cp + RRCP_UPLINK_MAC_OFFSET),
+                    EXTRACT_32BITS(cp + RRCP_VENDOR_ID_OFFSET),
+                    EXTRACT_16BITS(cp + RRCP_CHIP_ID_OFFSET)));
        }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){
-           ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4);
+           ND_TCHECK2(*(cp + RRCP_COOKIE2_OFFSET), 4);
            ND_PRINT((ndo, ", cookie=0x%08x%08x ",
-                   EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET),
-                   EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET)));
+                   EXTRACT_32BITS(cp + RRCP_COOKIE2_OFFSET),
+                   EXTRACT_32BITS(cp + RRCP_COOKIE1_OFFSET)));
        }
        return;
 
index 0cbc3c93103d2734ce01bb16f3ab018643472bb4..6148569ec160802ca48001223953ff1a16716b1e 100644 (file)
@@ -297,7 +297,7 @@ recurse:
                hdrlen += 4;
                goto recurse;
        } else {
-               if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
+               if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
                        /* ether_type not known, print raw packet */
                        if (!ndo->ndo_eflag)
                                sll_print(ndo, sllp, length + SLL_HDR_LEN);
index 13ac4e15aa4b117179ec6289105c2a7e9728e0c8..9e9f8f33f06d32281764dcdf8848f4be058d1f96 100644 (file)
@@ -101,7 +101,7 @@ symantec_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_
 
                if (!ndo->ndo_suppress_default_print)
                        ND_DEFAULTPRINT(p, caplen);
-       } else if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
+       } else if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
                /* ether_type not known, print raw packet */
                if (!ndo->ndo_eflag)
                        symantec_hdr_print(ndo, (const u_char *)sp, length + sizeof (struct symantec_header));
index 370c44c991a630831b7048c02a19b37d89b461c9..faffd4b13ce472194f17744fa02ff26c4fd9772a 100644 (file)
@@ -151,6 +151,7 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
        const struct token_header *trp;
        int llc_hdrlen;
        struct ether_header ehdr;
+       struct lladdr_info src, dst;
        u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
        int seg;
 
@@ -203,6 +204,11 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
                        token_hdr_print(ndo, trp, length, ESRC(&ehdr), EDST(&ehdr));
        }
 
+       src.addr = ESRC(&ehdr);
+       src.addr_string = etheraddr_string;
+       dst.addr = EDST(&ehdr);
+       dst.addr_string = etheraddr_string;
+
        /* Skip over token ring MAC header and routing information */
        length -= hdr_len;
        p += hdr_len;
@@ -211,8 +217,7 @@ token_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen
        /* Frame Control field determines interpretation of packet */
        if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
                /* Try to print the LLC-layer header & higher layers */
-               llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(&ehdr),
-                   EDST(&ehdr));
+               llc_hdrlen = llc_print(ndo, p, length, caplen, &src, &dst);
                if (llc_hdrlen < 0) {
                        /* packet type not known, print raw packet */
                        if (!ndo->ndo_suppress_default_print)
index a406c8840d558d633cfed1df6edd6ca02da0dc0b..96d0312d8e6f17e1933d8b175f08e4017ef709af 100644 (file)
@@ -379,3 +379,5 @@ heapoverflow-in_checksum    heapoverflow-in_checksum.pcap   heapoverflow-in_checksum.
 heapoverflow-tcp_print heapoverflow-tcp_print.pcap     heapoverflow-tcp_print.out      -t -v -n
 gre-heapoverflow-1     gre-heapoverflow-1.pcap gre-heapoverflow-1.out  -t -v -n
 gre-heapoverflow-2     gre-heapoverflow-2.pcap gre-heapoverflow-2.out  -t -v -n
+calm-fast-mac-lookup-heapoverflow      calm-fast-mac-lookup-heapoverflow.pcap  calm-fast-mac-lookup-heapoverflow.out   -t -v -n
+geonet-mac-lookup-heapoverflow geonet-mac-lookup-heapoverflow.pcap     geonet-mac-lookup-heapoverflow.out      -t -v -n
diff --git a/tests/calm-fast-mac-lookup-heapoverflow.out b/tests/calm-fast-mac-lookup-heapoverflow.out
new file mode 100644 (file)
index 0000000..a6e6f41
--- /dev/null
@@ -0,0 +1,5 @@
+Q.922, invalid address
+CALM FAST; SrcNwref:48; DstNwref:48; 
+       0x0000:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+       0x0010:  3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
+       0x0020:  3030 3030 3030 3030 3030                 0000000000
diff --git a/tests/calm-fast-mac-lookup-heapoverflow.pcap b/tests/calm-fast-mac-lookup-heapoverflow.pcap
new file mode 100644 (file)
index 0000000..a840955
Binary files /dev/null and b/tests/calm-fast-mac-lookup-heapoverflow.pcap differ
diff --git a/tests/geonet-mac-lookup-heapoverflow.out b/tests/geonet-mac-lookup-heapoverflow.out
new file mode 100644 (file)
index 0000000..7d49dd0
--- /dev/null
@@ -0,0 +1 @@
+GeoNet src:30:30:30:30:30:30; v:3 NH:0-Any HT:3-0-GeoAnycastCircle HopLim:48 Payload:12336 [|geonet]
diff --git a/tests/geonet-mac-lookup-heapoverflow.pcap b/tests/geonet-mac-lookup-heapoverflow.pcap
new file mode 100644 (file)
index 0000000..e3041fb
Binary files /dev/null and b/tests/geonet-mac-lookup-heapoverflow.pcap differ