summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2011-07-25 18:39:36 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2011-07-25 18:39:36 +0000
commit4eee80d8fefd139a740fedc1b1ea477a0cd116a0 (patch)
tree35f3e06070e2bc49a59106105b5013b8d7d9533d
parent2d4ecd8dd891af99fcd50da26b13db70b183b095 (diff)
Be more careful when looking at l2tp traffic. Do more length checks and
make sure that no unaligned access to uint16_t values happen. Tested and feedback by yasuoka@
-rw-r--r--usr.sbin/tcpdump/print-l2tp.c76
1 files changed, 51 insertions, 25 deletions
diff --git a/usr.sbin/tcpdump/print-l2tp.c b/usr.sbin/tcpdump/print-l2tp.c
index caa639112fc..95020de4c13 100644
--- a/usr.sbin/tcpdump/print-l2tp.c
+++ b/usr.sbin/tcpdump/print-l2tp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: print-l2tp.c,v 1.5 2009/10/27 23:59:55 deraadt Exp $ */
+/* $OpenBSD: print-l2tp.c,v 1.6 2011/07/25 18:39:35 claudio Exp $ */
/*
* Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/param.h>
#include <stdio.h>
+#include <strings.h>
#include "l2tp.h"
#include "interface.h"
@@ -615,9 +616,8 @@ l2tp_avp_print(const u_char *dat, u_int length)
void
l2tp_print(const u_char *dat, u_int length)
{
- const u_short *ptr = (u_short *)dat;
u_int cnt = 0; /* total octets consumed */
- u_short pad;
+ u_short pad, val;
int flag_t, flag_l, flag_s, flag_o, flag_p;
u_short l2tp_len;
@@ -630,9 +630,11 @@ l2tp_print(const u_char *dat, u_int length)
return;
}
- if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ if ((ntohs(val) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
printf(" l2tp:");
- } else if ((ntohs(*ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
+ } else if ((ntohs(val) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
printf(" l2f:");
return; /* nothing to do */
} else {
@@ -641,53 +643,74 @@ l2tp_print(const u_char *dat, u_int length)
}
printf("[");
- if (ntohs(*ptr) & L2TP_FLAG_TYPE) {
+ if (ntohs(val) & L2TP_FLAG_TYPE) {
flag_t = TRUE;
printf("T");
}
- if (ntohs(*ptr) & L2TP_FLAG_LENGTH) {
+ if (ntohs(val) & L2TP_FLAG_LENGTH) {
flag_l = TRUE;
printf("L");
}
- if (ntohs(*ptr) & L2TP_FLAG_SEQUENCE) {
+ if (ntohs(val) & L2TP_FLAG_SEQUENCE) {
flag_s = TRUE;
printf("S");
}
- if (ntohs(*ptr) & L2TP_FLAG_OFFSET) {
+ if (ntohs(val) & L2TP_FLAG_OFFSET) {
flag_o = TRUE;
printf("O");
}
- if (ntohs(*ptr) & L2TP_FLAG_PRIORITY) {
+ if (ntohs(val) & L2TP_FLAG_PRIORITY) {
flag_p = TRUE;
printf("P");
}
printf("]");
- ptr++;
+ dat += 2;
cnt += 2;
if (flag_l) {
- l2tp_len = ntohs(*ptr++); /* XXX need to consider
- truncation ?? */
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ l2tp_len = ntohs(val);
+ dat += 2;
cnt += 2;
} else {
l2tp_len = 0;
}
- printf("(%d/", ntohs(*ptr++)); /* Tunnel ID */
- printf("%d)", ntohs(*ptr++)); /* Session ID */
- cnt += 4;
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ printf("(%d/", ntohs(val)); /* Tunnel ID */
+ dat += 2;
+ cnt += 2;
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ printf("%d)", ntohs(val)); /* Session ID */
+ dat += 2;
+ cnt += 2;
if (flag_s) {
- printf("Ns=%d,", ntohs(*ptr++));
- printf("Nr=%d", ntohs(*ptr++));
- cnt += 4;
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ printf("Ns=%d,", ntohs(val));
+ dat += 2;
+ cnt += 2;
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ printf("Nr=%d", ntohs(val));
+ dat += 2;
+ cnt += 2;
}
if (flag_o) {
- pad = ntohs(*ptr++);
- ptr = (u_char *)ptr + pad;
- cnt += (2 + pad);
+ TCHECK2(*dat, sizeof(val));
+ memcpy(&val, dat, sizeof(val));
+ pad = ntohs(val);
+ dat += 2;
+ cnt += 2;
+ TCHECK2(*dat, pad);
+ dat += pad;
+ cnt += pad;
}
if (flag_t) {
@@ -695,15 +718,18 @@ l2tp_print(const u_char *dat, u_int length)
printf(" ZLB");
} else {
if (length >= cnt)
- l2tp_avp_print((u_char *)ptr, length - cnt);
+ l2tp_avp_print(dat, length - cnt);
}
} else {
#if 0
printf(" {");
- ppp_hdlc_print((u_char *)ptr, length - cnt);
+ ppp_hdlc_print(dat, length - cnt);
printf("}");
#else
printf("[hdlc|]");
#endif
}
-}
+
+trunc:
+ printf("[|l2tp]");
+}