Skip to content

Commit

Permalink
Bug #616 add checks for datalen for DLT_JUNIPER_ETHER
Browse files Browse the repository at this point in the history
Also did some fixes to Juniper Ethernet protocols to fix some bugs
and support various types of Juniper Ethernet protocol types. Used
Wireshark sources to figure out all the different packet types that
Juniper uses.

Unable to test all types because of lack of JNPER DLT pcaps.

Also applied a fix for DLT_RAW to prevent similar issues.
  • Loading branch information
fklassen committed Mar 13, 2021
1 parent 1621e1d commit 8323a7f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 18 deletions.
2 changes: 2 additions & 0 deletions docs/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
03/12/2021 Version 4.3.4 Beta1
- Fix gcc 8.3.0 build warnings (#634)
- CVE-2020-24265 heap buffer overflow in tcp-prep (#616)
- Compile failure on aarch64-linux-android (#612)

05/20/2020 Version 4.3.3
- Increase cache buffers size to accomodate VLAN edits (#594)
Expand Down
69 changes: 51 additions & 18 deletions src/common/get.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ extern int debug;
extern const char pcap_version[];
#endif


#define JUNIPER_FLAG_NO_L2 0x02 /* L2 header */
#define JUNIPER_FLAG_EXT 0x80 /* Juniper extensions present */
#define JUNIPER_PCAP_MAGIC "MGC"
/**
* Depending on what version of libpcap/WinPcap there are different ways to get
* the version of the libpcap/WinPcap library. This presents a unified way to
Expand Down Expand Up @@ -88,27 +90,46 @@ get_l2protocol(const u_char *pktdata, const uint32_t datalen, const int datalink

switch (datalink) {
case DLT_RAW:
if (datalen < 1)
return 0;
if ((pktdata[0] >> 4) == 4)
return ETHERTYPE_IP;
else if ((pktdata[0] >> 4) == 6)
return ETHERTYPE_IP6;
break;

case DLT_JUNIPER_ETHER:
if (datalen < 5)
if (datalen < 4)
return 0;

if (memcmp(pktdata, "MGC", 3))
warnx("No Magic Number found: %s (0x%x)",
if (memcmp(pktdata, JUNIPER_PCAP_MAGIC, 3)) {
warnx("No Magic Number found during protocol lookup: %s (0x%x)",
pcap_datalink_val_to_description(datalink), datalink);
return 0;
}

if ((pktdata[3] & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
if (datalen < 6)
return 0; /* datalen too short */

if ((pktdata[3] & 0x80) == 0x80) {
eth_hdr_offset = ntohs(*((uint16_t*)&pktdata[4]));
eth_hdr_offset += 6;
eth_hdr_offset += 6; /* MGC + flags + ext_total_len */
} else {
eth_hdr_offset = 4; /* no header extensions */
eth_hdr_offset = 4; /* MGC + flags (no header extensions) */
}
/* fallthrough */
if ((pktdata[3] & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
/* no L2 header present - eth_hdr_offset is actually IP offset */
uint32_t ip_hdr_offset = eth_hdr_offset;
if (datalen < ip_hdr_offset + 1)
return 0;
if ((pktdata[ip_hdr_offset] >> 4) == 4)
return ETHERTYPE_IP;
else if ((pktdata[ip_hdr_offset] >> 4) == 6)
return ETHERTYPE_IP6;
else
return 0;
}
/* fall through */
case DLT_EN10MB:
if ((size_t)datalen >= (sizeof(eth_hdr_t) + eth_hdr_offset)) {
eth_hdr_t *eth_hdr = (eth_hdr_t *)(pktdata + eth_hdr_offset);
Expand Down Expand Up @@ -158,7 +179,6 @@ get_l2protocol(const u_char *pktdata, const uint32_t datalen, const int datalink
}

return 0;

}

/**
Expand All @@ -178,23 +198,36 @@ get_l2len(const u_char *pktdata, const int datalen, const int datalink)
break;

case DLT_JUNIPER_ETHER:
if (datalen >= 5) {
if (datalen < 4) {
l2_len = -1;
break;
}

if (memcmp(pktdata, "MGC", 3))
warnx("No Magic Number found: %s (0x%x)",
pcap_datalink_val_to_description(datalink), datalink);
if (memcmp(pktdata, JUNIPER_PCAP_MAGIC, 3)) {
warnx("No Magic Number found during L2 lookup: %s (0x%x)",
pcap_datalink_val_to_description(datalink), datalink);
l2_len = -1;
break;
}

if ((pktdata[3] & 0x80) == 0x80) {
if ((pktdata[3] & JUNIPER_FLAG_NO_L2) == JUNIPER_FLAG_NO_L2) {
/* no L2 header present */
l2_len = 0;
break;
}

if ((pktdata[3] & JUNIPER_FLAG_EXT) == JUNIPER_FLAG_EXT) {
if (datalen < 6) {
/* datalen too short */
l2_len = -1;
break;
}
l2_len = ntohs(*((uint16_t*)&pktdata[4]));
l2_len += 6;
l2_len += 6; /* MGC + flags + ext_total_len */
} else {
l2_len = 4; /* no header extensions */
l2_len = 4; /* MGC + flags */
}

/* fallthrough */
/* fall through */
case DLT_EN10MB:
if ((size_t)datalen >= sizeof(eth_hdr_t) + l2_len) {
uint16_t ether_type = ntohs(((eth_hdr_t*)(pktdata + l2_len))->ether_type);
Expand Down

0 comments on commit 8323a7f

Please sign in to comment.