summaryrefslogtreecommitdiff
path: root/print-llc.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-12-18 15:51:11 -0800
committerGuy Harris <guy@alum.mit.edu>2014-12-18 15:51:11 -0800
commit743bcecdc92f88b118ec7aac4f68b606601205cc (patch)
treeb7797b0e4140a1bf0c2dd134fdc280ba9820b3d5 /print-llc.c
parentd7516761f9c4877bcb05bb6543be3543e1652498 (diff)
downloadtcpdump-743bcecdc92f88b118ec7aac4f68b606601205cc.tar.gz
Fix length checking.
Check both the captured length and the on-the-wire length (the latter *should* be greater than or equal to the former, but that's not guaranteed). Add some additional length checks, so neither caplen nor length underflow. If we stop dissecting because the packet is too short, return 1, not 0, as we've "dissected" what we can; 0 means "this is LLC+SNAP with an OUI of 0 and an unknown Ethertype".
Diffstat (limited to 'print-llc.c')
-rw-r--r--print-llc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/print-llc.c b/print-llc.c
index e78378d0..e8a3314c 100644
--- a/print-llc.c
+++ b/print-llc.c
@@ -151,10 +151,10 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
*extracted_ethertype = 0;
- if (caplen < 3) {
+ if (caplen < 3 || length < 3) {
ND_PRINT((ndo, "[|llc]"));
ND_DEFAULTPRINT((u_char *)p, caplen);
- return(0);
+ return (1);
}
dsap_field = *p;
@@ -177,10 +177,10 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
* The control field in I and S frames is
* 2 bytes...
*/
- if (caplen < 4) {
+ if (caplen < 4 || length < 4) {
ND_PRINT((ndo, "[|llc]"));
ND_DEFAULTPRINT((u_char *)p, caplen);
- return(0);
+ return (1);
}
/*
@@ -240,6 +240,11 @@ llc_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
control == LLC_UI) {
+ if (caplen < 4 || length < 4) {
+ ND_PRINT((ndo, "[|llc]"));
+ ND_DEFAULTPRINT((u_char *)p, caplen);
+ return (1);
+ }
ip_print(ndo, p+4, length-4);
return (1);
}
@@ -368,6 +373,8 @@ snap_print(netdissect_options *ndo, const u_char *p, u_int length, u_int caplen,
register int ret;
ND_TCHECK2(*p, 5);
+ if (caplen < 5 || length < 5)
+ goto trunc;
orgcode = EXTRACT_24BITS(p);
et = EXTRACT_16BITS(p + 3);