]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-rsvp.c
Pointers into packet data should usually be pointers to unsigned 1-byte
[tcpdump] / print-rsvp.c
index aa64295195cc77662f39a958ccca6c59d018a373..98c9e1087a1fa8d7d95141849e55ad19b15a5ba9 100644 (file)
@@ -15,7 +15,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.31 2004-09-16 06:34:01 hannes Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.37 2005-07-11 20:15:33 hannes Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -348,10 +348,12 @@ static struct tok rsvp_obj_prop_tlv_values[] = {
 
 #define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24
 #define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY  25
+#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 125
 
 static struct tok rsvp_obj_error_code_values[] = {
     { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" },
     { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY,  "Notify Error" },
+    { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" },
     { 0, NULL}
 };
 
@@ -369,6 +371,17 @@ static struct tok rsvp_obj_error_code_routing_values[] = {
     { 0, NULL}
 };
 
+static struct tok rsvp_obj_error_code_diffserv_te_values[] = {
+    { 1,                      "Unexpected CLASSTYPE object" },
+    { 2,                      "Unsupported Class-Type" },
+    { 3,                      "Invalid Class-Type value" },
+    { 4,                      "Class-Type and setup priority do not form a configured TE-Class" },
+    { 5,                      "Class-Type and holding priority do not form a configured TE-Class" },
+    { 6,                      "Inconsistency between signaled PSC and signaled Class-Type" },
+    { 7,                      "Inconsistency between signaled PHBs and signaled Class-Type" },
+    { 0, NULL}
+};
+
 #define FALSE 0
 #define TRUE  1
 
@@ -535,7 +548,7 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
     } bw;
     u_int8_t namelen;
 
-    while(tlen>0) {
+    while(tlen>=sizeof(struct rsvp_object_header)) {
         /* did we capture enough for fully decoding the object header ? */
         if (!TTEST2(*tptr, sizeof(struct rsvp_object_header)))
             goto trunc;
@@ -544,8 +557,12 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
         rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length);
         rsvp_obj_ctype=rsvp_obj_header->ctype;
 
-        if(rsvp_obj_len % 4 || rsvp_obj_len < sizeof(struct rsvp_object_header)) {
-            printf("ERROR: object header too short %u < %lu", rsvp_obj_len,
+        if(rsvp_obj_len % 4) {
+            printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len);
+            return -1;
+        }
+        if(rsvp_obj_len < sizeof(struct rsvp_object_header)) {
+            printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len,
                    (unsigned long)sizeof(const struct rsvp_object_header));
             return -1;
         }
@@ -569,6 +586,11 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                rsvp_obj_ctype,
                rsvp_obj_len);
     
+        if(tlen < rsvp_obj_len) {
+            printf("%sERROR: object goes past end of objects TLV", ident);
+            return -1;
+        }
+
         obj_tptr=tptr+sizeof(struct rsvp_object_header);
         obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header);
 
@@ -586,7 +608,7 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                 printf("%s  IPv4 DestAddress: %s, Protocol ID: 0x%02x",
                        ident,
                        ipaddr_string(obj_tptr),
-                       *(obj_tptr+4));
+                       *(obj_tptr+sizeof(struct in_addr)));
                 printf("%s  Flags: [0x%02x], DestPort %u",
                        ident,
                        *(obj_tptr+5),
@@ -601,11 +623,11 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                 printf("%s  IPv6 DestAddress: %s, Protocol ID: 0x%02x",
                        ident,
                        ip6addr_string(obj_tptr),
-                       *(obj_tptr+16));
+                       *(obj_tptr+sizeof(struct in6_addr)));
                 printf("%s  Flags: [0x%02x], DestPort %u",
                        ident,
-                       *(obj_tptr+17),
-                       EXTRACT_16BITS(obj_tptr+18));
+                       *(obj_tptr+sizeof(struct in6_addr)+1),
+                       EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2));
                 obj_tlen-=20;
                 obj_tptr+=20;                
                 break;
@@ -641,23 +663,23 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
         case RSVP_OBJ_CONFIRM:
             switch(rsvp_obj_ctype) {
             case RSVP_CTYPE_IPV4:
-                if (obj_tlen < 4)
+                if (obj_tlen < sizeof(struct in_addr))
                     return -1;
                 printf("%s  IPv4 Receiver Address: %s",
                        ident,
                        ipaddr_string(obj_tptr));
-                obj_tlen-=4;
-                obj_tptr+=4;                
+                obj_tlen-=sizeof(struct in_addr);
+                obj_tptr+=sizeof(struct in_addr);                
                 break;
 #ifdef INET6
             case RSVP_CTYPE_IPV6:
-                if (obj_tlen < 16)
+                if (obj_tlen < sizeof(struct in6_addr))
                     return -1;
                 printf("%s  IPv6 Receiver Address: %s",
                        ident,
                        ip6addr_string(obj_tptr));
-                obj_tlen-=16;
-                obj_tptr+=16;                
+                obj_tlen-=sizeof(struct in6_addr);
+                obj_tptr+=sizeof(struct in6_addr);                
                 break;
 #endif
             default:
@@ -668,23 +690,23 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
         case RSVP_OBJ_NOTIFY_REQ:
             switch(rsvp_obj_ctype) {
             case RSVP_CTYPE_IPV4:
-                if (obj_tlen < 4)
+                if (obj_tlen < sizeof(struct in_addr))
                     return -1;
                 printf("%s  IPv4 Notify Node Address: %s",
                        ident,
                        ipaddr_string(obj_tptr));
-                obj_tlen-=4;
-                obj_tptr+=4;                
+                obj_tlen-=sizeof(struct in_addr);
+                obj_tptr+=sizeof(struct in_addr);                
                 break;
 #ifdef INET6
             case RSVP_CTYPE_IPV6:
-                if (obj_tlen < 16)
+                if (obj_tlen < sizeof(struct in6_addr))
                     return-1;
                 printf("%s  IPv6 Notify Node Address: %s",
                        ident,
                        ip6addr_string(obj_tptr));
-                obj_tlen-=16;
-                obj_tptr+=16;                
+                obj_tlen-=sizeof(struct in6_addr);
+                obj_tptr+=sizeof(struct in6_addr);                
                 break;
 #endif
             default:
@@ -870,11 +892,18 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
             switch(rsvp_obj_ctype) {
             case RSVP_CTYPE_IPV4:
                 while(obj_tlen >= 4 ) {
-                    printf("%s  Subobject Type: %s",
+                    printf("%s  Subobject Type: %s, length %u",
                            ident,
                            tok2str(rsvp_obj_xro_values,
                                    "Unknown %u",
-                                   RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)));                
+                                   RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)),
+                           *(obj_tptr+1));                
+
+                    if (*(obj_tptr+1) == 0) { /* prevent infinite loops */
+                        printf("%s  ERROR: zero length ERO subtype",ident);
+                        break;
+                    }
+
                     switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) {
                     case RSVP_OBJ_XRO_IPV4:
                         printf(", %s, %s/%u, Flags: [%s]",
@@ -919,8 +948,8 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                     return-1;
                 printf("%s  Restart  Time: %ums, Recovery Time: %ums",
                        ident,
-                       EXTRACT_16BITS(obj_tptr),
-                       EXTRACT_16BITS(obj_tptr+4));
+                       EXTRACT_32BITS(obj_tptr),
+                       EXTRACT_32BITS(obj_tptr+4));
                 obj_tlen-=8;
                 obj_tptr+=8;
                 break;
@@ -1182,6 +1211,11 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                            tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
                            error_value);
                     break;
+                case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE:
+                    printf(", Error Value: %s (%u)",
+                           tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value),
+                           error_value);
+                    break;
                 default:
                     printf(", Unknown Error Value (%u)", error_value);
                     break;
@@ -1243,6 +1277,8 @@ rsvp_obj_print (const u_char *tptr, const char *ident, u_int tlen) {
                            *(obj_tptr+1));
                     if (obj_tlen < *(obj_tptr+1))
                         return-1;
+                    if (*(obj_tptr+1) < 2)
+                        return -1;
                     print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2);
                     obj_tlen-=*(obj_tptr+1);
                     obj_tptr+=*(obj_tptr+1);
@@ -1397,6 +1433,12 @@ rsvp_print(register const u_char *pptr, register u_int len) {
                 return;
             }
 
+            if (tlen < subtlen) {
+                printf("ERROR: common header too large %u > %u", subtlen,
+                       tlen);
+                return;
+            }
+
             subtptr+=sizeof(const struct rsvp_common_header);
             subtlen-=sizeof(const struct rsvp_common_header);