summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2015-07-03 15:54:14 -0700
committerFrancois-Xavier Le Bail <fx.lebail@yahoo.com>2017-01-18 09:16:36 +0100
commit6bc44295cfbe1f7b6633c755841518f4b159aa8a (patch)
tree859fda193d4664cfce2892e3c3c219847ada789b
parent237efcf593ee369519e9dfdc9166702219dabfec (diff)
downloadtcpdump-6bc44295cfbe1f7b6633c755841518f4b159aa8a.tar.gz
CVE-2016-7985,7986/Change the way protocols print link-layer addresses.
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.
-rw-r--r--netdissect.h27
-rw-r--r--print-802_11.c12
-rw-r--r--print-ap1394.c17
-rw-r--r--print-calm-fast.c22
-rw-r--r--print-ether.c20
-rw-r--r--print-fddi.c8
-rw-r--r--print-fr.c3
-rw-r--r--print-geneve.c2
-rw-r--r--print-geonet.c12
-rw-r--r--print-ipfc.c8
-rw-r--r--print-juniper.c3
-rw-r--r--print-llc.c31
-rw-r--r--print-medsa.c10
-rw-r--r--print-rrcp.c58
-rw-r--r--print-sll.c2
-rw-r--r--print-symantec.c2
-rw-r--r--print-token.c9
-rw-r--r--tests/TESTLIST2
-rw-r--r--tests/calm-fast-mac-lookup-heapoverflow.out5
-rw-r--r--tests/calm-fast-mac-lookup-heapoverflow.pcapbin0 -> 202 bytes
-rw-r--r--tests/geonet-mac-lookup-heapoverflow.out1
-rw-r--r--tests/geonet-mac-lookup-heapoverflow.pcapbin0 -> 74 bytes
22 files changed, 171 insertions, 83 deletions
diff --git a/netdissect.h b/netdissect.h
index 902bf1b2..a855e87a 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -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 *);
diff --git a/print-802_11.c b/print-802_11.c
index 7721524b..78a57b18 100644
--- a/print-802_11.c
+++ b/print-802_11.c
@@ -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
diff --git a/print-ap1394.c b/print-ap1394.c
index 1e6bbd98..79401cba 100644
--- a/print-ap1394.c
+++ b/print-ap1394.c
@@ -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);
diff --git a/print-calm-fast.c b/print-calm-fast.c
index 4e4e51af..c9be008c 100644
--- a/print-calm-fast.c
+++ b/print-calm-fast.c
@@ -37,19 +37,33 @@
* 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;
}
diff --git a/print-ether.c b/print-ether.c
index 0f8c7dc5..59d15c24 100644
--- a/print-ether.c
+++ b/print-ether.c
@@ -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:
diff --git a/print-fddi.c b/print-fddi.c
index 93f6ccd8..27803783 100644
--- a/print-fddi.c
+++ b/print-fddi.c
@@ -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
diff --git a/print-fr.c b/print-fr.c
index 3ee46551..9c97bcb4 100644
--- a/print-fr.c
+++ b/print-fr.c
@@ -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
diff --git a/print-geneve.c b/print-geneve.c
index d565103d..f0319636 100644
--- a/print-geneve.c
+++ b/print-geneve.c
@@ -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
diff --git a/print-geonet.c b/print-geonet.c
index 61441a0b..9da89bfe 100644
--- a/print-geonet.c
+++ b/print-geonet.c
@@ -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;
diff --git a/print-ipfc.c b/print-ipfc.c
index fc204652..b8a08e96 100644
--- a/print-ipfc.c
+++ b/print-ipfc.c
@@ -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
diff --git a/print-juniper.c b/print-juniper.c
index 2fc5bea6..4fb5453c 100644
--- a/print-juniper.c
+++ b/print-juniper.c
@@ -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));
diff --git a/print-llc.c b/print-llc.c
index 99d74c11..bca9b502 100644
--- a/print-llc.c
+++ b/print-llc.c
@@ -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
diff --git a/print-medsa.c b/print-medsa.c
index 1266c9c8..005416f0 100644
--- a/print-medsa.c
+++ b/print-medsa.c
@@ -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) ",
diff --git a/print-rrcp.c b/print-rrcp.c
index ee3a858d..936b3ea7 100644
--- a/print-rrcp.c
+++ b/print-rrcp.c
@@ -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;
diff --git a/print-sll.c b/print-sll.c
index 0cbc3c93..6148569e 100644
--- a/print-sll.c
+++ b/print-sll.c
@@ -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);
diff --git a/print-symantec.c b/print-symantec.c
index 13ac4e15..9e9f8f33 100644
--- a/print-symantec.c
+++ b/print-symantec.c
@@ -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));
diff --git a/print-token.c b/print-token.c
index 370c44c9..faffd4b1 100644
--- a/print-token.c
+++ b/print-token.c
@@ -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)
diff --git a/tests/TESTLIST b/tests/TESTLIST
index a406c884..96d0312d 100644
--- a/tests/TESTLIST
+++ b/tests/TESTLIST
@@ -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
index 00000000..a6e6f418
--- /dev/null
+++ b/tests/calm-fast-mac-lookup-heapoverflow.out
@@ -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
index 00000000..a8409557
--- /dev/null
+++ b/tests/calm-fast-mac-lookup-heapoverflow.pcap
Binary files differ
diff --git a/tests/geonet-mac-lookup-heapoverflow.out b/tests/geonet-mac-lookup-heapoverflow.out
new file mode 100644
index 00000000..7d49dd0e
--- /dev/null
+++ b/tests/geonet-mac-lookup-heapoverflow.out
@@ -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
index 00000000..e3041fb3
--- /dev/null
+++ b/tests/geonet-mac-lookup-heapoverflow.pcap
Binary files differ