]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-l2tp.c
C compilers can, and some do, optimize away pointer underflow checks.
[tcpdump] / print-l2tp.c
index b8087fcd98fc4eb83ca32bab462586f6ea09e265..2f726574e4ee3757b493bbdbd9707de6e5855d07 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 #ifndef lint
-static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.13 2002-08-01 08:53:15 risso Exp $";
+static const char rcsid[] _U_ =
+    "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -40,14 +40,6 @@ static const char rcsid[] =
 
 static char tstr[] = " [|l2tp]";
 
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
 #define        L2TP_MSGTYPE_SCCRQ      1  /* Start-Control-Connection-Request */
 #define        L2TP_MSGTYPE_SCCRP      2  /* Start-Control-Connection-Reply */
 #define        L2TP_MSGTYPE_SCCCN      3  /* Start-Control-Connection-Connected */
@@ -244,7 +236,7 @@ static char *l2tp_error_code_general[] = {
 static void
 print_string(const u_char *dat, u_int length)
 {
-       int i;
+       u_int i;
        for (i=0; i<length; i++) {
                printf("%c", *dat++);
        }
@@ -253,7 +245,7 @@ print_string(const u_char *dat, u_int length)
 static void
 print_octets(const u_char *dat, u_int length)
 {
-       int i;
+       u_int i;
        for (i=0; i<length; i++) {
                printf("%02x", *dat++);
        }
@@ -474,8 +466,17 @@ l2tp_avp_print(const u_char *dat, int length)
        TCHECK(*ptr);   /* Flags & Length */
        len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
 
-       /* If it is not long enough to decode the entire AVP, we'll
-          abandon. */
+       /* If it is not long enough to contain the header, we'll give up. */
+       if (len < 6)
+               goto trunc;
+
+       /* If it goes past the end of the remaining length of the packet,
+          we'll give up. */
+       if (len > (u_int)length)
+               goto trunc;
+
+       /* If it goes past the end of the remaining length of the captured
+          data, we'll give up. */
        TCHECK2(*ptr, len);
        /* After this point, no need to worry about truncation */
 
@@ -605,15 +606,15 @@ l2tp_avp_print(const u_char *dat, int length)
 void
 l2tp_print(const u_char *dat, u_int length)
 {
-       const u_int16_t *ptr = (u_int16_t *)dat;
+       const u_char *ptr = dat;
        u_int cnt = 0;                  /* total octets consumed */
        u_int16_t pad;
-       int flag_t, flag_l, flag_s, flag_o, flag_p;
+       int flag_t, flag_l, flag_s, flag_o;
        u_int16_t l2tp_len;
 
-       flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
+       flag_t = flag_l = flag_s = flag_o = FALSE;
 
-       TCHECK(*ptr);   /* Flags & Version */
+       TCHECK2(*ptr, 2);       /* Flags & Version */
        if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
                printf(" l2tp:");
        } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
@@ -641,55 +642,73 @@ l2tp_print(const u_char *dat, u_int length)
                flag_o = TRUE;
                printf("O");
        }
-       if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY) {
-               flag_p = TRUE;
+       if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY)
                printf("P");
-       }
        printf("]");
 
-       ptr++;
+       ptr += 2;
        cnt += 2;
 
        if (flag_l) {
-               TCHECK(*ptr);   /* Length */
-               l2tp_len = EXTRACT_16BITS(ptr); ptr++;
+               TCHECK2(*ptr, 2);       /* Length */
+               l2tp_len = EXTRACT_16BITS(ptr);
+               ptr += 2;
                cnt += 2;
        } else {
                l2tp_len = 0;
        }
 
-       TCHECK(*ptr);           /* Tunnel ID */
-       printf("(%u/", EXTRACT_16BITS(ptr)); ptr++;
+       TCHECK2(*ptr, 2);               /* Tunnel ID */
+       printf("(%u/", EXTRACT_16BITS(ptr));
+       ptr += 2;
        cnt += 2;
-       TCHECK(*ptr);           /* Session ID */
-       printf("%u)",  EXTRACT_16BITS(ptr)); ptr++;
+       TCHECK2(*ptr, 2);               /* Session ID */
+       printf("%u)",  EXTRACT_16BITS(ptr));
+       ptr += 2;
        cnt += 2;
 
        if (flag_s) {
-               TCHECK(*ptr);   /* Ns */
-               printf("Ns=%u,", EXTRACT_16BITS(ptr)); ptr++;
+               TCHECK2(*ptr, 2);       /* Ns */
+               printf("Ns=%u,", EXTRACT_16BITS(ptr));
+               ptr += 2;
                cnt += 2;
-               TCHECK(*ptr);   /* Nr */
-               printf("Nr=%u",  EXTRACT_16BITS(ptr)); ptr++;
+               TCHECK2(*ptr, 2);       /* Nr */
+               printf("Nr=%u",  EXTRACT_16BITS(ptr));
+               ptr += 2;
                cnt += 2;
        }
 
        if (flag_o) {
-               TCHECK(*ptr);   /* Offset Size */
-               pad =  EXTRACT_16BITS(ptr); ptr++;
-               ptr += pad / sizeof(*ptr);
+               TCHECK2(*ptr, 2);       /* Offset Size */
+               pad =  EXTRACT_16BITS(ptr);
+               ptr += (2 + pad);
                cnt += (2 + pad);
        }
 
+       if (flag_l) {
+               if (length < l2tp_len) {
+                       printf(" Length %u larger than packet", l2tp_len);
+                       return;
+               }
+               length = l2tp_len;
+       }
+       if (length < cnt) {
+               printf(" Length %u smaller than header length", length);
+               return;
+       }
        if (flag_t) {
+               if (!flag_l) {
+                       printf(" No length");
+                       return;
+               }
                if (length - cnt == 0) {
                        printf(" ZLB");
                } else {
-                       l2tp_avp_print((u_char *)ptr, length - cnt);
+                       l2tp_avp_print(ptr, length - cnt);
                }
        } else {
                printf(" {");
-               ppp_print((u_char *)ptr, length - cnt);
+               ppp_print(ptr, length - cnt);
                printf("}");
        }