Add an additional "protocol index" argument to "{old_}dissector_add()",
[obnox/wireshark/wip.git] / packet-isakmp.c
index f62d5e3cc5fa18cf1dca8dfce48bebda11bf663e..efa111001d89a308de10ac53781debcf83f22b30 100644 (file)
@@ -3,7 +3,7 @@
  * (ISAKMP) (RFC 2408)
  * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
  *
- * $Id: packet-isakmp.c,v 1.24 2000/08/07 03:20:45 guy Exp $
+ * $Id: packet-isakmp.c,v 1.34 2001/01/09 06:31:37 guy Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #endif
 
 #include <glib.h>
-#include "packet.h"
 
 #ifdef NEED_SNPRINTF_H
-# ifdef HAVE_STDARG_H
-#  include <stdarg.h>
-# else
-#  include <varargs.h>
-# endif
 # include "snprintf.h"
 #endif
 
+#include "packet.h"
+
 static int proto_isakmp = -1;
 
 static gint ett_isakmp = -1;
@@ -95,7 +91,7 @@ static const char *p1_atttypestr[NUM_P1_ATT_TYPES] = {
   "Group-Order"
 };
 
-#define NUM_ATT_TYPES  10
+#define NUM_ATT_TYPES  11
 #define atttype2str(t) \
   ((t < NUM_ATT_TYPES) ? atttypestr[t] : "UNKNOWN-ATTRIBUTE-TYPE")
 
@@ -109,7 +105,8 @@ static const char *atttypestr[NUM_ATT_TYPES] = {
   "Key-Length",
   "Key-Rounds",
   "Compress-Dictinary-Size",
-  "Compress-Private-Algorithm"
+  "Compress-Private-Algorithm",
+  "ECN Tunnel"
 };
 
 #define NUM_TRANS_TYPES        2
@@ -121,7 +118,7 @@ static const char *transtypestr[NUM_TRANS_TYPES] = {
   "KEY_IKE"
 };
 
-#define NUM_AH_TRANS_TYPES     5
+#define NUM_AH_TRANS_TYPES     8
 #define ah_trans2str(t)                \
   ((t < NUM_AH_TRANS_TYPES) ? ah_transtypestr[t] : "UNKNOWN-AH-TRANS-TYPE")
 
@@ -130,10 +127,13 @@ static const char *ah_transtypestr[NUM_AH_TRANS_TYPES] = {
   "RESERVED",
   "MD5",
   "SHA",
-  "DES"
+  "DES",
+  "SHA2-256",
+  "SHA2-384",
+  "SHA2-512"
 };
 
-#define NUM_ESP_TRANS_TYPES    12
+#define NUM_ESP_TRANS_TYPES    13
 #define esp_trans2str(t)       \
   ((t < NUM_ESP_TRANS_TYPES) ? esp_transtypestr[t] : "UNKNOWN-ESP-TRANS-TYPE")
 
@@ -149,7 +149,8 @@ static const char *esp_transtypestr[NUM_ESP_TRANS_TYPES] = {
   "3IDEA",
   "DES-IV32",
   "RC4",
-  "NULL"
+  "NULL",
+  "AES"
 };
 
 #define NUM_ID_TYPES   12
@@ -354,9 +355,11 @@ dissect_isakmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   
   struct isakmp_hdr *  hdr = (struct isakmp_hdr *)(pd + offset);
   guint32              len;
+
+  OLD_CHECK_DISPLAY_AS_DATA(proto_isakmp, pd, offset, fd, tree);
   
   if (check_col(fd, COL_PROTOCOL))
-    col_add_str(fd, COL_PROTOCOL, "ISAKMP");
+    col_set_str(fd, COL_PROTOCOL, "ISAKMP");
   
   len = pntohl(&hdr->length);
   
@@ -412,7 +415,9 @@ dissect_isakmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       offset += sizeof(hdr->flags);
     }
 
-    proto_tree_add_text(isakmp_tree, NullTVB, offset, sizeof(hdr->message_id), "Message ID");
+    proto_tree_add_text(isakmp_tree, NullTVB, offset, sizeof(hdr->message_id),
+        "Message ID: 0x%02x%02x%02x%02x", hdr->message_id[0],
+        hdr->message_id[1], hdr->message_id[2], hdr->message_id[3]);
     offset += sizeof(hdr->message_id);
     
     proto_tree_add_text(isakmp_tree, NullTVB, offset, sizeof(hdr->length),
@@ -549,6 +554,7 @@ dissect_transform(const u_char *pd, int offset, frame_data *fd,
 
   struct trans_hdr *   hdr     = (struct trans_hdr *)(pd + offset);
   guint16              length  = pntohs(&hdr->length);
+  int                   slength = length;
   proto_item *         ti      = proto_tree_add_text(tree, NullTVB, offset, length, "Transform payload");
   proto_tree *         ntree;
 
@@ -587,8 +593,8 @@ dissect_transform(const u_char *pd, int offset, frame_data *fd,
   }
   offset += sizeof(hdr->transform_id) + sizeof(hdr->reserved2);
   
-  length -= sizeof(*hdr);
-  while (length) {
+  slength -= sizeof(*hdr);
+  while (slength>0) {
     const char *str = NULL;
     int ike_phase1 = 0;
     guint16 type    = pntohs(pd + offset) & 0x7fff;
@@ -608,7 +614,7 @@ dissect_transform(const u_char *pd, int offset, frame_data *fd,
                          str, type,
                          value2str(ike_phase1, type, val_len), val_len);
       offset += 4;
-      length -= 4;
+      slength -= 4;
     }
     else {
       guint16  pack_len = 4 + val_len;
@@ -618,8 +624,15 @@ dissect_transform(const u_char *pd, int offset, frame_data *fd,
                          str, type,
                          num2str(pd + offset + 4, val_len));
       offset += pack_len;
-      length -= pack_len;
+      slength -= pack_len;
+    }
+#if 0 /* the last byte will fail with this test */
+    if (!IS_DATA_IN_FRAME(offset)) {
+           proto_tree_add_text(ntree, NullTVB, 0, 0,
+                           "Bad Offset: %u", offset);
+           return;
     }
+#endif
   }
 
   if (hdr->next_payload < NUM_LOAD_TYPES) {
@@ -932,7 +945,7 @@ dissect_notif(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
     offset += hdr->spi_size;
   }
 
-  if (length - sizeof(*hdr)) {
+  if (((int)length - sizeof(*hdr)) > 0) {
     proto_tree_add_text(ntree, NullTVB, offset, length - sizeof(*hdr) - hdr->spi_size,
                        "Notification Data");
     offset += (length - sizeof(*hdr) - hdr->spi_size);
@@ -1040,6 +1053,7 @@ dissect_config(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
 
   struct cfg_hdr *     hdr      = (struct cfg_hdr *)(pd + offset);
   guint16              length   = pntohs(&hdr->length);
+  int                   slength  = length;
   proto_item *         ti       = proto_tree_add_text(tree, NullTVB, offset, length, "Attribute payload");
   proto_tree *         ntree;
 
@@ -1062,9 +1076,9 @@ dissect_config(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
   proto_tree_add_text(ntree, NullTVB, offset, sizeof(hdr->identifier),
                       "Identifier: %u", pntohs(&hdr->identifier));
   offset += sizeof(hdr->identifier);
-  length -= sizeof(*hdr);
+  slength -= sizeof(*hdr);
   
-  while(length) {
+  while(slength>0) {
     guint16 type = pntohs(pd + offset) & 0x7fff;
     guint16 val_len = pntohs(pd + offset + 2);
     
@@ -1072,7 +1086,7 @@ dissect_config(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       proto_tree_add_text(ntree, NullTVB, offset, 4,
                          "%s (%u)",cfgattrident2str(type),val_len);
       offset += 4;
-      length -= 4;
+      slength -= 4;
     }
     else {
       guint pack_len = 4 + val_len;
@@ -1080,7 +1094,7 @@ dissect_config(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
       proto_tree_add_text(ntree, NullTVB, offset, 4,
                          "%s (%se)", cfgattrident2str(type), num2str(pd + offset + 4, val_len));
       offset += pack_len;
-      length -= pack_len;
+      slength -= pack_len;
     }
   }
 
@@ -1249,6 +1263,9 @@ value2str(int ike_p1, guint16 att_type, guint16 value) {
         case 2:  return "HMAC-SHA";
         case 3:  return "DES-MAC";
         case 4:  return "KPDK";
+       case 5:  return "HMAC-SHA2-256";
+       case 6:  return "HMAC-SHA2-384";
+       case 7:  return "HMAC-SHA2-512";
         default: return "UNKNOWN-AUTHENTICATION-VALUE";
       }
     case 6:
@@ -1270,6 +1287,7 @@ value2str(int ike_p1, guint16 att_type, guint16 value) {
           case 4:  return "RC5-R16-B64-CBC";
           case 5:  return "3DES-CBC";
           case 6:  return "CAST-CBC";
+         case 7:  return "AES-CBC";
           default: return "UNKNOWN-ENCRYPTION-ALG";
         }
       case 2:
@@ -1277,6 +1295,9 @@ value2str(int ike_p1, guint16 att_type, guint16 value) {
           case 1:  return "MD5";
           case 2:  return "SHA";
           case 3:  return "TIGER";
+         case 4:  return "SHA2-256";
+         case 5:  return "SHA2-384";
+         case 6:  return "SHA2-512";
           default: return "UNKNOWN-HASH-ALG";
         }
       case 3:
@@ -1424,7 +1445,8 @@ proto_register_isakmp(void)
                &ett_isakmp_payload,
        };
 
-        proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol", "isakmp");
+        proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol",
+                                              "ISAKMP", "isakmp");
  /*       proto_register_field_array(proto_isakmp, hf, array_length(hf));*/
        proto_register_subtree_array(ett, array_length(ett));
 }
@@ -1432,5 +1454,6 @@ proto_register_isakmp(void)
 void
 proto_reg_handoff_isakmp(void)
 {
-       old_dissector_add("udp.port", UDP_PORT_ISAKMP, dissect_isakmp);
+       old_dissector_add("udp.port", UDP_PORT_ISAKMP, dissect_isakmp,
+           proto_isakmp);
 }