summaryrefslogtreecommitdiff
path: root/print-aodv.c
diff options
context:
space:
mode:
authorguy <guy>2004-03-24 00:30:19 +0000
committerguy <guy>2004-03-24 00:30:19 +0000
commitb340e34b6ac70fe143bf375c91446273ed3e6552 (patch)
tree7318e590fa335b1b95439f2400306219aeda69ae /print-aodv.c
parent33ede7fbeaf45b5a26884f8ce4c4cb660b85adc1 (diff)
downloadtcpdump-b340e34b6ac70fe143bf375c91446273ed3e6552.tar.gz
Add bounds checking.
Diffstat (limited to 'print-aodv.c')
-rw-r--r--print-aodv.c28
1 files changed, 19 insertions, 9 deletions
diff --git a/print-aodv.c b/print-aodv.c
index b1539a9a..c5f66223 100644
--- a/print-aodv.c
+++ b/print-aodv.c
@@ -32,7 +32,7 @@
#ifndef lint
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.10 2003-11-16 09:36:12 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.11 2004-03-24 00:30:19 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -143,20 +143,30 @@ aodv_rrep(const union aodv *ap, const u_char *dat, u_int length)
}
static void
-aodv_rerr(const union aodv *ap, u_int length)
+aodv_rerr(const union aodv *ap, const u_char *dat, u_int length)
{
+ u_int i;
const struct rerr_unreach *dp = NULL;
- int i, j, n, trunc;
+ int n, trunc;
- i = length - offsetof(struct aodv_rerr, r);
- j = sizeof(ap->rerr.r.dest[0]);
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < offsetof(struct aodv_rerr, r)) {
+ printf(" [|rerr]");
+ return;
+ }
+ i -= offsetof(struct aodv_rerr, r);
dp = &ap->rerr.r.dest[0];
- n = ap->rerr.rerr_dc * j;
+ n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
printf(" rerr %s [items %u] [%u]:",
ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
ap->rerr.rerr_dc, length);
- trunc = n - (i/j);
- for (; i -= j >= 0; ++dp) {
+ trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
+ for (; i >= sizeof(ap->rerr.r.dest[0]);
+ ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
printf(" {%s}(%ld)", ipaddr_string(&dp->u_da),
(unsigned long)EXTRACT_32BITS(&dp->u_ds));
}
@@ -416,7 +426,7 @@ aodv_print(const u_char *dat, u_int length, int is_ip6)
if (is_ip6)
aodv_v6_rerr(ap, length);
else
- aodv_rerr(ap, length);
+ aodv_rerr(ap, dat, length);
break;
case AODV_RREP_ACK: