diff options
author | 2011-07-25 18:39:35 +0000 | |
---|---|---|
committer | 2011-07-25 18:39:35 +0000 | |
commit | 1187e207efe674cc461661190fc6f2c4728b496d (patch) | |
tree | ad3d0b6bf162c2990e097258ad2b5d97bcaca6a5 | |
parent | document syslog facility/level; from Stefan Unterweger (diff) | |
download | wireguard-openbsd-1187e207efe674cc461661190fc6f2c4728b496d.tar.xz wireguard-openbsd-1187e207efe674cc461661190fc6f2c4728b496d.zip |
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]"); +} |