Ethereal-dev: [Ethereal-dev] Patch to packet-isakmp.c

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Yaniv Kaul <ykaul@xxxxxxxxxxxx>
Date: Mon, 20 Sep 2004 18:55:53 +0300
Please find attached patch ('svn diff' output) to packet-isakmp.c, containing: 1. Fix dissection of Check Point vendor ID version field. The length was wrong. 2. Added dissection of payloads 130 and 131, which were used in early NAT-T drafts (and are still used by MS and others). They are equal to payloads 15 & 16, (NAT-D, NAT-OA), respectively. 3. Added ASN.1 decoding of Certificate requests of type X.509 Certificate - Signature (4)
4. Added ASN.1 decoding of ID of type ID_DER_ASN1_DN (9)

Regards,
Y.
Index: packet-isakmp.c
===================================================================
--- packet-isakmp.c	(revision 12053)
+++ packet-isakmp.c	(working copy)
@@ -41,6 +41,7 @@
 #include <epan/packet.h>
 #include <epan/ipv6-utils.h>
 #include "ipproto.h"
+#include <epan/dissectors/packet-x509if.h>
 
 #define isakmp_min(a, b)  ((a<b) ? a : b)
 
@@ -257,8 +258,6 @@
 #define LOAD_TYPE_PROPOSAL	2	/* payload type for Proposal */
 #define	LOAD_TYPE_TRANSFORM	3	/* payload type for Transform */
 #define NUM_LOAD_TYPES		17
-#define loadtype2str(t)	\
-  ((t < NUM_LOAD_TYPES) ? strfuncs[t].str : "Unknown payload type")
 
 static struct strfunc {
   const char *	str;
@@ -395,13 +394,15 @@
 /* 
 *  Seen in Netscreen. Suppose to be ASCII HeartBeat_Notify - but I don't know the rest yet. I suspect it then proceeds with
 *  8k10, which means every 8K (?), and version 1.0 of the protocol (?). I won't add it to the code, until I know what it really
-*  means. ykaul-at-netvision.net.il
+*  means. ykaul-at-bezeqint.net
 */
 static const guint8 VID_HeartBeat_Notify[VID_LEN] = {0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x5f, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79}; 
 
+static int hf_ike_certificate_authority = -1;
+
 static void
 dissect_payloads(tvbuff_t *tvb, proto_tree *tree, guint8 initial_payload,
-		 int offset, int length)
+		 int offset, int length, packet_info *pinfo)
 {
   guint8 payload, next_payload;
   guint16		payload_length;
@@ -424,12 +425,16 @@
       break;
     if (payload_length >= 4) {	/* XXX = > 4? */
       if (payload < NUM_LOAD_TYPES && strfuncs[payload].func != NULL) {
-        (*strfuncs[payload].func)(tvb, offset + 4, payload_length - 4, ntree,
-				  -1);
+        (*strfuncs[payload].func)(tvb, offset + 4, payload_length - 4, ntree, (int)pinfo);
       }
       else {
-        proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4,
-            "Payload");
+	if (payload == 130)
+		dissect_nat_discovery(tvb, offset + 4, payload_length - 4, ntree, -1);
+	else
+	if (payload == 131)
+		dissect_nat_original_address(tvb, offset + 4, payload_length - 4, ntree, -1);
+	else
+        	proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4, "Payload");
       }
     }
     else {
@@ -540,7 +545,7 @@
 			len, plurality(len, "", "s"));
       }
     } else
-      dissect_payloads(tvb, isakmp_tree, hdr.next_payload, offset, len);
+      dissect_payloads(tvb, isakmp_tree, hdr.next_payload, offset, len, pinfo);
   }
 }
 
@@ -562,7 +567,7 @@
   payload_length = tvb_get_ntohs(tvb, offset + 2);
 
   ti = proto_tree_add_text(tree, tvb, offset, payload_length,
-            "%s payload", loadtype2str(payload));
+            "%s payload", payloadtype2str(payload));
   ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
 
   proto_tree_add_text(ntree, tvb, offset, 1,
@@ -576,8 +581,8 @@
 }
 
 static void
-dissect_sa(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
-    int unused _U_)
+dissect_sa(tvbuff_t *tvb, int offset, int length, proto_tree *tree, 
+   int unused _U_)
 {
   guint32		doi;
   guint32		situation;
@@ -610,7 +615,7 @@
     offset += 4;
     length -= 4;
 
-    dissect_payloads(tvb, tree, LOAD_TYPE_PROPOSAL, offset, length);
+    dissect_payloads(tvb, tree, LOAD_TYPE_PROPOSAL, offset, length, (packet_info *)unused);
   } else {
     /* Unknown */
     proto_tree_add_text(tree, tvb, offset, length,
@@ -788,6 +793,7 @@
   guint8		id_type;
   guint8		protocol_id;
   guint16		port;
+	packet_info *pinfo = (packet_info *)unused;
 
   id_type = tvb_get_guint8(tvb, offset);
   proto_tree_add_text(tree, tvb, offset, 1,
@@ -833,6 +839,9 @@
 			  ip_to_str(tvb_get_ptr(tvb, offset, 4)),
 			  ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
       break;
+	case 9:
+		dissect_x509if_Name(FALSE, tvb, offset, pinfo, tree, hf_ike_certificate_authority);
+		break;
     default:
       proto_tree_add_text(tree, tvb, offset, length, "Identification Data");
       break;
@@ -860,7 +869,7 @@
     int unused _U_)
 {
   guint8		cert_type;
-
+	packet_info *pinfo = (packet_info *)unused;
   cert_type = tvb_get_guint8(tvb, offset);
   proto_tree_add_text(tree, tvb, offset, 1,
 		      "Certificate type: %u - %s",
@@ -868,7 +877,14 @@
   offset += 1;
   length -= 1;
 
-  proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority");
+  if (length) {
+	if (cert_type == 4)
+		dissect_x509if_Name(FALSE, tvb, offset, pinfo, tree, hf_ike_certificate_authority);
+	else
+		proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority");
+  }
+  else
+    proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority (empty)");
 }
 
 static void
@@ -1016,7 +1032,7 @@
 	}
 	offset += sizeof(CPproduct);
 	CPversion = tvb_get_ntohl(tvb, offset);
-	pt = proto_tree_add_text(ntree, tvb, offset, length, "Version: ");
+	pt = proto_tree_add_text(ntree, tvb, offset, sizeof(CPversion), "Version: ");
 	switch (CPversion) {
 		case 2: proto_item_append_text(pt, "4.1");
 			break;
@@ -1039,6 +1055,8 @@
 		default: proto_item_append_text(pt, " Unknown CP version!");
 			break;
 	}
+	offset += sizeof(CPversion);
+	proto_tree_add_text(ntree, tvb, offset, length - VID_CP_LEN - sizeof(CPproduct) - sizeof(CPversion),"Check Point Vendor ID parameters"); 
   }
   else
   if (memcmp(pVID, VID_CYBERGUARD, isakmp_min(VID_LEN, length)) == 0)
@@ -1312,6 +1330,10 @@
     return strfuncs[type].str;
   if (type < 128)
     return "RESERVED";
+  if (type == 130)
+	return "NAT-D (draft-ietf-ipsec-nat-t-ike-01 to 04)";
+  if (type == 131)
+	return "NAT-OA (draft-ietf-ipsec-nat-t-ike-01 to 04)";
   return "Private USE";
 }
 
@@ -1691,10 +1713,11 @@
 void
 proto_register_isakmp(void)
 {
-/*  static hf_register_info hf[] = {
-    { &variable,
-    { "Name",           "isakmp.abbreviation", TYPE, VALS_POINTER }},
-  };*/
+	static hf_register_info hf[] = {
+		{ &hf_ike_certificate_authority,
+		{ "Certificate Authority Distinguished Name", "ike.cert_authority_dn", FT_UINT32, BASE_DEC, NULL, 0x0, "Certificate Authority Distinguished Name", HFILL }
+		},
+	};
   static gint *ett[] = {
     &ett_isakmp,
     &ett_isakmp_flags,
@@ -1703,7 +1726,7 @@
 
   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_field_array(proto_isakmp, hf, array_length(hf));
   proto_register_subtree_array(ett, array_length(ett));
 
   register_dissector("isakmp", dissect_isakmp, proto_isakmp);