diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-07-25 18:39:36 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2011-07-25 18:39:36 +0000 |
commit | 4eee80d8fefd139a740fedc1b1ea477a0cd116a0 (patch) | |
tree | 35f3e06070e2bc49a59106105b5013b8d7d9533d | |
parent | 2d4ecd8dd891af99fcd50da26b13db70b183b095 (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.c | 76 |
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]"); +} |