]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ppp.c
Another length check, also found by the Clang Static Analyzer.
[tcpdump] / print-ppp.c
index ea8e00b244f9194d1810dc92a08791ad0f513c75..f19a03b100ee277709486371d437b354c0e75769 100644 (file)
  * o BAP support
  */
 
-#ifndef lint
-static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)";
-#endif
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -65,7 +60,7 @@ static const char rcsid[] _U_ =
 
 /* Protocol Codes defined in ppp.h */
 
-struct tok ppptype2str[] = {
+static const struct tok ppptype2str[] = {
         { PPP_IP,        "IP" },
         { PPP_OSI,       "OSI" },
         { PPP_NS,        "NS" },
@@ -129,7 +124,7 @@ struct tok ppptype2str[] = {
 #define CPCODES_RESET_REQ      14      /* Reset-Request (CCP only) RFC1962 */
 #define CPCODES_RESET_REP      15      /* Reset-Reply (CCP only) */
 
-struct tok cpcodes[] = {
+static const struct tok cpcodes[] = {
        {CPCODES_VEXT,      "Vendor-Extension"}, /* RFC2153 */
        {CPCODES_CONF_REQ,  "Conf-Request"},
         {CPCODES_CONF_ACK,  "Conf-Ack"},
@@ -243,7 +238,7 @@ static const char *lcpconfopts[] = {
 /* 27-254 unassigned */
 #define CCPOPT_RESV    255     /* RFC1962 */
 
-const struct tok ccpconfopts_values[] = {
+static const struct tok ccpconfopts_values[] = {
         { CCPOPT_OUI, "OUI" },
         { CCPOPT_PRED1, "Pred-1" },
         { CCPOPT_PRED2, "Pred-2" },
@@ -266,7 +261,7 @@ const struct tok ccpconfopts_values[] = {
 
 #define BACPOPT_FPEER  1       /* RFC2125 */
 
-const struct tok bacconfopts_values[] = {
+static const struct tok bacconfopts_values[] = {
         { BACPOPT_FPEER, "Favored-Peer" },
         {0,                 NULL}
 };
@@ -284,7 +279,7 @@ const struct tok bacconfopts_values[] = {
 #define IPCPOPT_SECDNS 131     /* RFC1877 */
 #define IPCPOPT_SECNBNS        132     /* RFC1877 */
 
-struct tok ipcpopt_values[] = {
+static const struct tok ipcpopt_values[] = {
         { IPCPOPT_2ADDR, "IP-Addrs" },
         { IPCPOPT_IPCOMP, "IP-Comp" },
         { IPCPOPT_ADDR, "IP-Addr" },
@@ -299,13 +294,13 @@ struct tok ipcpopt_values[] = {
 #define IPCPOPT_IPCOMP_HDRCOMP 0x61  /* rfc3544 */
 #define IPCPOPT_IPCOMP_MINLEN    14
 
-struct tok ipcpopt_compproto_values[] = {
+static const struct tok ipcpopt_compproto_values[] = {
         { PPP_VJC, "VJ-Comp" },
         { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" },
        { 0,              NULL }
 };
 
-struct tok ipcpopt_compproto_subopt_values[] = {
+static const struct tok ipcpopt_compproto_subopt_values[] = {
         { 1, "RTP-Compression" },
         { 2, "Enhanced RTP-Compression" },
        { 0,              NULL }
@@ -314,7 +309,7 @@ struct tok ipcpopt_compproto_subopt_values[] = {
 /* IP6CP Config Options */
 #define IP6CP_IFID      1
 
-struct tok ip6cpopt_values[] = {
+static const struct tok ip6cpopt_values[] = {
         { IP6CP_IFID, "Interface-ID" },
        { 0,              NULL }
 };
@@ -333,7 +328,7 @@ struct tok ip6cpopt_values[] = {
 #define AUTHALG_MSCHAP1        128     /* RFC2433 */
 #define AUTHALG_MSCHAP2        129     /* RFC2795 */
 
-struct tok authalg_values[] = {
+static const struct tok authalg_values[] = {
         { AUTHALG_CHAPMD5, "MD5" },
         { AUTHALG_MSCHAP1, "MS-CHAPv1" },
         { AUTHALG_MSCHAP2, "MS-CHAPv2" },
@@ -358,7 +353,7 @@ struct tok authalg_values[] = {
 #define CALLBACK_X500  4       /* X.500 distinguished name */
 #define CALLBACK_CBCP  6       /* Location is determined during CBCP nego */
 
-struct tok ppp_callback_values[] = {
+static const struct tok ppp_callback_values[] = {
         { CALLBACK_AUTH, "UserAuth" },
         { CALLBACK_DSTR, "DialString" },
         { CALLBACK_LID, "LocalID" },
@@ -375,7 +370,7 @@ struct tok ppp_callback_values[] = {
 #define CHAP_SUCC      3
 #define CHAP_FAIL      4
 
-struct tok chapcode_values[] = {
+static const struct tok chapcode_values[] = {
        { CHAP_CHAL, "Challenge" },
        { CHAP_RESP, "Response" },
        { CHAP_SUCC, "Success" },
@@ -389,7 +384,7 @@ struct tok chapcode_values[] = {
 #define PAP_AACK       2
 #define PAP_ANAK       3
 
-struct tok papcode_values[] = {
+static const struct tok papcode_values[] = {
         { PAP_AREQ, "Auth-Req" },
         { PAP_AACK, "Auth-ACK" },
         { PAP_ANAK, "Auth-NACK" },
@@ -439,7 +434,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
        TCHECK2(*tptr, 2);
 
        code = *tptr++;
-       
+
         printf("%s (0x%02x), id %u, length %u",
                tok2str(cpcodes, "Unknown Opcode",code),
                code,
@@ -459,7 +454,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
         printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4);
 
         if (vflag>1)
-            print_unknown_data(pptr-2,"\n\t",6);
+            print_unknown_data(gndo,pptr-2,"\n\t",6);
 
 
        switch (code) {
@@ -508,7 +503,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
 
                        if (pfunc == NULL) /* catch the above null pointer if unknown CP */
                                break;
+
                        if ((j = (*pfunc)(tptr, len)) == 0)
                                break;
                        x -= j;
@@ -533,7 +528,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
                /* XXX: need to decode Rejected-Information? - hexdump for now */
                 if (len > 6) {
                         printf("\n\t  Rejected Packet");
-                        print_unknown_data(tptr+2,"\n\t    ",len-2);
+                        print_unknown_data(gndo,tptr+2,"\n\t    ",len-2);
                 }
                break;
        case CPCODES_ECHO_REQ:
@@ -547,7 +542,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
                 if (len > 8) {
                         printf("\n\t  -----trailing data-----");
                         TCHECK2(tptr[4], len-8);
-                        print_unknown_data(tptr+4,"\n\t  ",len-8);
+                        print_unknown_data(gndo,tptr+4,"\n\t  ",len-8);
                 }
                break;
        case CPCODES_ID:
@@ -575,7 +570,7 @@ handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
              * original pointer passed to the begin
              * the PPP packet */
                 if (vflag <= 1)
-                    print_unknown_data(pptr-2,"\n\t  ",length+2);
+                    print_unknown_data(gndo,pptr-2,"\n\t  ",length+2);
                break;
        }
        return;
@@ -657,7 +652,7 @@ print_lcp_config_options(const u_char *p, int length)
                    case PPP_SPAP_OLD:
                         break;
                    default:
-                        print_unknown_data(p,"\n\t",len);
+                        print_unknown_data(gndo,p,"\n\t",len);
                    }
                }
                break;
@@ -758,12 +753,12 @@ print_lcp_config_options(const u_char *p, int length)
 #endif
         default:
                 if(vflag<2)
-                        print_unknown_data(&p[2],"\n\t    ",len-2);
+                        print_unknown_data(gndo,&p[2],"\n\t    ",len-2);
                 break;
        }
-         
+
         if (vflag>1)
-                print_unknown_data(&p[2],"\n\t    ",len-2); /* exclude TLV header */
+                print_unknown_data(gndo,&p[2],"\n\t    ",len-2); /* exclude TLV header */
 
        return len;
 
@@ -773,7 +768,7 @@ trunc:
 }
 
 /* ML-PPP*/
-struct tok ppp_ml_flag_values[] = {
+static const struct tok ppp_ml_flag_values[] = {
     { 0x80, "begin" },
     { 0x40, "end" },
     { 0, NULL }
@@ -1041,14 +1036,14 @@ print_ipcp_config_options(const u_char *p, int length)
                         if (len > IPCPOPT_IPCOMP_MINLEN) {
                                 ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN;
                                 p += IPCPOPT_IPCOMP_MINLEN;
-                                
+
                                 printf("\n\t      Suboptions, length %u", ipcomp_subopttotallen);
 
                                 while (ipcomp_subopttotallen >= 2) {
                                         TCHECK2(*p, 2);
                                         ipcomp_subopt = *p;
                                         ipcomp_suboptlen = *(p+1);
-                                        
+
                                         /* sanity check */
                                         if (ipcomp_subopt == 0 ||
                                             ipcomp_suboptlen == 0 )
@@ -1085,11 +1080,11 @@ print_ipcp_config_options(const u_char *p, int length)
                break;
        default:
                 if(vflag<2)
-                        print_unknown_data(&p[2],"\n\t    ",len-2);
+                        print_unknown_data(gndo,&p[2],"\n\t    ",len-2);
                break;
        }
         if (vflag>1)
-                print_unknown_data(&p[2],"\n\t    ",len-2); /* exclude TLV header */
+                print_unknown_data(gndo,&p[2],"\n\t    ",len-2); /* exclude TLV header */
        return len;
 
 invlen:
@@ -1140,11 +1135,11 @@ print_ip6cp_config_options(const u_char *p, int length)
                break;
        default:
                 if(vflag<2)
-                        print_unknown_data(&p[2],"\n\t    ",len-2);
+                        print_unknown_data(gndo,&p[2],"\n\t    ",len-2);
                break;
        }
         if (vflag>1)
-                print_unknown_data(&p[2],"\n\t    ",len-2); /* exclude TLV header */
+                print_unknown_data(gndo,&p[2],"\n\t    ",len-2); /* exclude TLV header */
 
        return len;
 
@@ -1203,11 +1198,11 @@ print_ccp_config_options(const u_char *p, int length)
        case CCPOPT_RESV:
        default:
                 if(vflag<2)
-                        print_unknown_data(&p[2],"\n\t    ",len-2);
+                        print_unknown_data(gndo,&p[2],"\n\t    ",len-2);
                break;
        }
         if (vflag>1)
-                print_unknown_data(&p[2],"\n\t    ",len-2); /* exclude TLV header */
+                print_unknown_data(gndo,&p[2],"\n\t    ",len-2); /* exclude TLV header */
 
        return len;
 
@@ -1249,11 +1244,11 @@ print_bacp_config_options(const u_char *p, int length)
                 break;
        default:
                 if(vflag<2)
-                        print_unknown_data(&p[2],"\n\t    ",len-2);
+                        print_unknown_data(gndo,&p[2],"\n\t    ",len-2);
                break;
        }
         if (vflag>1)
-                print_unknown_data(&p[2],"\n\t    ",len-2); /* exclude TLV header */
+                print_unknown_data(gndo,&p[2],"\n\t    ",len-2); /* exclude TLV header */
 
        return len;
 
@@ -1270,6 +1265,9 @@ ppp_hdlc(const u_char *p, int length)
        int i, proto;
        const void *se;
 
+        if (length <= 0)
+                return;
+
        b = (u_int8_t *)malloc(length);
        if (b == NULL)
                return;
@@ -1293,32 +1291,39 @@ ppp_hdlc(const u_char *p, int length)
 
        se = snapend;
        snapend = t;
+       length = t - b;
 
         /* now lets guess about the payload codepoint format */
+        if (length < 1)
+                goto trunc;
         proto = *b; /* start with a one-octet codepoint guess */
-        
+
         switch (proto) {
         case PPP_IP:
-               ip_print(gndo, b+1, t - b - 1);
+               ip_print(gndo, b+1, length - 1);
                goto cleanup;
 #ifdef INET6
         case PPP_IPV6:
-               ip6_print(gndo, b+1, t - b - 1);
+               ip6_print(gndo, b+1, length - 1);
                goto cleanup;
 #endif
         default: /* no luck - try next guess */
                break;
         }
 
+        if (length < 2)
+                goto trunc;
         proto = EXTRACT_16BITS(b); /* next guess - load two octets */
 
         switch (proto) {
         case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */
+            if (length < 4)
+                goto trunc;
             proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */
-            handle_ppp(proto, b+4, t - b - 4);
+            handle_ppp(proto, b+4, length - 4);
             break;
         default: /* last guess - proto must be a PPP proto-id */
-            handle_ppp(proto, b+2, t - b - 2);
+            handle_ppp(proto, b+2, length - 2);
             break;
         }
 
@@ -1326,6 +1331,12 @@ cleanup:
         snapend = se;
        free(b);
         return;
+
+trunc:
+        snapend = se;
+       free(b);
+       printf("[|ppp]");
+       return;
 }
 
 
@@ -1387,7 +1398,7 @@ handle_ppp(u_int proto, const u_char *p, int length)
                break;
        default:
                printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
-               print_unknown_data(p,"\n\t",length);
+               print_unknown_data(gndo,p,"\n\t",length);
                break;
        }
 }