c1d4de18b19877b899745e84b628c64935778edb
[obnox/wireshark/wip.git] / epan / dissectors / packet-isakmp.c
1 /* packet-isakmp.c
2  * Routines for the Internet Security Association and Key Management Protocol
3  * (ISAKMP) (RFC 2408) and the Internet IP Security Domain of Interpretation
4  * for ISAKMP (RFC 2407)
5  * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
6  *
7  * Added routines for the Internet Key Exchange (IKEv2) Protocol
8  * (draft-ietf-ipsec-ikev2-17.txt)
9  * Shoichi Sakane <sakane@tanu.org>
10  *
11  * Added routines for RFC3947 Negotiation of NAT-Traversal in the IKE
12  *   ronnie sahlberg
13  *
14  * 04/2009 Added routines for decryption of IKEv2 Encrypted Payload
15  *   Naoyoshi Ueda <piyomaru3141@gmail.com>
16  *
17  * $Id$
18  *
19  * Wireshark - Network traffic analyzer
20  * By Gerald Combs <gerald@wireshark.org>
21  * Copyright 1998 Gerald Combs
22  *
23  * This program is free software; you can redistribute it and/or
24  * modify it under the terms of the GNU General Public License
25  * as published by the Free Software Foundation; either version 2
26  * of the License, or (at your option) any later version.
27  *
28  * This program is distributed in the hope that it will be useful,
29  * but WITHOUT ANY WARRANTY; without even the implied warranty of
30  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
31  * GNU General Public License for more details.
32  *
33  * You should have received a copy of the GNU General Public License
34  * along with this program; if not, write to the Free Software
35  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
36  *
37  * References:
38  * IKEv2 http://www.ietf.org/rfc/rfc4306.txt?number=4306
39  * http://www.iana.org/assignments/ikev2-parameters
40  */
41
42 #ifdef HAVE_CONFIG_H
43 # include "config.h"
44 #endif
45
46 #include <stdio.h>
47 #include <string.h>
48
49 #include <glib.h>
50
51 #ifdef HAVE_LIBGCRYPT
52 #include <gcrypt.h>
53 #include <epan/strutil.h>
54 #include <wsutil/file_util.h>
55 #include <epan/uat.h>
56 #endif
57
58 #include <epan/proto.h>
59 #include <epan/packet.h>
60 #include <epan/ipproto.h>
61 #include <epan/asn1.h>
62 #include <epan/reassemble.h>
63 #include <epan/dissectors/packet-x509if.h>
64 #include <epan/dissectors/packet-x509af.h>
65 #include <epan/dissectors/packet-isakmp.h>
66 #include <epan/prefs.h>
67 #include <epan/expert.h>
68
69 #define isakmp_min(a, b)  ((a<b) ? a : b)
70
71 #define ARLEN(a) (sizeof(a)/sizeof(a[0]))
72
73 static int proto_isakmp = -1;
74 static int hf_isakmp_certificate_authority = -1;
75 static int hf_isakmp_v2_certificate_authority = -1;
76 static int hf_isakmp_nat_keepalive = -1;
77 static int hf_isakmp_nat_hash = -1;
78 static int hf_isakmp_nat_original_address_ipv6 = -1;
79 static int hf_isakmp_nat_original_address_ipv4 = -1;
80
81 static int hf_isakmp_icookie         = -1;
82 static int hf_isakmp_rcookie         = -1;
83 static int hf_isakmp_nextpayload     = -1;
84 static int hf_isakmp_version         = -1;
85 static int hf_isakmp_exchangetype    = -1;
86 static int hf_isakmp_flags           = -1;
87 static int hf_isakmp_flag_e          = -1;
88 static int hf_isakmp_flag_c          = -1;
89 static int hf_isakmp_flag_a          = -1;
90 static int hf_isakmp_flag_i          = -1;
91 static int hf_isakmp_flag_v          = -1;
92 static int hf_isakmp_flag_r          = -1;
93 static int hf_isakmp_messageid       = -1;
94 static int hf_isakmp_length          = -1;
95 static int hf_isakmp_payloadlen      = -1;
96 static int hf_isakmp_doi             = -1;
97 static int hf_isakmp_sa_situation    = -1;
98 static int hf_isakmp_prop_number     = -1;
99 static int hf_isakmp_spisize         = -1;
100 static int hf_isakmp_prop_transforms = -1;
101 static int hf_isakmp_trans_number    = -1;
102 static int hf_isakmp_trans_id        = -1;
103 static int hf_isakmp_id_type_v1      = -1;
104 static int hf_isakmp_id_type_v2      = -1;
105 static int hf_isakmp_protoid         = -1;
106 static int hf_isakmp_id_port         = -1;
107 static int hf_isakmp_cert_encoding   = -1;
108 static int hf_isakmp_certreq_type    = -1;
109 static int hf_isakmp_certificate     = -1;
110 static int hf_isakmp_notify_msgtype  = -1;
111 static int hf_isakmp_num_spis        = -1;
112
113 static int hf_isakmp_fragments = -1;
114 static int hf_isakmp_fragment = -1;
115 static int hf_isakmp_fragment_overlap = -1;
116 static int hf_isakmp_fragment_overlap_conflicts = -1;
117 static int hf_isakmp_fragment_multiple_tails = -1;
118 static int hf_isakmp_fragment_too_long_fragment = -1;
119 static int hf_isakmp_fragment_error = -1;
120 static int hf_isakmp_reassembled_in = -1;
121 static int hf_isakmp_reassembled_length = -1;
122
123 static int hf_isakmp_cisco_frag_packetid      = -1;
124 static int hf_isakmp_cisco_frag_seq     = -1;
125 static int hf_isakmp_cisco_frag_last    = -1;
126
127 static int hf_isakmp_cfg_type_v1 = -1;
128 static int hf_isakmp_cfg_identifier = -1;
129 static int hf_isakmp_cfg_type_v2 = -1;
130 static int hf_isakmp_cfg_attr_type_v1 = -1;
131 static int hf_isakmp_cfg_attr_type_v2 = -1;
132 static int hf_isakmp_cfg_attr_length = -1;
133 static int hf_isakmp_cfg_attr_value = -1;
134
135 static int hf_isakmp_cfg_attr_internal_ip4_address = -1;
136 static int hf_isakmp_cfg_attr_internal_ip4_netmask = -1;
137 static int hf_isakmp_cfg_attr_internal_ip4_dns = -1;
138 static int hf_isakmp_cfg_attr_internal_ip4_nbns = -1;
139 static int hf_isakmp_cfg_attr_internal_address_expiry = -1;
140 static int hf_isakmp_cfg_attr_internal_ip4_dhcp = -1;
141 static int hf_isakmp_cfg_attr_application_version = -1;
142 static int hf_isakmp_cfg_attr_internal_ip6_address = -1;
143 static int hf_isakmp_cfg_attr_internal_ip6_netmask = -1;
144 static int hf_isakmp_cfg_attr_internal_ip6_dns = -1;
145 static int hf_isakmp_cfg_attr_internal_ip6_nbns = -1;
146 static int hf_isakmp_cfg_attr_internal_ip6_dhcp = -1;
147 static int hf_isakmp_cfg_attr_internal_ip4_subnet_ip = -1;
148 static int hf_isakmp_cfg_attr_internal_ip4_subnet_netmask = -1;
149 static int hf_isakmp_cfg_attr_xauth_type  = -1;
150 static int hf_isakmp_cfg_attr_xauth_user_name = -1;
151 static int hf_isakmp_cfg_attr_xauth_user_password = -1;
152 static int hf_isakmp_cfg_attr_xauth_passcode = -1;
153 static int hf_isakmp_cfg_attr_xauth_message = -1;
154 static int hf_isakmp_cfg_attr_xauth_challenge = -1;
155 static int hf_isakmp_cfg_attr_xauth_domain = -1;
156 static int hf_isakmp_cfg_attr_xauth_status = -1;
157 static int hf_isakmp_cfg_attr_xauth_next_pin = -1;
158 static int hf_isakmp_cfg_attr_xauth_answer = -1;
159 static int hf_isakmp_cfg_attr_unity_banner = -1;
160
161 static gint ett_isakmp = -1;
162 static gint ett_isakmp_flags = -1;
163 static gint ett_isakmp_payload = -1;
164 static gint ett_isakmp_fragment = -1;
165 static gint ett_isakmp_fragments = -1;
166 static gint ett_isakmp_cfg_attr = -1;
167 #ifdef HAVE_LIBGCRYPT
168 /* For decrypted IKEv2 Encrypted payload*/
169 static gint ett_isakmp_decrypted_data = -1;
170 static gint ett_isakmp_decrypted_payloads = -1;
171 #endif /* HAVE_LIBGCRYPT */
172
173 static dissector_handle_t eap_handle = NULL;
174
175 static GHashTable *isakmp_fragment_table = NULL;
176 static GHashTable *isakmp_reassembled_table = NULL;
177
178 static const fragment_items isakmp_frag_items = {
179   /* Fragment subtrees */
180   &ett_isakmp_fragment,
181   &ett_isakmp_fragments,
182   /* Fragment fields */
183   &hf_isakmp_fragments,
184   &hf_isakmp_fragment,
185   &hf_isakmp_fragment_overlap,
186   &hf_isakmp_fragment_overlap_conflicts,
187   &hf_isakmp_fragment_multiple_tails,
188   &hf_isakmp_fragment_too_long_fragment,
189   &hf_isakmp_fragment_error,
190   /* Reassembled in field */
191   &hf_isakmp_reassembled_in,
192   /* Reassembled length field */
193   &hf_isakmp_reassembled_length,
194   /* Tag */
195   "Message fragments"
196 };
197 /* IKE port number assigned by IANA */
198 #define UDP_PORT_ISAKMP 500
199 #define TCP_PORT_ISAKMP 500
200
201 /*
202  * Identifier Type
203  *   RFC2407 for IKEv1
204  *   RFC3554 for ID_LIST
205  *   RFC4306 for IKEv2
206  *   RFC4595 for ID_FC_NAME 
207  */
208 #define IKE_ID_IPV4_ADDR                1
209 #define IKE_ID_FQDN                     2
210 #define IKE_ID_USER_FQDN                3
211 #define IKE_ID_IPV4_ADDR_SUBNET         4
212 #define IKE_ID_IPV6_ADDR                5
213 #define IKE_ID_IPV6_ADDR_SUBNET         6
214 #define IKE_ID_IPV4_ADDR_RANGE          7
215 #define IKE_ID_IPV6_ADDR_RANGE          8
216 #define IKE_ID_DER_ASN1_DN              9
217 #define IKE_ID_DER_ASN1_GN              10
218 #define IKE_ID_KEY_ID                   11
219 #define IKE_ID_LIST                     12
220 #define IKE_ID_FC_NAME                  12
221 #define IKE_ID_RFC822_ADDR              3
222 /*
223  * Traffic Selector Type
224  *   Not in use for IKEv1
225  */
226 #define IKEV2_TS_IPV4_ADDR_RANGE        7
227 #define IKEV2_TS_IPV6_ADDR_RANGE        8
228
229 /*
230  * Configuration Payload Attribute Types
231  *   draft-ietf-ipsec-isakmp-mode-cfg-05.txt for IKEv1
232  *   draft-ietf-ipsec-isakmp-xauth-06.txt and draft-beaulieu-ike-xauth-02.txt for XAUTH
233  *   RFC4306 for IKEv2
234  *   RFC-ietf-ipsecme-ikev2-ipv6-config-03.txt for INTERNAL_IP6_LINK and INTERNAL_IP6_PREFIX
235  */
236 #define INTERNAL_IP4_ADDRESS            1       
237 #define INTERNAL_IP4_NETMASK            2       
238 #define INTERNAL_IP4_DNS                3       
239 #define INTERNAL_IP4_NBNS               4       
240 #define INTERNAL_ADDRESS_EXPIRY         5       
241 #define INTERNAL_IP4_DHCP               6
242 #define APPLICATION_VERSION             7
243 #define INTERNAL_IP6_ADDRESS            8
244 #define INTERNAL_IP6_NETMASK            9
245 #define INTERNAL_IP6_DNS                10
246 #define INTERNAL_IP6_NBNS               11
247 #define INTERNAL_IP6_DHCP               12
248 #define INTERNAL_IP4_SUBNET             13
249 #define SUPPORTED_ATTRIBUTES            14
250 #define INTERNAL_IP6_SUBNET             15
251 #define MIP6_HOME_PREFIX                16
252 #define INTERNAL_IP6_LINK               17
253 #define INTERNAL_IP6_PREFIX             18
254 /* checkpoint configuration attributes */
255 #define CHKPT_DEF_DOMAIN                16387
256 #define CHKPT_MAC_ADDRESS               16388
257 #define CHKPT_MARCIPAN_REASON_CODE      16389
258 #define CHKPT_UNKNOWN1                  16400
259 #define CHKPT_UNKNOWN2                  16401
260 #define CHKPT_UNKNOWN3                  16402
261 /* XAUTH configuration attributes */
262 #define XAUTH_TYPE                      16520
263 #define XAUTH_USER_NAME                 16521
264 #define XAUTH_USER_PASSWORD             16522
265 #define XAUTH_PASSCODE                  16523
266 #define XAUTH_MESSAGE                   16524
267 #define XAUTH_CHALLENGE                 16525
268 #define XAUTH_DOMAIN                    16526
269 #define XAUTH_STATUS                    16527
270 #define XAUTH_NEXT_PIN                  16528   
271 #define XAUTH_ANSWER                    16529
272 /* unity (CISCO) configuration attributes */
273 #define UNITY_BANNER                    28672   
274 #define UNITY_SAVE_PASSWD               28673   
275 #define UNITY_DEF_DOMAIN                28674   
276 #define UNITY_SPLIT_DOMAIN              28675   
277 #define UNITY_SPLIT_INCLUDE             28676   
278 #define UNITY_NATT_PORT                 28677   
279 #define UNITY_SPLIT_EXCLUDE             28678   
280 #define UNITY_PFS                       28679   
281 #define UNITY_FW_TYPE                   28680   
282 #define UNITY_BACKUP_SERVERS            28681   
283 #define UNITY_DDNS_HOSTNAME             28682   
284
285 static const value_string frag_last_vals[] = {
286   { 0,  "More fragments" },
287   { 1,  "Last fragment" },
288   { 0,  NULL },
289 };
290
291 static const value_string vs_proto[] = {
292   { 0,  "RESERVED" },
293   { 1,  "ISAKMP" },
294   { 2,  "IPSEC_AH" },
295   { 3,  "IPSEC_ESP" },
296   { 4,  "IPCOMP" },
297   { 0,  NULL },
298 };
299
300 static const range_string vs_v1_cfgtype[] = {
301   { 0,0,        "Reserved" },
302   { 1,1,        "ISAKMP_CFG_REQUEST" },
303   { 2,2,        "ISAKMP_CFG_REPLY" },
304   { 3,3,        "ISAKMP_CFG_SET" },
305   { 4,4,        "ISAKMP_CFG_ACK" },
306   { 5,127,      "Future use"    },
307   { 128,256,    "Private Use"   },
308   { 0,0,        NULL },
309   };
310
311
312 static const range_string vs_v2_cfgtype[] = {
313   { 0,0,        "RESERVED" },
314   { 1,1,        "CFG_REQUEST" },
315   { 2,2,        "CFG_REPLY" },
316   { 3,3,        "CFG_SET" },
317   { 4,4,        "CFG_ACK" },
318   { 5,127,      "Future use"    },
319   { 128,256,    "Private Use"   },
320   { 0,0,        NULL },
321   };
322
323 static const range_string vs_v1_cfgattr[] = {
324   { 0,0,         "RESERVED" },
325   { 1,1,         "INTERNAL_IP4_ADDRESS" },
326   { 2,2,         "INTERNAL_IP4_NETMASK" },
327   { 3,3,         "INTERNAL_IP4_DNS" },
328   { 4,4,         "INTERNAL_IP4_NBNS" },
329   { 5,5,         "INTERNAL_ADDRESS_EXPIREY" },
330   { 6,6,         "INTERNAL_IP4_DHCP" },
331   { 7,7,         "APPLICATION_VERSION" },
332   { 8,8,         "INTERNAL_IP6_ADDRESS" },
333   { 9,9,         "INTERNAL_IP6_NETMASK" },
334   { 10,10,       "INTERNAL_IP6_DNS" },
335   { 11,11,       "INTERNAL_IP6_NBNS" },
336   { 12,12,       "INTERNAL_IP6_DHCP" },
337   { 13,13,       "INTERNAL_IP4_SUBNET" },
338   { 14,14,       "SUPPORTED_ATTRIBUTES" },
339   { 15,16383,    "FUTURE USE"},
340   { 16384,16386, "PRIVATE USE"},
341   { 16387,16387, "CHKPT_DEF_DOMAIN" },
342   { 16388,16388, "CHKPT_MAC_ADDRESS" },
343   { 16389,16389, "CHKPT_MARCIPAN_REASON_CODE" },
344   { 16400,16400, "CHKPT_UNKNOWN1" },
345   { 16401,16401, "CHKPT_UNKNOWN2" },
346   { 16402,16402, "CHKPT_UNKNOWN3" },
347   { 16403,16519, "PRIVATE USE"},
348   { 16520,16520, "XAUTH_TYPE" },
349   { 16521,16521, "XAUTH_USER_NAME" },
350   { 16522,16522, "XAUTH_USER_PASSWORD" },
351   { 16523,16523, "XAUTH_PASSCODE" },
352   { 16524,16524, "XAUTH_MESSAGE" },
353   { 16525,16525, "XAUTH_CHALLANGE" },
354   { 16526,16526, "XAUTH_DOMAIN" },
355   { 16527,16527, "XAUTH_STATUS" },
356   { 16528,16528, "XAUTH_NEXT_PIN" },
357   { 16529,16529, "XAUTH_ANSWER" },
358   { 16530,28671, "PRIVATE USE"},
359   { 28672,28672, "UNITY_BANNER" },
360   { 28673,28673, "UNITY_SAVE_PASSWD" },
361   { 28674,28674, "UNITY_DEF_DOMAIN" },
362   { 28675,28675, "UNITY_SPLIT_DOMAIN" },
363   { 28676,28676, "UNITY_SPLIT_INCLUDE" },
364   { 28677,28677, "UNITY_NATT_PORT" },
365   { 28678,28678, "UNITY_SPLIT_EXCLUDE" },
366   { 28679,28679, "UNITY_PFS" },
367   { 28680,28680, "UNITY_FW_TYPE" },
368   { 28681,28681, "UNITY_BACKUP_SERVERS" },
369   { 28682,28682, "UNITY_DDNS_HOSTNAME" },
370   { 28683,32767, "PRIVATE USE"},
371   { 0,0,         NULL },
372   };
373
374 static const range_string vs_v2_cfgattr[] = {
375   { 0,0,         "RESERVED" },
376   { 1,1,         "INTERNAL_IP4_ADDRESS" },
377   { 2,2,         "INTERNAL_IP4_NETMASK" },
378   { 3,3,         "INTERNAL_IP4_DNS" },
379   { 4,4,         "INTERNAL_IP4_NBNS" },
380   { 5,5,         "INTERNAL_ADDRESS_EXPIREY" },
381   { 6,6,         "INTERNAL_IP4_DHCP" },
382   { 7,7,         "APPLICATION_VERSION" },
383   { 8,8,         "INTERNAL_IP6_ADDRESS" },
384   { 9,9,         "RESERVED" },
385   { 10,10,       "INTERNAL_IP6_DNS" },
386   { 11,11,       "INTERNAL_IP6_NBNS" },
387   { 12,12,       "INTERNAL_IP6_DHCP" },
388   { 13,13,       "INTERNAL_IP4_SUBNET" },
389   { 14,14,       "SUPPORTED_ATTRIBUTES" },
390   { 15,15,       "INTERNAL_IP6_SUBNET" },
391   { 16,16,       "MIP6_HOME_PREFIX" },
392   { 17,17,       "INTERNAL_IP6_LINK" },
393   { 18,18,       "INTERNAL_IP6_PREFIX" },
394   { 19,16383,    "RESERVED TO IANA"},
395   { 16384,32767, "PRIVATE USE"},
396   { 0,0,          NULL },
397   };
398
399 static const range_string cfgattr_xauth_type[] = {
400   { 0,0,         "Generic" },
401   { 1,1,         "RADIUS-CHAP" },
402   { 2,2,         "OTP" },
403   { 3,3,         "S/KEY" },
404   { 4,32767,     "Future use" },
405   { 32768,65535, "Private use" },
406   { 0,0,          NULL },
407   };
408
409 static const value_string cfgattr_xauth_status[] = {
410   { 0,  "Fail" },
411   { 1,  "Success" },
412   { 0,  NULL },
413 };
414
415 static const range_string vs_v1_id_type[] = {
416   { 0,0,                                                "RESERVED" },
417   { IKE_ID_IPV4_ADDR,IKE_ID_IPV4_ADDR,                  "IPV4_ADDR" },
418   { IKE_ID_FQDN,IKE_ID_FQDN,                            "FQDN" },
419   { IKE_ID_USER_FQDN,IKE_ID_USER_FQDN,                  "USER_FQDN" },
420   { IKE_ID_IPV4_ADDR_SUBNET,IKE_ID_IPV4_ADDR_SUBNET,    "IPV4_ADDR_SUBNET" },
421   { IKE_ID_IPV6_ADDR,IKE_ID_IPV6_ADDR,                  "IPV6_ADDR" },
422   { IKE_ID_IPV6_ADDR_SUBNET,IKE_ID_IPV6_ADDR_SUBNET,    "IPV6_ADDR_SUBNET" },
423   { IKE_ID_IPV4_ADDR_RANGE,IKE_ID_IPV4_ADDR_RANGE,      "IPV4_ADDR_RANGE" },
424   { IKE_ID_IPV6_ADDR_RANGE,IKE_ID_IPV6_ADDR_RANGE,      "IPV6_ADDR_RANGE" },
425   { IKE_ID_DER_ASN1_DN,IKE_ID_DER_ASN1_DN,              "DER_ASN1_DN" },
426   { IKE_ID_DER_ASN1_GN,IKE_ID_DER_ASN1_GN,              "DER_ASN1_GN" },
427   { IKE_ID_KEY_ID,IKE_ID_KEY_ID,                        "KEY_ID" },
428   { IKE_ID_LIST,IKE_ID_LIST,                            "KEY_LIST" },
429   { 13,248,                                             "Future use" },
430   { 249,255,                                            "Private Use" },
431   { 0,0,          NULL },
432   };
433 static const range_string vs_v2_id_type[] = {
434   { 0,0,                                                "RESERVED" },
435   { IKE_ID_IPV4_ADDR,IKE_ID_IPV4_ADDR,                  "IPV4_ADDR" },
436   { IKE_ID_FQDN,IKE_ID_FQDN,                            "FQDN" },
437   { IKE_ID_RFC822_ADDR,IKE_ID_RFC822_ADDR,              "ID_RFC822_ADDR" },
438   { 4,4,                                                "Unassigned" },
439   { IKE_ID_IPV6_ADDR,IKE_ID_IPV6_ADDR,                  "IPV6_ADDR" },
440   { 6,8,                                                "Unassigned" },
441   { IKE_ID_DER_ASN1_DN,IKE_ID_DER_ASN1_DN,              "DER_ASN1_DN" },
442   { IKE_ID_DER_ASN1_GN,IKE_ID_DER_ASN1_GN,              "DER_ASN1_GN" },
443   { IKE_ID_KEY_ID,IKE_ID_KEY_ID,                        "KEY_ID" },
444   { IKE_ID_FC_NAME,IKE_ID_FC_NAME,                      "KEY_LIST" },
445   { 13,200,                                             "Future use" },
446   { 201,255,                                            "Private Use" },
447   { 0,0,          NULL },
448   };
449 #define COOKIE_SIZE 8
450
451 typedef struct isakmp_hdr {
452   guint8        next_payload;
453   guint8        version;
454   guint8        exch_type;
455   guint8        flags;
456 #define E_FLAG          0x01
457 #define C_FLAG          0x02
458 #define A_FLAG          0x04
459 #define I_FLAG          0x08
460 #define V_FLAG          0x10
461 #define R_FLAG          0x20
462   guint32       message_id;
463   guint32       length;
464 } isakmp_hdr_t;
465
466 static const true_false_string flag_e = {
467   "Encrypted", 
468   "Not encrypted"
469 };
470 static const true_false_string flag_c = {
471   "Commit", 
472   "No commit"
473 };
474 static const true_false_string flag_a = {
475   "Authentication", 
476   "No authentication"
477 };
478 static const true_false_string flag_i = {
479   "Initiator", 
480   "Responder"
481 };
482 static const true_false_string flag_v = {
483   "A higher version enabled", 
484   "No higher version"
485 };
486 static const true_false_string flag_r = {
487   "Response", 
488   "Request"
489 };
490
491 #define ISAKMP_HDR_SIZE (sizeof(struct isakmp_hdr) + (2 * COOKIE_SIZE))
492
493 #define ENC_DES_CBC             1
494 #define ENC_IDEA_CBC            2
495 #define ENC_BLOWFISH_CBC        3
496 #define ENC_RC5_R16_B64_CBC     4
497 #define ENC_3DES_CBC            5
498 #define ENC_CAST_CBC            6
499 #define ENC_AES_CBC             7
500
501 #define HMAC_MD5        1
502 #define HMAC_SHA        2
503 #define HMAC_TIGER      3
504 #define HMAC_SHA2_256   4
505 #define HMAC_SHA2_384   5
506 #define HMAC_SHA2_512   6
507
508 #ifdef HAVE_LIBGCRYPT
509
510 #define MAIN_MODE            2
511 #define AGGRESSIVE_MODE      4
512 #define MAX_KEY_SIZE       256
513 #define MAX_DIGEST_SIZE     64
514 #define MAX_OAKLEY_KEY_LEN  32
515
516 typedef struct decrypt_key {
517   guchar        secret[MAX_KEY_SIZE];
518   guint         secret_len;
519 } decrypt_key_t;
520
521 typedef struct iv_data {
522   guchar  iv[MAX_DIGEST_SIZE];
523   guint   iv_len;
524   guint32 frame_num;
525 } iv_data_t;
526
527 typedef struct decrypt_data {
528   gboolean       is_psk;
529   address        initiator;
530   guint          encr_alg;
531   guint          hash_alg;
532   guint          group;
533   gchar         *gi;
534   guint          gi_len;
535   gchar         *gr;
536   guint          gr_len;
537   guchar         secret[MAX_KEY_SIZE];
538   guint          secret_len;
539   GList         *iv_list;
540   gchar          last_cbc[MAX_DIGEST_SIZE];
541   guint          last_cbc_len;
542   gchar          last_p1_cbc[MAX_DIGEST_SIZE];
543   guint          last_p1_cbc_len;
544   guint32        last_message_id;
545 } decrypt_data_t;
546
547 static GHashTable *isakmp_hash = NULL;
548 #if GLIB_CHECK_VERSION(2,10,0)
549 #else
550 static GMemChunk *isakmp_key_data = NULL;
551 static GMemChunk *isakmp_decrypt_data = NULL;
552 #endif
553 static FILE *log_f = NULL;
554 static const char *pluto_log_path = "insert pluto log path here";
555
556 /* Specifications of encryption algorithms for IKEv2 decryption */
557 typedef struct _ikev2_encr_alg_spec {
558   guint number;
559   /* Length of encryption key */
560   guint key_len;
561   /* Block size of the cipher */
562   guint block_len;
563   /* Length of initialization vector */
564   guint iv_len;
565   /* Encryption algorithm ID to be passed to gcry_cipher_open() */
566   gint gcry_alg;
567   /* Cipher mode to be passed to gcry_cipher_open() */
568   gint gcry_mode;
569 } ikev2_encr_alg_spec_t;
570
571 #define IKEV2_ENCR_NULL        1
572 #define IKEV2_ENCR_3DES        2
573 #define IKEV2_ENCR_AES_CBC_128 3
574 #define IKEV2_ENCR_AES_CBC_192 4
575 #define IKEV2_ENCR_AES_CBC_256 5
576
577 static ikev2_encr_alg_spec_t ikev2_encr_algs[] = {
578   {IKEV2_ENCR_NULL, 0, 1, 0, GCRY_CIPHER_NONE, GCRY_CIPHER_MODE_NONE},
579   {IKEV2_ENCR_3DES, 24, 8, 8, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC},
580   {IKEV2_ENCR_AES_CBC_128, 16, 16, 16, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC},
581   {IKEV2_ENCR_AES_CBC_192, 24, 16, 16, GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC},
582   {IKEV2_ENCR_AES_CBC_256, 32, 16, 16, GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC},
583   {0, 0, 0, 0, 0, 0}
584 };
585
586 /*
587  * Specifications of authentication algorithms for
588  * decryption and/or ICD (Integrity Checksum Data) checking of IKEv2
589  */
590 typedef struct _ikev2_auth_alg_spec {
591   guint number;
592   /* Output length of the hash algorithm */
593   guint output_len;
594   /* Length of the hash key */
595   guint key_len;
596   /* Actual ICD length after truncation */
597   guint trunc_len;
598   /* Hash algorithm ID to be passed to gcry_md_open() */
599   gint gcry_alg;
600   /* Flags to be passed to gcry_md_open() */
601   guint gcry_flag;
602 } ikev2_auth_alg_spec_t;
603
604 #define IKEV2_AUTH_NONE         1
605 #define IKEV2_AUTH_HMAC_MD5_96  2
606 #define IKEV2_AUTH_HMAC_SHA1_96 3
607 #define IKEV2_AUTH_ANY_96BITS   4
608 #define IKEV2_AUTH_ANY_128BITS  5
609 #define IKEV2_AUTH_ANY_160BITS  6
610 #define IKEV2_AUTH_ANY_192BITS  7
611 #define IKEV2_AUTH_ANY_256BITS  8
612
613 static ikev2_auth_alg_spec_t ikev2_auth_algs[] = {
614   {IKEV2_AUTH_NONE, 0, 0, 0, GCRY_MD_NONE, 0},
615   {IKEV2_AUTH_HMAC_MD5_96, 16, 16, 12, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC},
616   {IKEV2_AUTH_HMAC_SHA1_96, 20, 20, 12, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC},
617   {IKEV2_AUTH_ANY_96BITS, 0, 0, 12, 0, 0},
618   {IKEV2_AUTH_ANY_128BITS, 0, 0, 16, 0, 0},
619   {IKEV2_AUTH_ANY_160BITS, 0, 0, 20, 0, 0},
620   {IKEV2_AUTH_ANY_192BITS, 0, 0, 24, 0, 0},
621   {IKEV2_AUTH_ANY_256BITS, 0, 0, 32, 0, 0},
622   {0, 0, 0, 0, 0, 0}
623 };
624
625 typedef struct _ikev2_decrypt_data {
626   guchar *encr_key;
627   guchar *auth_key;
628   ikev2_encr_alg_spec_t *encr_spec;
629   ikev2_auth_alg_spec_t *auth_spec;
630 } ikev2_decrypt_data_t;
631
632 typedef struct _ikev2_uat_data_key {
633   guchar *spii;
634   guint spii_len;
635   guchar *spir;
636   guint spir_len;
637 } ikev2_uat_data_key_t;
638
639 typedef struct _ikev2_uat_data {
640   ikev2_uat_data_key_t key;
641   guint encr_alg;
642   guint auth_alg;
643   guchar *sk_ei;
644   guint sk_ei_len;
645   guchar *sk_er;
646   guint sk_er_len;
647   guchar *sk_ai;
648   guint sk_ai_len;
649   guchar *sk_ar;
650   guint sk_ar_len;
651   ikev2_encr_alg_spec_t *encr_spec;
652   ikev2_auth_alg_spec_t *auth_spec;
653 } ikev2_uat_data_t;
654
655 static ikev2_uat_data_t* ikev2_uat_data = NULL;
656 static guint num_ikev2_uat_data = 0;
657 static uat_t* ikev2_uat;
658
659 static GHashTable *ikev2_key_hash = NULL;
660
661 #define IKEV2_ENCR_3DES_STR "3DES [RFC2451]"
662 static const value_string vs_ikev2_encr_algs[] = {
663   {IKEV2_ENCR_3DES,        IKEV2_ENCR_3DES_STR},
664   {IKEV2_ENCR_AES_CBC_128, "AES-CBC-128 [RFC3602]"},
665   {IKEV2_ENCR_AES_CBC_192, "AES-CBC-192 [RFC3602]"},
666   {IKEV2_ENCR_AES_CBC_256, "AES-CBC-256 [RFC3602]"},
667   {IKEV2_ENCR_NULL,        "NULL [RFC2410]"},
668   {0, NULL}
669 };
670
671 #define IKEV2_AUTH_HMAC_SHA1_96_STR "HMAC_SHA1_96 [RFC2404]"
672 static const value_string vs_ikev2_auth_algs[] = {
673   {IKEV2_AUTH_HMAC_MD5_96,  "HMAC_MD5_96 [RFC2403]"},
674   {IKEV2_AUTH_HMAC_SHA1_96, IKEV2_AUTH_HMAC_SHA1_96_STR},
675   {IKEV2_AUTH_NONE,         "NONE [RFC4306]"},
676   {IKEV2_AUTH_ANY_96BITS,   "ANY 96-bits of Authentication [No Checking]"},
677   {IKEV2_AUTH_ANY_128BITS,  "ANY 128-bits of Authentication [No Checking]"},
678   {IKEV2_AUTH_ANY_160BITS,  "ANY 160-bits of Authentication [No Checking]"},
679   {IKEV2_AUTH_ANY_192BITS,  "ANY 192-bits of Authentication [No Checking]"},
680   {IKEV2_AUTH_ANY_256BITS,  "ANY 256-bits of Authentication [No Checking]"},
681   {0, NULL}
682 };
683
684 ikev2_encr_alg_spec_t* ikev2_decrypt_find_encr_spec(guint num) {
685   ikev2_encr_alg_spec_t *e;
686
687   for (e = ikev2_encr_algs; e->number != 0; e++) {
688     if (e->number == num) {
689       return e;
690     }
691   }
692   return NULL;
693 }
694
695 ikev2_auth_alg_spec_t* ikev2_decrypt_find_auth_spec(guint num) {
696   ikev2_auth_alg_spec_t *a;
697
698   for (a = ikev2_auth_algs; a->number != 0; a++) {
699     if (a->number == num) {
700       return a;
701     }
702   }
703   return NULL;
704 }
705
706 static void
707 scan_pluto_log(void) {
708 #define MAX_PLUTO_LINE 500
709   decrypt_data_t *decr;
710   gchar    line[MAX_PLUTO_LINE];
711   guint8   i_cookie[COOKIE_SIZE], *ic_key;
712   gboolean got_cookie = FALSE;
713   guchar   secret[MAX_KEY_SIZE];
714   guint    secret_len = 0;
715   gchar   *icookie_pfx = "| ICOOKIE: ";
716   gchar   *enc_key_pfx = "| enc key: ";
717   gchar   *pos, *endpos;
718   gint     icpfx_len = (gint) strlen(icookie_pfx);
719   gint     ec_len = (gint) strlen(enc_key_pfx);
720   gint     i;
721   address  null_addr;
722   unsigned long hexval;
723
724   SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
725
726   if (log_f) {
727     while (fgets(line, MAX_PLUTO_LINE, log_f)) {
728       if (strncmp(line, icookie_pfx, icpfx_len) == 0) {
729         secret_len = 0;
730         pos = line + icpfx_len;
731         for (i = 0; i < COOKIE_SIZE; i++) {
732           hexval = strtoul(pos, &endpos, 16);
733           if (endpos == pos)
734             break;
735           i_cookie[i] = (guint8) hexval;
736           pos = endpos;
737         }
738         if (i == COOKIE_SIZE)
739           got_cookie = TRUE;
740       } else if (strncmp(line, enc_key_pfx, ec_len) == 0) {
741         pos = line + ec_len;
742         for (; secret_len < MAX_KEY_SIZE; secret_len++) {
743           hexval = strtoul(pos, &endpos, 16);
744           if (endpos == pos)
745             break;
746           secret[secret_len] = (guint8) hexval;
747           pos = endpos;
748         }
749       } else if (got_cookie && secret_len > 1) {
750         decr = (decrypt_data_t*) g_hash_table_lookup(isakmp_hash, i_cookie);
751
752         if (! decr) {
753 #if GLIB_CHECK_VERSION(2,10,0)
754           ic_key = g_slice_alloc(COOKIE_SIZE);
755           decr   = g_slice_alloc(sizeof(decrypt_data_t));
756 #else
757           ic_key = g_mem_chunk_alloc(isakmp_key_data);
758           decr   = g_mem_chunk_alloc(isakmp_decrypt_data);
759 #endif
760           memcpy(ic_key, i_cookie, COOKIE_SIZE);
761           memset(decr, 0, sizeof(decrypt_data_t));
762
763           g_hash_table_insert(isakmp_hash, ic_key, decr);
764         }
765
766         memcpy(decr->secret, secret, secret_len);
767         decr->secret_len = secret_len;
768       }
769     }
770   }
771 }
772
773 static void
774 set_transform_vals(decrypt_data_t *decr, int ike_p1, guint16 type, guint32 val) {
775   if (! ike_p1)
776     return;
777
778   if (decr != NULL) {
779     switch (type) {
780       case 1:
781         decr->encr_alg = val;
782         break;
783       case 2:
784         decr->hash_alg = val;
785         break;
786       case 3:
787         if (val == 1)
788           decr->is_psk = TRUE;
789         break;
790       case 4:
791         decr->group = val;
792         break;
793     }
794   }
795 }
796
797 static tvbuff_t *
798 decrypt_payload(tvbuff_t *tvb, packet_info *pinfo, const guint8 *buf, guint buf_len, isakmp_hdr_t *hdr) {
799   decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
800   gchar *decrypted_data = NULL;
801   gint gcry_md_algo, gcry_cipher_algo;
802   gcry_md_hd_t md_ctx;
803   gcry_cipher_hd_t decr_ctx;
804   tvbuff_t *encr_tvb;
805   iv_data_t *ivd = NULL;
806   GList *ivl;
807   guchar iv[MAX_DIGEST_SIZE];
808   guint iv_len = 0;
809   guint32 message_id, cbc_block_size, digest_size;
810
811   if (!decr ||
812       decr->is_psk == FALSE ||
813       decr->gi_len == 0 ||
814       decr->gr_len == 0)
815     return NULL;
816
817   switch(decr->encr_alg) {
818     case ENC_3DES_CBC:
819       gcry_cipher_algo = GCRY_CIPHER_3DES;
820       break;
821     case ENC_DES_CBC:
822       gcry_cipher_algo = GCRY_CIPHER_DES;
823       break;
824     default:
825       return NULL;
826       break;
827   }
828   if (decr->secret_len < gcry_cipher_get_algo_keylen(gcry_cipher_algo))
829     return NULL;
830   cbc_block_size = (guint32) gcry_cipher_get_algo_blklen(gcry_cipher_algo);
831
832   switch(decr->hash_alg) {
833     case HMAC_MD5:
834       gcry_md_algo = GCRY_MD_MD5;
835       break;
836     case HMAC_SHA:
837       gcry_md_algo = GCRY_MD_SHA1;
838       break;
839     default:
840       return NULL;
841       break;
842   }
843   digest_size = gcry_md_get_algo_dlen(gcry_md_algo);
844
845   for (ivl = g_list_first(decr->iv_list); ivl != NULL; ivl = g_list_next(ivl)) {
846     ivd = (iv_data_t *) ivl->data;
847     if (ivd->frame_num == pinfo->fd->num) {
848       iv_len = ivd->iv_len;
849       memcpy(iv, ivd->iv, iv_len);
850     }
851   }
852
853   /*
854    * Set our initialization vector as follows:
855    * - If the IV list is empty, assume we have the first packet in a phase 1
856    *   exchange.  The IV is built from DH values.
857    * - If our message ID changes, assume we're entering a new mode.  The IV
858    *   is built from the message ID and the last phase 1 CBC.
859    * - Otherwise, use the last CBC.
860    */
861   if (iv_len == 0) {
862     if (gcry_md_open(&md_ctx, gcry_md_algo, 0) != GPG_ERR_NO_ERROR)
863       return NULL;
864     if (decr->iv_list == NULL) {
865       /* First packet */
866       ivd = g_malloc(sizeof(iv_data_t));
867       ivd->frame_num = pinfo->fd->num;
868       ivd->iv_len = digest_size;
869       decr->last_message_id = hdr->message_id;
870       gcry_md_reset(md_ctx);
871       gcry_md_write(md_ctx, decr->gi, decr->gi_len);
872       gcry_md_write(md_ctx, decr->gr, decr->gr_len);
873       gcry_md_final(md_ctx);
874       memcpy(ivd->iv, gcry_md_read(md_ctx, gcry_md_algo), digest_size);
875       decr->iv_list = g_list_append(decr->iv_list, ivd);
876       iv_len = ivd->iv_len;
877       memcpy(iv, ivd->iv, iv_len);
878     } else if (decr->last_cbc_len >= cbc_block_size) {
879       ivd = g_malloc(sizeof(iv_data_t));
880       ivd->frame_num = pinfo->fd->num;
881       if (hdr->message_id != decr->last_message_id) {
882         if (decr->last_p1_cbc_len == 0) {
883           memcpy(decr->last_p1_cbc, decr->last_cbc, cbc_block_size);
884           decr->last_p1_cbc_len = cbc_block_size;
885         }
886         ivd->iv_len = digest_size;
887         decr->last_message_id = hdr->message_id;
888         message_id = g_htonl(decr->last_message_id);
889         gcry_md_reset(md_ctx);
890         gcry_md_write(md_ctx, decr->last_p1_cbc, cbc_block_size);
891         gcry_md_write(md_ctx, &message_id, sizeof(message_id));
892         memcpy(ivd->iv, gcry_md_read(md_ctx, gcry_md_algo), digest_size);
893       } else {
894         ivd->iv_len = cbc_block_size;
895         memcpy(ivd->iv, decr->last_cbc, ivd->iv_len);
896       }
897       decr->iv_list = g_list_append(decr->iv_list, ivd);
898       iv_len = ivd->iv_len;
899       memcpy(iv, ivd->iv, iv_len);
900     }
901     gcry_md_close(md_ctx);
902   }
903
904   if (ivd == NULL) return NULL;
905
906   if (gcry_cipher_open(&decr_ctx, gcry_cipher_algo, GCRY_CIPHER_MODE_CBC, 0) != GPG_ERR_NO_ERROR)
907     return NULL;
908   if (iv_len > cbc_block_size)
909       iv_len = cbc_block_size; /* gcry warns otherwise */
910   if (gcry_cipher_setiv(decr_ctx, iv, iv_len))
911     return NULL;
912   if (gcry_cipher_setkey(decr_ctx, decr->secret, decr->secret_len))
913     return NULL;
914
915   decrypted_data = g_malloc(buf_len);
916
917   if (gcry_cipher_decrypt(decr_ctx, decrypted_data, buf_len, buf, buf_len) != GPG_ERR_NO_ERROR) {
918     g_free(decrypted_data);
919     return NULL;
920   }
921   gcry_cipher_close(decr_ctx);
922
923   encr_tvb = tvb_new_child_real_data(tvb, decrypted_data, buf_len, buf_len);
924
925   /* Add the decrypted data to the data source list. */
926   add_new_data_source(pinfo, encr_tvb, "Decrypted IKE");
927
928   /* Fill in the next IV */
929   if (tvb_length(tvb) > cbc_block_size) {
930     decr->last_cbc_len = cbc_block_size;
931     memcpy(decr->last_cbc, buf + buf_len - cbc_block_size, cbc_block_size);
932   } else {
933     decr->last_cbc_len = 0;
934   }
935
936   return encr_tvb;
937 }
938
939 #endif /* HAVE_LIBGCRYPT */
940
941 static const char* vid_to_str(tvbuff_t *, int, int);
942 static proto_tree *dissect_payload_header(tvbuff_t *, int, int, int, guint8,
943     guint8 *, guint16 *, proto_tree *);
944
945 static void dissect_sa(tvbuff_t *, int, int, proto_tree *,
946     proto_tree *, packet_info *, int, int, guint8);
947 static void dissect_proposal(tvbuff_t *, int, int, proto_tree *,
948     proto_tree *, packet_info *, int, int, guint8);
949 static void dissect_transform(tvbuff_t *, int, int, proto_tree *,
950     proto_tree *, packet_info *, int, int, guint8);
951 static void dissect_transform2(tvbuff_t *, int, int, proto_tree *,
952     proto_tree *, packet_info *, int, int, guint8);
953 static void dissect_key_exch(tvbuff_t *, int, int, proto_tree *,
954     proto_tree *, packet_info *, int, int, guint8);
955 static void dissect_id(tvbuff_t *, int, int, proto_tree *,
956     proto_tree *, packet_info *, int, int, guint8);
957 static void dissect_cert(tvbuff_t *, int, int, proto_tree *,
958     proto_tree *, packet_info *, int, int, guint8);
959 static void dissect_certreq_v1(tvbuff_t *, int, int, proto_tree *,
960     proto_tree *, packet_info *, int, int, guint8);
961 static void dissect_certreq_v2(tvbuff_t *, int, int, proto_tree *,
962     proto_tree *, packet_info *, int, int, guint8);
963 static void dissect_hash(tvbuff_t *, int, int, proto_tree *,
964     proto_tree *, packet_info *, int, int, guint8);
965 static void dissect_auth(tvbuff_t *, int, int, proto_tree *,
966     proto_tree *, packet_info *, int, int, guint8);
967 static void dissect_sig(tvbuff_t *, int, int, proto_tree *,
968     proto_tree *, packet_info *, int, int, guint8);
969 static void dissect_nonce(tvbuff_t *, int, int, proto_tree *,
970     proto_tree *, packet_info *, int, int, guint8);
971 static void dissect_notif(tvbuff_t *, int, int, proto_tree *,
972     proto_tree *, packet_info *, int, int, guint8);
973 static void dissect_delete(tvbuff_t *, int, int, proto_tree *,
974     proto_tree *, packet_info *, int, int, guint8);
975 static void dissect_vid(tvbuff_t *, int, int, proto_tree *,
976     proto_tree *, packet_info *, int, int, guint8);
977 static void dissect_config(tvbuff_t *, int, int, proto_tree *,
978     proto_tree *, packet_info *, int, int, guint8);
979 static void dissect_nat_discovery(tvbuff_t *, int, int, proto_tree *,
980     proto_tree *, packet_info *, int, int, guint8);
981 static void dissect_nat_original_address(tvbuff_t *, int, int, proto_tree *,
982     proto_tree *, packet_info *, int, int, guint8);
983 static void dissect_ts(tvbuff_t *, int, int, proto_tree *,
984     proto_tree *, packet_info *, int, int, guint8);
985 static void dissect_enc(tvbuff_t *, int, int, proto_tree *,
986     proto_tree *, packet_info *, int, int, guint8);
987 static void dissect_eap(tvbuff_t *, int, int, proto_tree *,
988     proto_tree *, packet_info *, int, int, guint8);
989 static void dissect_cisco_fragmentation(tvbuff_t *, int, int, proto_tree *,
990     proto_tree *, packet_info *, int, int, guint8);
991
992 static const char *payloadtype2str(int, guint8);
993 static const char *exchtype2str(int, guint8);
994 static const char *doitype2str(guint32);
995 static const char *msgtype2str(int, guint16);
996 static const char *situation2str(guint32);
997 static const char *v1_attrval2str(int, guint16, guint32);
998 static const char *v2_attrval2str(guint16);
999 static const char *v2_tstype2str(guint8);
1000 static const char *v2_auth2str(guint8);
1001 static const char *certtype2str(int, guint8);
1002
1003 static gboolean get_num(tvbuff_t *, int, guint16, guint32 *);
1004
1005 #define LOAD_TYPE_NONE          0       /* payload type for None */
1006 #define LOAD_TYPE_PROPOSAL      2       /* payload type for Proposal */
1007 #define LOAD_TYPE_TRANSFORM     3       /* payload type for Transform */
1008
1009 struct payload_func {
1010   guint8 type;
1011   const char *  str;
1012   void (*func)(tvbuff_t *, int, int, proto_tree *, proto_tree *, packet_info *,
1013                 int, int, guint8);
1014 };
1015
1016 static struct payload_func v1_plfunc[] = {
1017   {  0, "NONE",                 NULL              },
1018   {  1, "Security Association", dissect_sa        },
1019   {  2, "Proposal",             dissect_proposal  },
1020   {  3, "Transform",            dissect_transform },
1021   {  4, "Key Exchange",         dissect_key_exch  },
1022   {  5, "Identification",       dissect_id        },
1023   {  6, "Certificate",          dissect_cert      },
1024   {  7, "Certificate Request",  dissect_certreq_v1},
1025   {  8, "Hash",                 dissect_hash      },
1026   {  9, "Signature",            dissect_sig       },
1027   { 10, "Nonce",                dissect_nonce     },
1028   { 11, "Notification",         dissect_notif     },
1029   { 12, "Delete",               dissect_delete    },
1030   { 13, "Vendor ID",            dissect_vid       },
1031   { 14, "Attrib",               dissect_config    },
1032   { 15, "NAT-Discovery",        dissect_nat_discovery },        /* draft-ietf-ipsec-nat-t-ike-04 */
1033   { 16, "NAT-Original Address", dissect_nat_original_address }, /* draft-ietf-ipsec-nat-t-ike */
1034   { 20, "NAT-D (RFC 3947)",     dissect_nat_discovery },
1035   { 21, "NAT-OA (RFC 3947)",    dissect_nat_original_address },
1036   { 130, "NAT-D (draft-ietf-ipsec-nat-t-ike-01 to 03)",         dissect_nat_discovery },
1037   { 131, "NAT-OA (draft-ietf-ipsec-nat-t-ike-01 to 04)",        dissect_nat_original_address },
1038   { 132, "Cisco-Fragmentation", dissect_cisco_fragmentation },
1039 };
1040
1041 static struct payload_func v2_plfunc[] = {
1042   {  0, "NONE",                 NULL },
1043   {  2, "Proposal",             dissect_proposal  },
1044   {  3, "Transform",            dissect_transform2 },
1045   { 33, "Security Association", dissect_sa        },
1046   { 34, "Key Exchange",         dissect_key_exch  },
1047   { 35, "Identification - I",   dissect_id        },
1048   { 36, "Identification - R",   dissect_id        },
1049   { 37, "Certificate",          dissect_cert      },
1050   { 38, "Certificate Request",  dissect_certreq_v2},
1051   { 39, "Authentication",       dissect_auth      },
1052   { 40, "Nonce",                dissect_nonce     },
1053   { 41, "Notification",         dissect_notif     },
1054   { 42, "Delete",               dissect_delete    },
1055   { 43, "Vendor ID",            dissect_vid       },
1056   { 44, "Traffic Selector - I", dissect_ts        },
1057   { 45, "Traffic Selector - R", dissect_ts        },
1058   { 46, "Encrypted",            dissect_enc       },
1059   { 47, "Configuration",        dissect_config    },
1060   { 48, "Extensible Authentication",    dissect_eap       },
1061 };
1062
1063 static struct payload_func * getpayload_func(guint8, int);
1064
1065 #define VID_LEN 16
1066 #define VID_MS_LEN 20
1067 #define VID_CISCO_FRAG_LEN 20
1068
1069 static const guint8 VID_CISCO_FRAG[VID_CISCO_FRAG_LEN] = {0x40, 0x48, 0xB7, 0xD5, 0x6E, 0xBC, 0xE8, 0x85, 0x25, 0xE7, 0xDE, 0x7F, 0x00, 0xD6, 0xC2, 0xD3, 0x80, 0x00, 0x00, 0x00};
1070
1071 static const guint8 VID_MS_W2K_WXP[VID_MS_LEN] = {0x1E, 0x2B, 0x51, 0x69, 0x5, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61, 0x0, 0x0, 0x0, 0x2}; /* according to http://www.microsoft.com/technet/treeview/default.asp?url=/technet/columns/cableguy/cg0602.asp */
1072
1073 #define VID_CP_LEN 20
1074 static const guint8 VID_CP[VID_CP_LEN] = {0xF4, 0xED, 0x19, 0xE0, 0xC1, 0x14, 0xEB, 0x51, 0x6F, 0xAA, 0xAC, 0x0E, 0xE3, 0x7D, 0xAF, 0x28, 0x7, 0xB4, 0x38, 0x1F};
1075
1076 static const guint8 VID_CYBERGUARD[VID_LEN] = {0x9A, 0xA1, 0xF3, 0xB4, 0x34, 0x72, 0xA4, 0x5D, 0x5F, 0x50, 0x6A, 0xEB, 0x26, 0xC, 0xF2, 0x14};
1077
1078 static const guint8 VID_rfc3947[VID_LEN] = {0x4a, 0x13, 0x1c, 0x81, 0x07, 0x03, 0x58, 0x45, 0x5c, 0x57, 0x28, 0xf2, 0x0e, 0x95, 0x45, 0x2f}; /* RFC 3947 Negotiation of NAT-Traversal in the IKE*/
1079
1080 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_0[VID_LEN] = {0xfB, 0xF4, 0x76, 0x14, 0x98, 0x40, 0x31, 0xFA, 0x8E, 0x3B, 0xB6, 0x19, 0x80, 0x89, 0xB2, 0x23}; /* Ssh Communications Security IPSEC Express version 1.1.0 */
1081
1082 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_1[VID_LEN] = {0x19, 0x52, 0xDC, 0x91, 0xAC, 0x20, 0xF6, 0x46, 0xFB, 0x01, 0xCF, 0x42, 0xA3, 0x3A, 0xEE, 0x30}; /* Ssh Communications Security IPSEC Express version 1.1.1 */
1083
1084 static const guint8 VID_SSH_IPSEC_EXPRESS_1_1_2[VID_LEN] = {0xE8, 0xBF, 0xFA, 0x64, 0x3E, 0x5C, 0x8F, 0x2C, 0xD1, 0x0F, 0xDA, 0x73, 0x70, 0xB6, 0xEB, 0xE5}; /* Ssh Communications Security IPSEC Express version 1.1.2 */
1085
1086 static const guint8 VID_SSH_IPSEC_EXPRESS_1_2_1[VID_LEN] = {0xC1, 0x11, 0x1B, 0x2D, 0xEE, 0x8C, 0xBC, 0x3D, 0x62, 0x05, 0x73, 0xEC, 0x57, 0xAA, 0xB9, 0xCB}; /* Ssh Communications Security IPSEC Express version 1.2.1 */
1087
1088 static const guint8 VID_SSH_IPSEC_EXPRESS_1_2_2[VID_LEN] = {0x09, 0xEC, 0x27, 0xBF, 0xBC, 0x09, 0xC7, 0x58, 0x23, 0xCF, 0xEC, 0xBF, 0xFE, 0x56, 0x5A, 0x2E}; /* Ssh Communications Security IPSEC Express version 1.2.2 */
1089
1090 static const guint8 VID_SSH_IPSEC_EXPRESS_2_0_0[VID_LEN] = {0x7F, 0x21, 0xA5, 0x96, 0xE4, 0xE3, 0x18, 0xF0, 0xB2, 0xF4, 0x94, 0x4C, 0x23, 0x84, 0xCB, 0x84};  /* SSH Communications Security IPSEC Express version 2.0.0 */
1091
1092 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_0[VID_LEN] = {0x28, 0x36, 0xD1, 0xFD, 0x28, 0x07, 0xBC, 0x9E, 0x5A, 0xE3, 0x07, 0x86, 0x32, 0x04, 0x51, 0xEC}; /* SSH Communications Security IPSEC Express version 2.1.0 */
1093
1094 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_1[VID_LEN] = {0xA6, 0x8D, 0xE7, 0x56, 0xA9, 0xC5, 0x22, 0x9B, 0xAE, 0x66, 0x49, 0x80, 0x40, 0x95, 0x1A, 0xD5}; /* SSH Communications Security IPSEC Express version 2.1.1 */
1095
1096 static const guint8 VID_SSH_IPSEC_EXPRESS_2_1_2[VID_LEN] = {0x3F, 0x23, 0x72, 0x86, 0x7E, 0x23, 0x7C, 0x1C, 0xD8, 0x25, 0x0A, 0x75, 0x55, 0x9C, 0xAE, 0x20}; /* SSH Communications Security IPSEC Express version 2.1.2 */
1097
1098 static const guint8 VID_SSH_IPSEC_EXPRESS_3_0_0[VID_LEN] = {0x0E, 0x58, 0xD5, 0x77, 0x4D, 0xF6, 0x02, 0x00, 0x7D, 0x0B, 0x02, 0x44, 0x36, 0x60, 0xF7, 0xEB}; /* SSH Communications Security IPSEC Express version 3.0.0 */
1099
1100 static const guint8 VID_SSH_IPSEC_EXPRESS_3_0_1[VID_LEN] = {0xF5, 0xCE, 0x31, 0xEB, 0xC2, 0x10, 0xF4, 0x43, 0x50, 0xCF, 0x71, 0x26, 0x5B, 0x57, 0x38, 0x0F}; /* SSH Communications Security IPSEC Express version 3.0.1 */
1101
1102 static const guint8 VID_SSH_IPSEC_EXPRESS_4_0_0[VID_LEN] = {0xF6, 0x42, 0x60, 0xAF, 0x2E, 0x27, 0x42, 0xDA, 0xDD, 0xD5, 0x69, 0x87, 0x06, 0x8A, 0x99, 0xA0}; /* SSH Communications Security IPSEC Express version 4.0.0 */
1103
1104 static const guint8 VID_SSH_IPSEC_EXPRESS_4_0_1[VID_LEN] = {0x7A, 0x54, 0xD3, 0xBD, 0xB3, 0xB1, 0xE6, 0xD9, 0x23, 0x89, 0x20, 0x64, 0xBE, 0x2D, 0x98, 0x1C}; /* SSH Communications Security IPSEC Express version 4.0.1 */
1105
1106 static const guint8 VID_SSH_IPSEC_EXPRESS_4_1_0[VID_LEN] = {0x9A, 0xA1, 0xF3, 0xB4, 0x34, 0x72, 0xA4, 0x5D, 0x5F, 0x50, 0x6A, 0xEB, 0x26, 0x0C, 0xF2, 0x14}; /* SSH Communications Security IPSEC Express version 4.1.0 */
1107
1108 static const guint8 VID_SSH_IPSEC_EXPRESS_4_1_1[VID_LEN] = {0x89, 0xF7, 0xB7, 0x60, 0xD8, 0x6B, 0x01, 0x2A, 0xCF, 0x26, 0x33, 0x82, 0x39, 0x4D, 0x96, 0x2F}; /* SSH Communications Security IPSEC Express version 4.1.1 */
1109
1110 static const guint8 VID_SSH_IPSEC_EXPRESS_5_0[VID_LEN] = {0xB0, 0x37, 0xA2, 0x1A, 0xCE, 0xCC, 0xB5, 0x57, 0x0F, 0x60, 0x25, 0x46, 0xF9, 0x7B, 0xDE, 0x8C}; /* SSH Communications Security IPSEC Express version 5.0 */
1111
1112 static const guint8 VID_SSH_IPSEC_EXPRESS_5_0_0[VID_LEN] = {0x2B, 0x2D, 0xAD, 0x97, 0xC4, 0xD1, 0x40, 0x93, 0x00, 0x53, 0x28, 0x7F, 0x99, 0x68, 0x50, 0xB0}; /* SSH Communications Security IPSEC Express version 5.0.0 */
1113
1114 static const guint8 VID_SSH_IPSEC_EXPRESS_5_1_0[VID_LEN] = {0x45, 0xE1, 0x7F, 0x3A, 0xBE, 0x93, 0x94, 0x4C, 0xB2, 0x02, 0x91, 0x0C, 0x59, 0xEF, 0x80, 0x6B}; /* SSH Communications Security IPSEC Express version 5.1.0 */
1115
1116 static const guint8 VID_SSH_IPSEC_EXPRESS_5_1_1[VID_LEN] = {0x59, 0x25, 0x85, 0x9F, 0x73, 0x77, 0xED, 0x78, 0x16, 0xD2, 0xFB, 0x81, 0xC0, 0x1F, 0xA5, 0x51}; /* SSH Communications Security IPSEC Express version 5.1.1 */
1117
1118 static const guint8 VID_SSH_SENTINEL[VID_LEN] = {0x05, 0x41, 0x82, 0xA0, 0x7C, 0x7A, 0xE2, 0x06, 0xF9, 0xD2, 0xCF, 0x9D, 0x24, 0x32, 0xC4, 0x82}; /* SSH Sentinel */
1119
1120 static const guint8 VID_SSH_SENTINEL_1_1[VID_LEN] = {0xB9, 0x16, 0x23, 0xE6, 0x93, 0xCA, 0x18, 0xA5, 0x4C, 0x6A, 0x27, 0x78, 0x55, 0x23, 0x05, 0xE8}; /* SSH Sentinel 1.1 */
1121
1122 static const guint8 VID_SSH_SENTINEL_1_2[VID_LEN] = {0x54, 0x30, 0x88, 0x8D, 0xE0, 0x1A, 0x31, 0xA6, 0xFA, 0x8F, 0x60, 0x22, 0x4E, 0x44, 0x99, 0x58}; /* SSH Sentinel 1.2 */
1123
1124 static const guint8 VID_SSH_SENTINEL_1_3[VID_LEN] = {0x7E, 0xE5, 0xCB, 0x85, 0xF7, 0x1C, 0xE2, 0x59, 0xC9, 0x4A, 0x5C, 0x73, 0x1E, 0xE4, 0xE7, 0x52}; /* SSH Sentinel 1.3 */
1125
1126 static const guint8 VID_SSH_QUICKSEC_0_9_0[VID_LEN] = {0x37, 0xEB, 0xA0, 0xC4, 0x13, 0x61, 0x84, 0xE7, 0xDA, 0xF8, 0x56, 0x2A, 0x77, 0x06, 0x0B, 0x4A}; /* SSH Communications Security QuickSec 0.9.0 */
1127
1128 static const guint8 VID_SSH_QUICKSEC_1_1_0[VID_LEN] = {0x5D, 0x72, 0x92, 0x5E, 0x55, 0x94, 0x8A, 0x96, 0x61, 0xA7, 0xFC, 0x48, 0xFD, 0xEC, 0x7F, 0xF9}; /* SSH Communications Security QuickSec 1.1.0 */
1129
1130 static const guint8 VID_SSH_QUICKSEC_1_1_1[VID_LEN] = {0x77, 0x7F, 0xBF, 0x4C, 0x5A, 0xF6, 0xD1, 0xCD, 0xD4, 0xB8, 0x95, 0xA0, 0x5B, 0xF8, 0x25, 0x94}; /* SSH Communications Security QuickSec 1.1.1 */
1131
1132 static const guint8 VID_SSH_QUICKSEC_1_1_2[VID_LEN] = {0x2C, 0xDF, 0x08, 0xE7, 0x12, 0xED, 0xE8, 0xA5, 0x97, 0x87, 0x61, 0x26, 0x7C, 0xD1, 0x9B, 0x91}; /* SSH Communications Security QuickSec 1.1.2 */
1133
1134 static const guint8 VID_SSH_QUICKSEC_1_1_3[VID_LEN] = {0x59, 0xE4, 0x54, 0xA8, 0xC2, 0xCF, 0x02, 0xA3, 0x49, 0x59, 0x12, 0x1F, 0x18, 0x90, 0xBC, 0x87}; /* SSH Communications Security QuickSec 1.1.3 */
1135
1136 static const guint8 VID_draft_huttunen_ipsec_esp_in_udp_01[VID_LEN] = {0x50, 0x76, 0x0F, 0x62, 0x4C, 0x63, 0xE5, 0xC5, 0x3E, 0xEA, 0x38, 0x6C, 0x68, 0x5C, 0xA0, 0x83}; /* draft-huttunen-ipsec-esp-in-udp-01.txt */
1137
1138 static const guint8 VID_draft_stenberg_ipsec_nat_traversal_01[VID_LEN] = {0x27, 0xBA, 0xB5, 0xDC, 0x01, 0xEA, 0x07, 0x60, 0xEA, 0x4E, 0x31, 0x90, 0xAC, 0x27, 0xC0, 0xD0}; /* draft-stenberg-ipsec-nat-traversal-01 */
1139
1140 static const guint8 VID_draft_stenberg_ipsec_nat_traversal_02[VID_LEN]= {0x61, 0x05, 0xC4, 0x22, 0xE7, 0x68, 0x47, 0xE4, 0x3F, 0x96, 0x84, 0x80, 0x12, 0x92, 0xAE, 0xCD}; /* draft-stenberg-ipsec-nat-traversal-02 */
1141
1142 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_00[VID_LEN]= {0x44, 0x85, 0x15, 0x2D, 0x18, 0xB6, 0xBB, 0xCD, 0x0B, 0xE8, 0xA8, 0x46, 0x95, 0x79, 0xDD, 0xCC}; /* draft-ietf-ipsec-nat-t-ike-00 */
1143
1144 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_01[VID_LEN]= {0x16, 0xf6, 0xca, 0x16, 0xe4, 0xa4, 0x06, 0x6d, 0x83, 0x82, 0x1a, 0x0f, 0x0a, 0xea, 0xa8, 0x62 }; /* "draft-ietf-ipsec-nat-t-ike-01" */
1145
1146 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_02a[VID_LEN]= {0xCD, 0x60, 0x46, 0x43, 0x35, 0xDF, 0x21, 0xF8, 0x7C, 0xFD, 0xB2, 0xFC, 0x68, 0xB6, 0xA4, 0x48}; /* draft-ietf-ipsec-nat-t-ike-02 */
1147
1148 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_02b[VID_LEN]= {0x90, 0xCB, 0x80, 0x91, 0x3E, 0xBB, 0x69, 0x6E, 0x08, 0x63, 0x81, 0xB5, 0xEC, 0x42, 0x7B, 0x1F}; /* draft-ietf-ipsec-nat-t-ike-02 */
1149
1150 static const guint8 VID_draft_ietf_ipsec_nat_t_ike_03[VID_LEN] = {0x7D, 0x94, 0x19, 0xA6, 0x53, 0x10, 0xCA, 0x6F, 0x2C, 0x17, 0x9D, 0x92, 0x15, 0x52, 0x9d, 0x56}; /* according to http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-03.txt */
1151
1152 static const guint8 VID_draft_beaulieu_ike_xauth_02[VID_LEN]= {0x09, 0x00, 0x26, 0x89, 0xDF, 0xD6, 0xB7, 0x12, 0x80, 0xA2, 0x24, 0xDE, 0xC3, 0x3B, 0x81, 0xE5}; /* draft-beaulieu-ike-xauth-02.txt */
1153
1154
1155 static const guint8 VID_rfc3706_dpd[VID_LEN]= {0xAF, 0xCA,0xD7, 0x13, 0x68, 0xA1, 0xF1, 0xC9, 0x6B, 0x86, 0x96, 0xFC, 0x77, 0x57, 0x01, 0x00}; /* RFC 3706 */
1156
1157 static const guint8 VID_IKE_CHALLENGE_RESPONSE_1[VID_LEN]= {0xBA, 0x29, 0x04, 0x99, 0xC2, 0x4E, 0x84, 0xE5, 0x3A, 0x1D, 0x83, 0xA0, 0x5E, 0x5F, 0x00, 0xC9}; /* IKE Challenge/Response for Authenticated Cryptographic Keys */
1158
1159 static const guint8 VID_IKE_CHALLENGE_RESPONSE_2[VID_LEN]= {0x0D, 0x33, 0x61, 0x1A, 0x5D, 0x52, 0x1B, 0x5E, 0x3C, 0x9C, 0x03, 0xD2, 0xFC, 0x10, 0x7E, 0x12}; /* IKE Challenge/Response for Authenticated Cryptographic Keys */
1160
1161 static const guint8 VID_IKE_CHALLENGE_RESPONSE_REV_1[VID_LEN]= {0xAD, 0x32, 0x51, 0x04, 0x2C, 0xDC, 0x46, 0x52, 0xC9, 0xE0, 0x73, 0x4C, 0xE5, 0xDE, 0x4C, 0x7D}; /* IKE Challenge/Response for Authenticated Cryptographic Keys (Revised) */
1162
1163 static const guint8 VID_IKE_CHALLENGE_RESPONSE_REV_2[VID_LEN]= {0x01, 0x3F, 0x11, 0x82, 0x3F, 0x96, 0x6F, 0xA9, 0x19, 0x00, 0xF0, 0x24, 0xBA, 0x66, 0xA8, 0x6B}; /* IKE Challenge/Response for Authenticated Cryptographic Keys (Revised) */
1164
1165 static const guint8 VID_MS_L2TP_IPSEC_VPN_CLIENT[VID_LEN]= {0x40, 0x48, 0xB7, 0xD5, 0x6E, 0xBC, 0xE8, 0x85, 0x25, 0xE7, 0xDE, 0x7F, 0x00, 0xD6, 0xC2, 0xD3}; /* Microsoft L2TP/IPSec VPN Client */
1166
1167 static const guint8 VID_GSS_API_1[VID_LEN]= {0xB4, 0x6D, 0x89, 0x14, 0xF3, 0xAA, 0xA3, 0xF2, 0xFE, 0xDE, 0xB7, 0xC7, 0xDB, 0x29, 0x43, 0xCA}; /* A GSS-API Authentication Method for IKE */
1168
1169 static const guint8 VID_GSS_API_2[VID_LEN]= {0xAD, 0x2C, 0x0D, 0xD0, 0xB9, 0xC3, 0x20, 0x83, 0xCC, 0xBA, 0x25, 0xB8, 0x86, 0x1E, 0xC4, 0x55}; /* A GSS-API Authentication Method for IKE */
1170
1171 static const guint8 VID_GSSAPI[VID_LEN]= {0x62, 0x1B, 0x04, 0xBB, 0x09, 0x88, 0x2A, 0xC1, 0xE1, 0x59, 0x35, 0xFE, 0xFA, 0x24, 0xAE, 0xEE}; /* GSSAPI */
1172
1173 static const guint8 VID_MS_NT5_ISAKMPOAKLEY[VID_LEN]= {0x1E, 0x2B, 0x51, 0x69, 0x05, 0x99, 0x1C, 0x7D, 0x7C, 0x96, 0xFC, 0xBF, 0xB5, 0x87, 0xE4, 0x61}; /* MS NT5 ISAKMPOAKLEY */
1174
1175 static const guint8 VID_CISCO_UNITY[VID_LEN]= {0x12, 0xF5, 0xF2, 0x8C, 0x45, 0x71, 0x68, 0xA9, 0x70, 0x2D, 0x9F, 0xE2, 0x74, 0xCC, 0x02, 0xD4}; /* CISCO-UNITY */
1176
1177 static const guint8 VID_CISCO_UNITY_10[VID_LEN]= {0x12, 0xF5, 0xF2, 0x8C, 0x45, 0x71, 0x68, 0xA9, 0x70, 0x2D, 0x9F, 0xE2, 0x74, 0xCC, 0x01, 0x00}; /* CISCO-UNITY 1.0 */
1178
1179 static const guint8 VID_CISCO_CONCENTRATOR[VID_LEN]= {0x1F, 0x07, 0xF7, 0x0E, 0xAA, 0x65, 0x14, 0xD3, 0xB0, 0xFA, 0x96, 0x54, 0x2A, 0x50, 0x01, 0x00}; /* CISCO-CONCENTRATOR */
1180
1181 #define VID_LEN_8 8
1182 static const guint8 VID_draft_ietf_ipsec_antireplay_00[VID_LEN_8]= {0x32, 0x5D, 0xF2, 0x9A, 0x23, 0x19, 0xF2, 0xDD}; /* draft-ietf-ipsec-antireplay-00.txt */
1183
1184 static const guint8 VID_draft_ietf_ipsec_heartbeats_00[VID_LEN_8]= {0x8D, 0xB7, 0xA4, 0x18, 0x11, 0x22, 0x16, 0x60}; /* draft-ietf-ipsec-heartbeats-00.txt */
1185
1186 /*
1187 *  Seen in Netscreen. Suppose to be ASCII HeartBeat_Notify - but I don't know the rest yet. I suspect it then proceeds with
1188 *  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
1189 *  means. ykaul-at-bezeqint.net
1190 */
1191 static const guint8 VID_HeartBeat_Notify[VID_LEN] _U_ = {0x48, 0x65, 0x61, 0x72, 0x74, 0x42, 0x65, 0x61, 0x74, 0x5f, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79};
1192
1193 static void
1194 dissect_payloads(tvbuff_t *tvb, proto_tree *tree, proto_tree *parent_tree,
1195                 int isakmp_version, guint8 initial_payload, int offset, int length,
1196                 packet_info *pinfo)
1197 {
1198   guint8 payload, next_payload;
1199   guint16               payload_length;
1200   proto_tree *          ntree;
1201   struct payload_func * f;
1202
1203   for (payload = initial_payload; length > 0; payload = next_payload) {
1204     if (payload == LOAD_TYPE_NONE) {
1205       /*
1206        * What?  There's more stuff in this chunk of data, but the
1207        * previous payload had a "next payload" type of None?
1208        */
1209       proto_tree_add_text(tree, tvb, offset, length,
1210                           "Extra data: %s",
1211                           tvb_bytes_to_str(tvb, offset, length));
1212       break;
1213     }
1214     ntree = dissect_payload_header(tvb, offset, length, isakmp_version,
1215       payload, &next_payload, &payload_length, tree);
1216     if (ntree == NULL)
1217       break;
1218     if (payload_length >= 4) {  /* XXX = > 4? */
1219       tvb_ensure_bytes_exist(tvb, offset + 4, payload_length - 4);
1220       if ((f = getpayload_func(payload, isakmp_version)) != NULL && f->func != NULL)
1221         (*f->func)(tvb, offset + 4, payload_length - 4, ntree, parent_tree,
1222                    pinfo, isakmp_version, -1, next_payload);
1223       else {
1224         proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4,
1225                             "Payload");
1226       }
1227     }
1228     else if (payload_length > length) {
1229         proto_tree_add_text(ntree, tvb, 0, 0,
1230                             "Payload (bogus, length is %u, greater than remaining length %d",
1231                             payload_length, length);
1232         return;
1233     }
1234     else {
1235         proto_tree_add_text(ntree, tvb, 0, 0,
1236                             "Payload (bogus, length is %u, must be at least 4)",
1237                             payload_length);
1238         payload_length = 4;
1239     }
1240     offset += payload_length;
1241     length -= payload_length;
1242   }
1243 }
1244
1245 void
1246 isakmp_dissect_payloads(tvbuff_t *tvb, proto_tree *tree, int isakmp_version,
1247                         guint8 initial_payload, int offset, int length,
1248                         packet_info *pinfo)
1249 {
1250   dissect_payloads(tvb, tree, tree, isakmp_version, initial_payload, offset, length,
1251                    pinfo);
1252 }
1253
1254 static struct payload_func *
1255 getpayload_func(guint8 payload, int isakmp_version)
1256 {
1257   struct payload_func *f = 0;
1258   int i, len;
1259
1260   if (isakmp_version == 1) {
1261     f = v1_plfunc;
1262     len = ARLEN(v1_plfunc);
1263   } else if (isakmp_version == 2) {
1264     f = v2_plfunc;
1265     len = ARLEN(v2_plfunc);
1266   } else
1267     return NULL;
1268   for (i = 0; i < len; i++) {
1269     if (f[i].type == payload)
1270       return &f[i];
1271   }
1272   return NULL;
1273 }
1274
1275 static void
1276 dissect_isakmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1277 {
1278   int                   offset = 0, len;
1279   isakmp_hdr_t  hdr;
1280   proto_item *  ti;
1281   proto_tree *  isakmp_tree = NULL;
1282   int                   isakmp_version;
1283 #ifdef HAVE_LIBGCRYPT
1284   guint8                i_cookie[COOKIE_SIZE], *ic_key;
1285   decrypt_data_t       *decr = NULL;
1286   tvbuff_t             *decr_tvb;
1287   proto_tree           *decr_tree;
1288   address               null_addr;
1289   void                 *pd_save = NULL;
1290   gboolean             pd_changed = FALSE;
1291 #endif /* HAVE_LIBGCRYPT */
1292
1293   col_set_str(pinfo->cinfo, COL_PROTOCOL, "ISAKMP");
1294   col_clear(pinfo->cinfo, COL_INFO);
1295
1296   if (tree) {
1297     ti = proto_tree_add_item(tree, proto_isakmp, tvb, offset, -1, FALSE);
1298     isakmp_tree = proto_item_add_subtree(ti, ett_isakmp);
1299   }
1300
1301   /* RFC3948 2.3 NAT Keepalive packet:
1302    * 1 byte payload with the value 0xff.
1303    */
1304   if( (tvb_length(tvb)==1) && (tvb_get_guint8(tvb, offset)==0xff) ){
1305     col_set_str(pinfo->cinfo, COL_INFO, "NAT Keepalive");
1306     proto_tree_add_item(isakmp_tree, hf_isakmp_nat_keepalive, tvb, offset, 1, FALSE);
1307     return;
1308   }
1309
1310   hdr.length = tvb_get_ntohl(tvb, offset + ISAKMP_HDR_SIZE - 4);
1311   hdr.exch_type = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1 + 1);
1312   hdr.version = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1);
1313   isakmp_version = hi_nibble(hdr.version);      /* save the version */
1314   hdr.flags = tvb_get_guint8(tvb, COOKIE_SIZE + COOKIE_SIZE + 1 + 1 + 1);
1315   if (check_col(pinfo->cinfo, COL_INFO))
1316     col_add_str(pinfo->cinfo, COL_INFO,
1317                 exchtype2str(isakmp_version, hdr.exch_type));
1318
1319 #ifdef HAVE_LIBGCRYPT
1320   if (isakmp_version == 1) {
1321     SET_ADDRESS(&null_addr, AT_NONE, 0, NULL);
1322
1323     tvb_memcpy(tvb, i_cookie, offset, COOKIE_SIZE);
1324     decr = (decrypt_data_t*) g_hash_table_lookup(isakmp_hash, i_cookie);
1325
1326     if (! decr) {
1327 #if GLIB_CHECK_VERSION(2,10,0)
1328       ic_key = g_slice_alloc(COOKIE_SIZE);
1329       decr   = g_slice_alloc(sizeof(decrypt_data_t));
1330 #else
1331       ic_key = g_mem_chunk_alloc(isakmp_key_data);
1332       decr   = g_mem_chunk_alloc(isakmp_decrypt_data);
1333 #endif
1334       memcpy(ic_key, i_cookie, COOKIE_SIZE);
1335       memset(decr, 0, sizeof(decrypt_data_t));
1336       SET_ADDRESS(&decr->initiator, AT_NONE, 0, NULL);
1337
1338       g_hash_table_insert(isakmp_hash, ic_key, decr);
1339     }
1340
1341     if (ADDRESSES_EQUAL(&decr->initiator, &null_addr)) {
1342       /* XXX - We assume that we're seeing the second packet in an exchange here.
1343        * Is there a way to verify this? */
1344       SE_COPY_ADDRESS(&decr->initiator, &pinfo->src);
1345     }
1346
1347     pd_save = pinfo->private_data;
1348     pinfo->private_data = decr;
1349     pd_changed = TRUE;
1350   } else if (isakmp_version == 2) {
1351     ikev2_uat_data_key_t hash_key;
1352     ikev2_uat_data_t *ike_sa_data = NULL;
1353     ikev2_decrypt_data_t *ikev2_dec_data;
1354     guchar spii[COOKIE_SIZE], spir[COOKIE_SIZE];
1355
1356     tvb_memcpy(tvb, spii, offset, COOKIE_SIZE);
1357     tvb_memcpy(tvb, spir, offset + COOKIE_SIZE, COOKIE_SIZE);
1358     hash_key.spii = spii;
1359     hash_key.spir = spir;
1360     hash_key.spii_len = COOKIE_SIZE;
1361     hash_key.spir_len = COOKIE_SIZE;
1362
1363     ike_sa_data = g_hash_table_lookup(ikev2_key_hash, &hash_key);
1364     if (ike_sa_data) {
1365       guint8 initiator_flag;
1366       initiator_flag = hdr.flags & I_FLAG;
1367       ikev2_dec_data = ep_alloc(sizeof(ikev2_decrypt_data_t));
1368       ikev2_dec_data->encr_key = initiator_flag ? ike_sa_data->sk_ei : ike_sa_data->sk_er;
1369       ikev2_dec_data->auth_key = initiator_flag ? ike_sa_data->sk_ai : ike_sa_data->sk_ar;
1370       ikev2_dec_data->encr_spec = ike_sa_data->encr_spec;
1371       ikev2_dec_data->auth_spec = ike_sa_data->auth_spec;
1372
1373       pd_save = pinfo->private_data;
1374       pinfo->private_data = ikev2_dec_data;
1375       pd_changed = TRUE;
1376     }
1377   }
1378 #endif /* HAVE_LIBGCRYPT */
1379
1380   if (tree) {
1381     proto_tree_add_item(isakmp_tree, hf_isakmp_icookie, tvb, offset, COOKIE_SIZE, FALSE);
1382     offset += COOKIE_SIZE;
1383
1384     proto_tree_add_item(isakmp_tree, hf_isakmp_rcookie, tvb, offset, COOKIE_SIZE, FALSE);
1385     offset += COOKIE_SIZE;
1386
1387     hdr.next_payload = tvb_get_guint8(tvb, offset);
1388     proto_tree_add_uint_format(isakmp_tree, hf_isakmp_nextpayload, tvb, offset,
1389                                1, hdr.next_payload,
1390                                "Next payload: %s (%u)",
1391                                payloadtype2str(isakmp_version, hdr.next_payload),
1392                                hdr.next_payload);
1393     offset += 1;
1394
1395     proto_tree_add_uint_format(isakmp_tree, hf_isakmp_version, tvb, offset,
1396                                1, hdr.version, "Version: %u.%u",
1397                                hi_nibble(hdr.version), lo_nibble(hdr.version));
1398     offset += 1;
1399
1400     hdr.exch_type = tvb_get_guint8(tvb, offset);
1401     proto_tree_add_uint_format(isakmp_tree, hf_isakmp_exchangetype, tvb, offset,
1402                                1, hdr.exch_type,
1403                                "Exchange type: %s (%u)",
1404                                exchtype2str(isakmp_version, hdr.exch_type),
1405                                hdr.exch_type);
1406     offset += 1;
1407
1408     {
1409       proto_item *      fti;
1410       proto_tree *      ftree;
1411
1412       fti   = proto_tree_add_item(isakmp_tree, hf_isakmp_flags, tvb, offset, 1, FALSE);
1413       ftree = proto_item_add_subtree(fti, ett_isakmp_flags);
1414
1415       if (isakmp_version == 1) {
1416         proto_tree_add_item(ftree, hf_isakmp_flag_e, tvb, offset, 1, FALSE);
1417
1418         proto_tree_add_item(ftree, hf_isakmp_flag_c, tvb, offset, 1, FALSE);
1419                                                  
1420         proto_tree_add_item(ftree, hf_isakmp_flag_a, tvb, offset, 1, FALSE);
1421                                                  
1422       } else if (isakmp_version == 2) {
1423         proto_tree_add_item(ftree, hf_isakmp_flag_i, tvb, offset, 1, FALSE);
1424                                                  
1425         proto_tree_add_item(ftree, hf_isakmp_flag_v, tvb, offset, 1, FALSE);
1426                                                   
1427         proto_tree_add_item(ftree, hf_isakmp_flag_r, tvb, offset, 1, FALSE);
1428                                                  
1429       }
1430       offset += 1;
1431     }
1432
1433     hdr.message_id = tvb_get_ntohl(tvb, offset);
1434     proto_tree_add_item(isakmp_tree, hf_isakmp_messageid, tvb, offset, 4, FALSE);
1435     offset += 4;
1436
1437     if (hdr.length < ISAKMP_HDR_SIZE) {
1438       proto_tree_add_uint_format(isakmp_tree, hf_isakmp_length, tvb, offset, 4,
1439                                  hdr.length, "Length: (bogus, length is %u, should be at least %lu)",
1440                                  hdr.length, (unsigned long)ISAKMP_HDR_SIZE);
1441 #ifdef HAVE_LIBGCRYPT
1442       if (pd_changed) pinfo->private_data = pd_save;
1443 #endif /* HAVE_LIBGCRYPT */
1444       return;
1445     }
1446
1447     len = hdr.length - ISAKMP_HDR_SIZE;
1448
1449     if (len < 0) {
1450       proto_tree_add_uint_format(isakmp_tree, hf_isakmp_length, tvb, offset, 4,
1451                                  hdr.length, "Length: (bogus, length is %u, which is too large)",
1452                                  hdr.length);
1453 #ifdef HAVE_LIBGCRYPT
1454       if (pd_changed) pinfo->private_data = pd_save;
1455 #endif /* HAVE_LIBGCRYPT */
1456       return;
1457     }
1458
1459     proto_tree_add_item(isakmp_tree, hf_isakmp_length, tvb, offset, 4, FALSE);
1460     offset += 4;
1461
1462     if (hdr.flags & E_FLAG) {
1463       if (len && isakmp_tree) {
1464         ti = proto_tree_add_text(isakmp_tree, tvb, offset, len,
1465                                  "Encrypted payload (%d byte%s)",
1466                                  len, plurality(len, "", "s"));
1467 #ifdef HAVE_LIBGCRYPT
1468
1469         if (decr) {
1470           decr_tvb = decrypt_payload(tvb, pinfo, tvb_get_ptr(tvb, offset, len), len, &hdr);
1471           if (decr_tvb) {
1472             decr_tree = proto_item_add_subtree(ti, ett_isakmp);
1473             dissect_payloads(decr_tvb, decr_tree, tree, isakmp_version,
1474                              hdr.next_payload, 0, tvb_length(decr_tvb), pinfo);
1475           }
1476         }
1477 #endif /* HAVE_LIBGCRYPT */
1478       }
1479     } else
1480       dissect_payloads(tvb, isakmp_tree, tree, isakmp_version, hdr.next_payload,
1481                        offset, len, pinfo);
1482   }
1483 #ifdef HAVE_LIBGCRYPT
1484   if (pd_changed) pinfo->private_data = pd_save;
1485 #endif /* HAVE_LIBGCRYPT */
1486 }
1487
1488 static proto_tree *
1489 dissect_payload_header(tvbuff_t *tvb, int offset, int length,
1490     int isakmp_version, guint8 payload, guint8 *next_payload_p,
1491     guint16 *payload_length_p, proto_tree *tree)
1492 {
1493   guint8                next_payload;
1494   guint16               payload_length;
1495   proto_item *          ti;
1496   proto_tree *          ntree;
1497
1498   if (length < 4) {
1499     proto_tree_add_text(tree, tvb, offset, length,
1500                         "Not enough room in payload for all transforms");
1501     return NULL;
1502   }
1503   next_payload = tvb_get_guint8(tvb, offset);
1504   payload_length = tvb_get_ntohs(tvb, offset + 2);
1505
1506   /* This is ugly, but the code is too inflexible to handle this at the
1507    * proper place (dissect_vid)
1508    */
1509   if (payload == 13) { /* Vendor ID */
1510     ti = proto_tree_add_text(tree, tvb, offset, payload_length,
1511                              "%s: %s", payloadtype2str(isakmp_version, payload),
1512                              vid_to_str(tvb, offset + 4, payload_length - 4));
1513   } else {
1514     ti = proto_tree_add_text(tree, tvb, offset, payload_length,
1515                              "%s payload", payloadtype2str(isakmp_version, payload));
1516   }
1517   ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
1518
1519   proto_tree_add_uint_format(ntree, hf_isakmp_nextpayload, tvb, offset, 1,
1520                              next_payload, "Next payload: %s (%u)",
1521                              payloadtype2str(isakmp_version, next_payload),
1522                              next_payload);
1523   if (isakmp_version == 2) {
1524     proto_tree_add_text(ntree, tvb, offset + 1, 1, "%s",
1525                         decode_boolean_bitfield(tvb_get_guint8(tvb, offset + 1), 0x80,
1526                                                 8, "Critical", "Not critical"));
1527   }
1528   proto_tree_add_item(ntree, hf_isakmp_payloadlen, tvb, offset + 2, 2, FALSE);
1529
1530   *next_payload_p = next_payload;
1531   *payload_length_p = payload_length;
1532   return ntree;
1533 }
1534
1535 static void
1536 dissect_sa(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1537            proto_tree *p _U_, packet_info *pinfo, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
1538 {
1539   guint32               doi;
1540   guint32               situation;
1541
1542   if (length < 4) {
1543     proto_tree_add_text(tree, tvb, offset, length,
1544                         "DOI %s (length is %u, should be >= 4)",
1545                         tvb_bytes_to_str(tvb, offset, length), length);
1546     return;
1547   }
1548   if (isakmp_version == 1) {
1549     doi = tvb_get_ntohl(tvb, offset);
1550     proto_tree_add_uint_format(tree, hf_isakmp_doi, tvb, offset, 4,
1551                                doi, "Domain of interpretation: %s (%u)",
1552                                doitype2str(doi), doi);
1553     offset += 4;
1554     length -= 4;
1555
1556     if (doi == 1) {
1557       /* IPSEC */
1558       if (length < 4) {
1559         proto_tree_add_bytes_format(tree, hf_isakmp_sa_situation, tvb, offset, length,
1560                                     tvb_get_ptr(tvb, offset, length),
1561                                     "Situation: %s (length is %u, should be >= 4)",
1562                                     tvb_bytes_to_str(tvb, offset, length), length);
1563         return;
1564       }
1565       situation = tvb_get_ntohl(tvb, offset);
1566       proto_tree_add_bytes_format(tree, hf_isakmp_sa_situation, tvb, offset, 4,
1567                                   tvb_get_ptr(tvb, offset, 4), "Situation: %s (%u)",
1568                                   situation2str(situation), situation);
1569       offset += 4;
1570       length -= 4;
1571
1572       dissect_payloads(tvb, tree, tree, isakmp_version, LOAD_TYPE_PROPOSAL, offset,
1573                        length, pinfo);
1574     } else {
1575       /* Unknown */
1576       proto_tree_add_item(tree, hf_isakmp_sa_situation, tvb, offset, length, FALSE);
1577     }
1578   } else if (isakmp_version == 2) {
1579     dissect_payloads(tvb, tree, tree, isakmp_version, LOAD_TYPE_PROPOSAL, offset,
1580                      length, pinfo);
1581   }
1582 }
1583
1584 static void
1585 dissect_proposal(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1586                  proto_tree *p _U_,  packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
1587 {
1588   guint8                protocol_id;
1589   guint8                spi_size;
1590   guint8                num_transforms;
1591   guint8                next_payload;
1592   guint16               payload_length;
1593   proto_tree *          ntree;
1594   guint8                proposal_num;
1595
1596   proposal_num = tvb_get_guint8(tvb, offset);
1597
1598   proto_item_append_text(tree, " # %d", proposal_num);
1599
1600   proto_tree_add_item(tree, hf_isakmp_prop_number, tvb, offset, 1, FALSE);
1601   offset += 1;
1602   length -= 1;
1603
1604   protocol_id = tvb_get_guint8(tvb, offset);
1605   proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
1606                              protocol_id, "Protocol ID: %s (%u)",
1607                              val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
1608   offset += 1;
1609   length -= 1;
1610
1611   spi_size = tvb_get_guint8(tvb, offset);
1612   proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
1613   offset += 1;
1614   length -= 1;
1615
1616   num_transforms = tvb_get_guint8(tvb, offset);
1617   proto_tree_add_item(tree, hf_isakmp_prop_transforms, tvb, offset, 1, FALSE);
1618   offset += 1;
1619   length -= 1;
1620
1621   if (spi_size) {
1622     proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
1623                         tvb_bytes_to_str(tvb, offset, spi_size));
1624     offset += spi_size;
1625     length -= spi_size;
1626   }
1627
1628   while (num_transforms > 0) {
1629     ntree = dissect_payload_header(tvb, offset, length, isakmp_version,
1630                                    LOAD_TYPE_TRANSFORM, &next_payload, &payload_length, tree);
1631     if (ntree == NULL)
1632       break;
1633     if (length < payload_length) {
1634       proto_tree_add_text(tree, tvb, offset + 4, length,
1635                           "Not enough room in payload for all transforms");
1636       break;
1637     }
1638     if (payload_length >= 4) {
1639       if (isakmp_version == 1)
1640         dissect_transform(tvb, offset + 4, payload_length - 4, ntree,
1641                           ntree, pinfo, isakmp_version, protocol_id, 0);
1642       else if (isakmp_version == 2)
1643         dissect_transform2(tvb, offset + 4, payload_length - 4, ntree,
1644                            ntree, pinfo, isakmp_version, protocol_id, 0);
1645     }
1646     else
1647       proto_tree_add_text(ntree, tvb, offset + 4, payload_length - 4, "Payload");
1648     offset += payload_length;
1649     length -= payload_length;
1650     num_transforms--;
1651   }
1652 }
1653
1654 static void
1655 dissect_transform(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
1656                   proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
1657                   int protocol_id, guint8 inner_payload _U_)
1658 {
1659   static const value_string vs_v1_attr[] = {
1660     { 1,        "Encryption-Algorithm" },
1661     { 2,        "Hash-Algorithm" },
1662     { 3,        "Authentication-Method" },
1663     { 4,        "Group-Description" },
1664     { 5,        "Group-Type" },
1665     { 6,        "Group-Prime" },
1666     { 7,        "Group-Generator-One" },
1667     { 8,        "Group-Generator-Two" },
1668     { 9,        "Group-Curve-A" },
1669     { 10,       "Group-Curve-B" },
1670     { 11,       "Life-Type" },
1671     { 12,       "Life-Duration" },
1672     { 13,       "PRF" },
1673     { 14,       "Key-Length" },
1674     { 15,       "Field-Size" },
1675     { 16,       "Group-Order" },
1676     { 0,        NULL },
1677   };
1678
1679   static const value_string vs_v2_sttr[] = {
1680     { 1,        "SA-Life-Type" },
1681     { 2,        "SA-Life-Duration" },
1682     { 3,        "Group-Description" },
1683     { 4,        "Encapsulation-Mode" },
1684     { 5,        "Authentication-Algorithm" },
1685     { 6,        "Key-Length" },
1686     { 7,        "Key-Rounds" },
1687     { 8,        "Compress-Dictionary-Size" },
1688     { 9,        "Compress-Private-Algorithm" },
1689     { 10,       "ECN Tunnel" },
1690     { 0,        NULL },
1691   };
1692
1693   static const value_string vs_v1_trans_isakmp[] = {
1694     { 0,        "RESERVED" },
1695     { 1,        "KEY_IKE" },
1696     { 0,        NULL },
1697   };
1698
1699   static const value_string vs_v1_trans_ah[] = {
1700     { 0,        "RESERVED" },
1701     { 1,        "RESERVED" },
1702     { 2,        "MD5" },
1703     { 3,        "SHA" },
1704     { 4,        "DES" },
1705     { 5,        "SHA2-256" },
1706     { 6,        "SHA2-384" },
1707     { 7,        "SHA2-512" },
1708     { 0,        NULL },
1709   };
1710
1711   static const value_string vs_v1_trans_esp[] = {
1712     { 0,        "RESERVED" },
1713     { 1,        "DES-IV64" },
1714     { 2,        "DES" },
1715     { 3,        "3DES" },
1716     { 4,        "RC5" },
1717     { 5,        "IDEA" },
1718     { 6,        "CAST" },
1719     { 7,        "BLOWFISH" },
1720     { 8,        "3IDEA" },
1721     { 9,        "DES-IV32" },
1722     { 10,       "RC4" },
1723     { 11,       "NULL" },
1724     { 12,       "AES" },
1725     { 0,        NULL },
1726   };
1727
1728   static const value_string vs_v1_trans_ipcomp[] = {
1729     { 0,        "RESERVED" },
1730     { 1,        "OUI" },
1731     { 2,        "DEFLATE" },
1732     { 3,        "LZS" },
1733     { 4,        "LZJH" },
1734     { 0,        NULL },
1735   };
1736
1737   guint8                transform_id;
1738   guint8                transform_num;
1739 #ifdef HAVE_LIBGCRYPT
1740   decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
1741 #endif /* HAVE_LIBGCRYPT */
1742
1743   transform_num = tvb_get_guint8(tvb, offset);
1744   proto_item_append_text(tree," # %d",transform_num);
1745   proto_tree_add_item(tree, hf_isakmp_trans_number, tvb, offset, 1, FALSE);
1746   offset += 1;
1747   length -= 1;
1748
1749   transform_id = tvb_get_guint8(tvb, offset);
1750   switch (protocol_id) {
1751   default:
1752     proto_tree_add_item(tree, hf_isakmp_trans_id, tvb, offset, 1, FALSE);
1753     break;
1754   case 1:       /* ISAKMP */
1755     proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1756                         transform_id, "Transform ID: %s (%u)",
1757                         val_to_str(transform_id, vs_v1_trans_isakmp, "UNKNOWN-TRANS-TYPE"), transform_id);
1758     break;
1759   case 2:       /* AH */
1760     proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1761                         transform_id, "Transform ID: %s (%u)",
1762                         val_to_str(transform_id, vs_v1_trans_ah, "UNKNOWN-AH-TRANS-TYPE"), transform_id);
1763     break;
1764   case 3:       /* ESP */
1765     proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1766                         transform_id, "Transform ID: %s (%u)",
1767                         val_to_str(transform_id, vs_v1_trans_esp, "UNKNOWN-ESP-TRANS-TYPE"), transform_id);
1768     break;
1769   case 4:       /* IPCOMP */
1770     proto_tree_add_uint_format(tree, hf_isakmp_trans_id, tvb, offset, 1,
1771                         transform_id, "Transform ID: %s (%u)",
1772                         val_to_str(transform_id, vs_v1_trans_ipcomp, "UNKNOWN-IPCOMP-TRANS-TYPE"), transform_id);
1773     break;
1774   }
1775   offset += 3;
1776   length -= 3;
1777
1778   while (length>0) {
1779     const char *str;
1780     int ike_phase1  = 0;
1781     guint16 aft     = tvb_get_ntohs(tvb, offset);
1782     guint16 type    = aft & 0x7fff;
1783     guint16 len;
1784     guint32 val;
1785     guint pack_len;
1786
1787     /* XXX - Add header fields */
1788     if (protocol_id == 1 && transform_id == 1) {
1789       ike_phase1 = 1;
1790       str = val_to_str(type, vs_v1_attr, "UNKNOWN-ATTRIBUTE-TYPE");
1791     }
1792     else {
1793       str = val_to_str(type, vs_v2_sttr, "UNKNOWN-ATTRIBUTE-TYPE");
1794     }
1795
1796     if (aft & 0x8000) {
1797       val = tvb_get_ntohs(tvb, offset + 2);
1798       proto_tree_add_text(tree, tvb, offset, 4,
1799                           "%s (%u): %s (%u)",
1800                           str, type,
1801                           v1_attrval2str(ike_phase1, type, val), val);
1802 #ifdef HAVE_LIBGCRYPT
1803       set_transform_vals(decr, ike_phase1, type, val);
1804 #endif
1805       offset += 4;
1806       length -= 4;
1807     }
1808     else {
1809       len = tvb_get_ntohs(tvb, offset + 2);
1810       pack_len = 4 + len;
1811       if (!get_num(tvb, offset + 4, len, &val)) {
1812         proto_tree_add_text(tree, tvb, offset, pack_len,
1813                             "%s (%u): <too big (%u bytes)>",
1814                             str, type, len);
1815       } else {
1816         proto_tree_add_text(tree, tvb, offset, pack_len,
1817                             "%s (%u): %s (%u)",
1818                             str, type,
1819                             v1_attrval2str(ike_phase1, type, val), val);
1820 #ifdef HAVE_LIBGCRYPT
1821         set_transform_vals(decr, ike_phase1, type, val);
1822 #endif
1823       }
1824       offset += pack_len;
1825       length -= pack_len;
1826     }
1827   }
1828 }
1829
1830 /* For Transform Type 1 (Encryption Algorithm), defined Transform IDs */
1831 static const char *
1832 v2_tid2encstr(guint16 tid)
1833 {
1834   static const value_string vs_v2_trans_enc[] = {
1835     { 0,        "RESERVED" },
1836     { 1,        "ENCR_DES_IV64" },
1837     { 2,        "ENCR_DES" },
1838     { 3,        "ENCR_3DES" },
1839     { 4,        "ENCR_RC5" },
1840     { 5,        "ENCR_IDEA" },
1841     { 6,        "ENCR_CAST" },
1842     { 7,        "ENCR_BLOWFISH" },
1843     { 8,        "ENCR_3IDEA" },
1844     { 9,        "ENCR_DES_IV32" },
1845     { 10,       "RESERVED" },
1846     { 11,       "ENCR_NULL" },
1847     { 12,       "ENCR_AES_CBC" },
1848     { 13,       "ENCR_AES_CTR" },                /* [RFC3686] */
1849     { 14,       "ENCR_AES-CCM_8" },              /* [RFC4309] */
1850     { 15,       "ENCR-AES-CCM_12" },             /* [RFC4309] */
1851     { 16,       "ENCR-AES-CCM_16" },             /* [RFC4309] */
1852     { 17,       "UNASSIGNED" },
1853     { 18,       "AES-GCM with a 8 octet ICV" },  /* [RFC4106] */
1854     { 19,       "AES-GCM with a 12 octet ICV" }, /* [RFC4106] */
1855     { 20,       "AES-GCM with a 16 octet ICV" }, /* [RFC4106] */
1856     { 21,       "ENCR_NULL_AUTH_AES_GMAC" },     /* [RFC4543] */
1857 /*
1858  *              22-1023    RESERVED TO IANA         [RFC4306]
1859  *              1024-65535    PRIVATE USE           [RFC4306]
1860  */
1861     { 0,        NULL },
1862   };
1863
1864   return val_to_str(tid, vs_v2_trans_enc, "UNKNOWN-ENC-ALG");
1865 }
1866
1867 /* For Transform Type 2 (Pseudo-random Function), defined Transform IDs */
1868 static const char *
1869 v2_tid2prfstr(guint16 tid)
1870 {
1871   static const value_string vs_v2_trans_prf[] = {
1872     { 0,        "RESERVED" },
1873     { 1,        "PRF_HMAC_MD5" },
1874     { 2,        "PRF_HMAC_SHA1" },
1875     { 3,        "PRF_HMAC_TIGER" },
1876     { 4,        "PRF_AES128_CBC" },
1877     { 5,        "RESERVED TO IANA" },           /* [RFC4306] */
1878     { 6,        "RESERVED TO IANA" },           /* [RFC4306] */
1879     { 7,        "RESERVED TO IANA" },           /* [RFC4306] */
1880     { 8,        "PRF_AES128_CMAC6" },           /* [RFC4615] */
1881         /*
1882      9-1023    RESERVED TO IANA                    [RFC4306]
1883          1024-65535    PRIVATE USE                 [RFC4306]
1884          */
1885     { 0,        NULL },
1886   };
1887   return val_to_str(tid, vs_v2_trans_prf, "UNKNOWN-PRF");
1888 }
1889
1890 /* For Transform Type 3 (Integrity Algorithm), defined Transform IDs */
1891 static const char *
1892 v2_tid2iastr(guint16 tid)
1893 {
1894   static const value_string vs_v2_trans_integrity[] = {
1895     { 0,        "NONE" },
1896     { 1,        "AUTH_HMAC_MD5_96" },
1897     { 2,        "AUTH_HMAC_SHA1_96" },
1898     { 3,        "AUTH_DES_MAC" },
1899     { 4,        "AUTH_KPDK_MD5" },
1900     { 5,        "AUTH_AES_XCBC_96" },
1901     { 6,        "AUTH_HMAC_MD5_128" },          /* [RFC-maino-fcsp-02.txt] */
1902     { 7,        "AUTH_HMAC_SHA1_160" },         /* [RFC-maino-fcsp-02.txt] */
1903     { 8,        "AUTH_AES_CMAC_96" },           /* [RFC4494] */
1904     { 9,        "AUTH_AES_128_GMAC" },          /* [RFC4543] */
1905     { 10,       "AUTH_AES_192_GMAC" },          /* [RFC4543] */
1906     { 11,       "AUTH_AES_256_GMAC" },          /* [RFC4543] */
1907         /*
1908     12-1023    RESERVED TO IANA                    [RFC4306]
1909  1024-65535    PRIVATE USE                         [RFC4306]
1910  */
1911     { 0,        NULL },
1912   };
1913   return val_to_str(tid, vs_v2_trans_integrity, "UNKNOWN-INTEGRITY-ALG");
1914 }
1915
1916 /* For Transform Type 4 (Diffie-Hellman Group), defined Transform IDs */
1917 static const char *
1918 v2_tid2dhstr(guint16 tid)
1919 {
1920   static const value_string vs_v2_trans_dhgroup[] = {
1921     {  0,       "NONE" },
1922     {  1,       "Group 1 - 768 Bit MODP" },
1923     {  2,       "Group 2 - 1024 Bit MODP" },
1924     {  3,       "RESERVED" },
1925     {  4,       "RESERVED" },
1926     {  5,       "group 5 - 1536 Bit MODP" },
1927         /* 6-13    RESERVED TO IANA                [RFC4306] */
1928     { 14,       "2048-bit MODP Group" },
1929     { 15,       "3072-bit MODP Group" },
1930     { 16,       "4096-bit MODP Group" },
1931     { 17,       "6144-bit MODP Group" },
1932     { 18,       "8192-bit MODP Group" },
1933     { 19,       "256-bit random ECP group" },   /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1934     { 20,       "384-bit random ECP group" },   /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1935     { 21,       "521-bit random ECP group" },   /* [RFC-ietf-ipsec-ike-ecp-groups-02.txt]*/
1936         /*
1937     22-1023    RESERVED TO IANA                    [RFC4306]
1938  1024-65535    PRIVATE USE                         [RFC4306]
1939  */
1940     { 0,        NULL },
1941   };
1942
1943   if ((tid >= 6 && tid <= 13) || (tid >= 22 && tid <= 1023))
1944     return "RESERVED TO IANA";
1945   if (tid >= 1024)
1946     return "PRIVATE USE";
1947   return val_to_str(tid, vs_v2_trans_dhgroup, "UNKNOWN-DH-GROUP");
1948 }
1949
1950 /* For Transform Type 5 (Extended Sequence Numbers), defined Transform */
1951 static const char *
1952 v2_tid2esnstr(guint16 tid)
1953 {
1954   static const value_string vs_v2_trans_esn[] = {
1955     { 0,        "No Extended Sequence Numbers" },
1956     { 1,        "Extended Sequence Numbers" },
1957     { 0,        NULL },
1958   };
1959
1960   return val_to_str(tid, vs_v2_trans_esn, "UNKNOWN-ESN-TYPE");
1961 }
1962
1963 static struct {
1964   const gint8 type;
1965   const char *str;
1966   const char *(*func)(guint16);
1967 } v2_tid_func[] = {
1968   { 0,  "RESERVED", NULL, },
1969   { 1,  "Encryption Algorithm (ENCR)",     v2_tid2encstr },
1970   { 2,  "Pseudo-random Function (PRF)",    v2_tid2prfstr },
1971   { 3,  "Integrity Algorithm (INTEG)",     v2_tid2iastr },
1972   { 4,  "Diffie-Hellman Group (D-H)",      v2_tid2dhstr },
1973   { 5,  "Extended Sequence Numbers (ESN)", v2_tid2esnstr },
1974 };
1975
1976 static const char *
1977 v2_trans2str(guint8 type)
1978 {
1979   if (type < ARLEN(v2_tid_func)) return v2_tid_func[type].str;
1980   if (type < 240) return "RESERVED TO IANA";
1981   return "PRIVATE USE";
1982 }
1983
1984 static const char *
1985 v2_tid2str(guint8 type, guint16 tid)
1986 {
1987   if (type < ARLEN(v2_tid_func) && v2_tid_func[type].func != NULL) {
1988     return (v2_tid_func[type].func)(tid);
1989   }
1990   return "RESERVED";
1991 }
1992
1993 static const char *
1994 v2_aft2str(guint16 aft)
1995 {
1996   if (aft < 14 || (aft > 14 && aft < 18)) return "RESERVED";
1997   if (aft == 14) return "Key Length (in bits)";
1998   if (aft >= 18 && aft < 16384) return "RESERVED TO IANA";
1999   return "PRIVATE USE";
2000 }
2001
2002 static void
2003 dissect_transform2(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2004                    proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2005 {
2006   guint8 transform_type;
2007   guint16 transform_id;
2008
2009   transform_type = tvb_get_guint8(tvb, offset);
2010   proto_tree_add_text(tree, tvb, offset, 1,
2011     "Transform type: %s (%u)", v2_trans2str(transform_type), transform_type);
2012   offset += 2;
2013   length -= 2;
2014
2015   transform_id = tvb_get_ntohs(tvb, offset);
2016   proto_tree_add_text(tree, tvb, offset, 2,
2017     "Transform ID: %s (%u)", v2_tid2str(transform_type, transform_id),
2018     transform_id);
2019   offset += 2;
2020   length -= 2;
2021
2022   while (length>0) {
2023     const char *str;
2024     guint16 aft     = tvb_get_ntohs(tvb, offset);
2025     guint16 type    = aft & 0x7fff;
2026     guint16 len;
2027     guint32 val;
2028     guint pack_len;
2029
2030     str = v2_aft2str(type);
2031
2032     if (aft & 0x8000) {
2033       val = tvb_get_ntohs(tvb, offset + 2);
2034       proto_tree_add_text(tree, tvb, offset, 4,
2035                           "%s (%u): %s (%u)",
2036                           str, type,
2037                           v2_attrval2str(type), val);
2038       offset += 4;
2039       length -= 4;
2040     }
2041     else {
2042       len = tvb_get_ntohs(tvb, offset + 2);
2043       pack_len = 4 + len;
2044       if (!get_num(tvb, offset + 4, len, &val)) {
2045         proto_tree_add_text(tree, tvb, offset, pack_len,
2046                             "%s (%u): <too big (%u bytes)>",
2047                             str, type, len);
2048       } else {
2049         proto_tree_add_text(tree, tvb, offset, pack_len,
2050                             "%s (%u): %s (%u)",
2051                             str, type,
2052                             v2_attrval2str(type), val);
2053       }
2054       offset += pack_len;
2055       length -= pack_len;
2056     }
2057   }
2058 }
2059
2060 static void
2061 dissect_key_exch(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2062     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2063 {
2064   guint16 dhgroup;
2065 #ifdef HAVE_LIBGCRYPT
2066   decrypt_data_t *decr = (decrypt_data_t *) pinfo->private_data;
2067 #endif /* HAVE_LIBGCRYPT */
2068
2069   if (isakmp_version == 2) {
2070     dhgroup = tvb_get_ntohs(tvb, offset);
2071     proto_tree_add_text(tree, tvb, offset, 2,
2072                       "DH Group #: %u", dhgroup);
2073     offset += 4;
2074     length -= 4;
2075   }
2076
2077   proto_tree_add_text(tree, tvb, offset, length, "Key Exchange Data (%d bytes / %d bits)",
2078                       length, length * 8);
2079
2080 #ifdef HAVE_LIBGCRYPT
2081   if (decr && decr->gi_len == 0 && ADDRESSES_EQUAL(&decr->initiator, &pinfo->src)) {
2082     decr->gi = g_malloc(length);
2083     tvb_memcpy(tvb, decr->gi, offset, length);
2084     decr->gi_len = length;
2085   } else if (decr && decr->gr_len == 0 && !ADDRESSES_EQUAL(&decr->initiator, &pinfo->src)) {
2086     decr->gr = g_malloc(length);
2087     tvb_memcpy(tvb, decr->gr, offset, length);
2088     decr->gr_len = length;
2089   }
2090 #endif /* HAVE_LIBGCRYPT */
2091 }
2092
2093 static void
2094 dissect_id(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2095            proto_tree *p _U_, packet_info *pinfo, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2096 {
2097   guint8                id_type;
2098   guint8                protocol_id;
2099   guint16               port;
2100   asn1_ctx_t asn1_ctx;
2101   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2102
2103   id_type = tvb_get_guint8(tvb, offset);
2104   if(isakmp_version == 1)
2105   {
2106      proto_tree_add_item(tree, hf_isakmp_id_type_v1, tvb, offset, 1, FALSE);
2107   }else if(isakmp_version == 2)
2108   {
2109      proto_tree_add_item(tree, hf_isakmp_id_type_v2, tvb, offset, 1, FALSE);
2110   }
2111   offset += 1;
2112   length -= 1;
2113
2114   protocol_id = tvb_get_guint8(tvb, offset);
2115   if (protocol_id == 0) {
2116     proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2117                                protocol_id, "Protocol ID: Unused");
2118   } else {
2119     proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2120                                protocol_id, "Protocol ID: %s (%u)",
2121                                ipprotostr(protocol_id), protocol_id);
2122   }
2123   offset += 1;
2124   length -= 1;
2125
2126   port = tvb_get_ntohs(tvb, offset);
2127   if (port == 0)
2128     proto_tree_add_uint_format(tree, hf_isakmp_id_port, tvb, offset, 2,
2129                                port, "Port: Unused");
2130   else
2131     proto_tree_add_item(tree, hf_isakmp_id_port, tvb, offset, 2, FALSE);
2132   offset += 2;
2133   length -= 2;
2134
2135   /*
2136    * It shows strings of all types though some of types are not
2137    * supported in IKEv2 specification actually.
2138    */
2139   switch (id_type) {
2140     case IKE_ID_IPV4_ADDR:
2141       proto_tree_add_text(tree, tvb, offset, length,
2142                           "Identification data: %s",
2143                           ip_to_str(tvb_get_ptr(tvb, offset, 4)));
2144       break;
2145     case IKE_ID_FQDN:
2146     case IKE_ID_USER_FQDN:
2147       proto_tree_add_text(tree, tvb, offset, length,
2148                           "Identification data: %.*s", length,
2149                           tvb_get_ptr(tvb, offset, length));
2150       break;
2151     case IKE_ID_IPV4_ADDR_SUBNET:
2152     case IKE_ID_IPV4_ADDR_RANGE:
2153       proto_tree_add_text(tree, tvb, offset, length,
2154                           "Identification data: %s/%s",
2155                           ip_to_str(tvb_get_ptr(tvb, offset, 4)),
2156                           ip_to_str(tvb_get_ptr(tvb, offset+4, 4)));
2157       break;
2158     case IKE_ID_IPV6_ADDR:
2159       proto_tree_add_text(tree, tvb, offset, length,
2160                           "Identification data: %s",
2161                           ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)));
2162       break;
2163     case IKE_ID_IPV6_ADDR_SUBNET:
2164     case IKE_ID_IPV6_ADDR_RANGE:
2165       proto_tree_add_text(tree, tvb, offset, length,
2166                           "Identification data: %s/%s",
2167                           ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, 16)),
2168                           ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset+16, 16)));
2169       break;
2170     case IKE_ID_DER_ASN1_DN:
2171       dissect_x509if_Name(FALSE, tvb, offset, &asn1_ctx, tree,
2172                           hf_isakmp_certificate_authority);
2173       break;
2174     default:
2175       proto_tree_add_text(tree, tvb, offset, length, "Identification Data");
2176       break;
2177   }
2178 }
2179
2180 static void
2181 dissect_cert(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2182              proto_tree *p _U_, packet_info *pinfo, int isakmp_version,
2183              int unused _U_, guint8 inner_payload _U_)
2184 {
2185   guint8                cert_enc;
2186   asn1_ctx_t asn1_ctx;
2187   asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo);
2188
2189   cert_enc = tvb_get_guint8(tvb, offset);
2190   proto_tree_add_uint_format(tree, hf_isakmp_cert_encoding, tvb, offset, 1,
2191                         cert_enc, "Certificate encoding: %u - %s",
2192                         cert_enc, certtype2str(isakmp_version, cert_enc));
2193   offset += 1;
2194   length -= 1;
2195
2196   dissect_x509af_Certificate(FALSE, tvb, offset, &asn1_ctx, tree, hf_isakmp_certificate);
2197 }
2198
2199 static void
2200 dissect_certreq_v1(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2201                    proto_tree *p _U_, packet_info *pinfo, int isakmp_version,
2202                    int unused _U_, guint8 inner_payload _U_)
2203 {
2204   guint8                cert_type;
2205   asn1_ctx_t asn1_ctx;
2206   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2207
2208   cert_type = tvb_get_guint8(tvb, offset);
2209   proto_tree_add_uint_format(tree, hf_isakmp_certreq_type, tvb, offset, 1,
2210                              cert_type, "Certificate type: %u - %s",
2211                              cert_type, certtype2str(isakmp_version, cert_type));
2212   offset += 1;
2213   length -= 1;
2214
2215   if (length) {
2216     if (cert_type == 4){
2217       dissect_x509if_Name(FALSE, tvb, offset, &asn1_ctx, tree, hf_isakmp_certificate_authority);
2218     } else {
2219       proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority");
2220     }
2221   }
2222   else
2223     proto_tree_add_text(tree, tvb, offset, length, "Certificate Authority (empty)");
2224 }
2225
2226 static void
2227 dissect_certreq_v2(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2228                    proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version,
2229                    int unused _U_, guint8 inner_payload _U_)
2230 {
2231   guint8                cert_type;
2232
2233   cert_type = tvb_get_guint8(tvb, offset);
2234   proto_tree_add_text(tree, tvb, offset, 1,
2235                       "Certificate type: %u - %s",
2236                       cert_type, certtype2str(isakmp_version, cert_type));
2237   offset += 1;
2238   length -= 1;
2239
2240   /* this is a list of 20 byte SHA-1 hashes */
2241   while (length > 0) {
2242     proto_tree_add_item(tree, hf_isakmp_v2_certificate_authority, tvb, offset, 20, FALSE);
2243     offset+=20;
2244     length-=20;
2245   }
2246 }
2247
2248 static void
2249 dissect_hash(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2250              proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2251              int unused _U_, guint8 inner_payload _U_)
2252 {
2253   proto_tree_add_text(tree, tvb, offset, length, "Hash Data");
2254 }
2255
2256 static void
2257 dissect_auth(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2258              proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2259              int unused _U_, guint8 inner_payload _U_)
2260 {
2261   guint8 auth;
2262
2263   auth = tvb_get_guint8(tvb, offset);
2264   proto_tree_add_text(tree, tvb, offset, 1,
2265                       "Auth Method: %s (%u)", v2_auth2str(auth), auth);
2266   offset += 4;
2267   length -= 4;
2268
2269   proto_tree_add_text(tree, tvb, offset, length, "Authentication Data");
2270 }
2271
2272 static void
2273 dissect_sig(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2274     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2275 {
2276   proto_tree_add_text(tree, tvb, offset, length, "Signature Data");
2277 }
2278
2279 static void
2280 dissect_cisco_fragmentation(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2281                             proto_tree *ptree, packet_info *pinfo, int isakmp_version _U_,
2282                             int unused _U_, guint8 inner_payload _U_)
2283 {
2284
2285   guint8 seq; /* Packet sequence number, starting from 1 */
2286   guint8 last;
2287
2288   if (length < 4)
2289     return;
2290
2291   proto_tree_add_item(tree, hf_isakmp_cisco_frag_packetid, tvb, offset, 2, FALSE);
2292   offset += 2;
2293   seq = tvb_get_guint8(tvb, offset);
2294   proto_tree_add_item(tree, hf_isakmp_cisco_frag_seq, tvb, offset, 1, FALSE);
2295   offset += 1;
2296   last = tvb_get_guint8(tvb, offset);
2297   proto_tree_add_item(tree, hf_isakmp_cisco_frag_last, tvb, offset, 1, FALSE);
2298   offset += 1;
2299   length-=4;
2300
2301   /* Start Reassembly stuff for Cisco IKE fragmentation */
2302   {
2303     gboolean save_fragmented;
2304     tvbuff_t *defrag_isakmp_tvb = NULL;
2305     fragment_data *frag_msg = NULL;
2306
2307     save_fragmented = pinfo->fragmented;
2308     pinfo->fragmented = TRUE;
2309     frag_msg = fragment_add_seq_check(tvb, offset, pinfo,
2310                                       12345,                    /*FIXME:  Fragmented packet id, guint16, somehow get CKY here */
2311                                       isakmp_fragment_table,    /* list of message fragments */
2312                                       isakmp_reassembled_table, /* list of reassembled messages */
2313                                       seq-1,                    /* fragment sequence number, starting from 0 */
2314                                       tvb_length_remaining(tvb, offset), /* fragment length - to the end */
2315                                       last);                    /* More fragments? */
2316     defrag_isakmp_tvb = process_reassembled_data(tvb, offset, pinfo,
2317                                                  "Reassembled ISAKMP", frag_msg, &isakmp_frag_items,
2318                                                  NULL, ptree);
2319
2320     if (defrag_isakmp_tvb) { /* take it all */
2321       dissect_isakmp(defrag_isakmp_tvb, pinfo, ptree);
2322     }
2323     if (check_col(pinfo->cinfo, COL_INFO))
2324       col_append_fstr(pinfo->cinfo, COL_INFO,
2325                       " (%sMessage fragment %u%s)",
2326                       (frag_msg ? "Reassembled + " : ""),
2327                       seq, (last ? " - last" : ""));
2328     pinfo->fragmented = save_fragmented;
2329   }
2330   /* End Reassembly stuff for Cisco IKE fragmentation */
2331
2332 }
2333
2334 static void
2335 dissect_nonce(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2336               proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2337               int unused _U_, guint8 inner_payload _U_)
2338 {
2339   proto_tree_add_text(tree, tvb, offset, length, "Nonce Data");
2340 }
2341
2342 static const char *
2343 v2_ipcomptype2str(guint8 type)
2344 {
2345   static const value_string vs_v2_ipcomptype[] = {
2346     { 0,        "RESERVED" },
2347     { 1,        "IPCOMP_OUI" },
2348     { 2,        "IPCOMP_DEFLATE" },
2349     { 3,        "IPCOMP_LZS" },
2350     { 4,        "IPCOMP_LZJH" },
2351     { 0,        NULL },
2352   };
2353
2354   if (type >= 5 && type <= 240)
2355     return "RESERVED TO IANA";
2356   if (type >= 241)
2357     return "PRIVATE USE";
2358   return val_to_str(type, vs_v2_ipcomptype, "UNKNOWN-IPCOMP-TYPE");
2359 }
2360
2361 static void
2362 dissect_notif(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2363     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2364 {
2365   guint32               doi;
2366   guint8                protocol_id;
2367   guint8                spi_size;
2368   guint16               msgtype;
2369   guint8                ipcomptype;
2370
2371   if (isakmp_version == 1) {
2372     doi = tvb_get_ntohl(tvb, offset);
2373     proto_tree_add_uint_format(tree, hf_isakmp_doi, tvb, offset, 4,
2374                         doi, "Domain of interpretation: %s (%u)",
2375                         doitype2str(doi), doi);
2376     offset += 4;
2377     length -= 4;
2378   }
2379
2380   protocol_id = tvb_get_guint8(tvb, offset);
2381   proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2382                         protocol_id, "Protocol ID: %s (%u)",
2383                         val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
2384   offset += 1;
2385   length -= 1;
2386
2387   spi_size = tvb_get_guint8(tvb, offset);
2388   proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
2389   offset += 1;
2390   length -= 1;
2391
2392   msgtype = tvb_get_ntohs(tvb, offset);
2393   proto_tree_add_uint_format(tree, hf_isakmp_notify_msgtype, tvb, offset, 2,
2394                         msgtype, "Message type: %s (%u)",
2395                         msgtype2str(isakmp_version, msgtype), msgtype);
2396   offset += 2;
2397   length -= 2;
2398
2399   if (spi_size) {
2400     proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
2401                         tvb_bytes_to_str(tvb, offset, spi_size));
2402     offset += spi_size;
2403     length -= spi_size;
2404   }
2405
2406   if (length > 0) {
2407     proto_tree_add_text(tree, tvb, offset, length, "Notification Data");
2408
2409     /* notification data */
2410     if (isakmp_version == 2 && msgtype == 16387) {
2411       /* IPCOMP_SUPPORTED */
2412       proto_tree_add_text(tree, tvb, offset, 2,
2413                         "IPComp CPI (%u)", tvb_get_ntohs(tvb, offset));
2414       ipcomptype = tvb_get_guint8(tvb, offset + 2);
2415       proto_tree_add_text(tree, tvb, offset + 2, 1,
2416                         "Transform ID: %s (%u)",
2417                         v2_ipcomptype2str(ipcomptype), ipcomptype);
2418       offset += 3;
2419       length -= 3;
2420     }
2421   }
2422 }
2423
2424 static void
2425 dissect_delete(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2426                proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2427                int unused _U_, guint8 inner_payload _U_)
2428 {
2429   guint32               doi;
2430   guint8                protocol_id;
2431   guint8                spi_size;
2432   guint16               num_spis;
2433   guint16               i;
2434
2435   if (isakmp_version == 1) {
2436     doi = tvb_get_ntohl(tvb, offset);
2437     proto_tree_add_text(tree, tvb, offset, 4,
2438                         "Domain of Interpretation: %s (%u)",
2439                         doitype2str(doi), doi);
2440     offset += 4;
2441     length -= 4;
2442   }
2443
2444   protocol_id = tvb_get_guint8(tvb, offset);
2445   proto_tree_add_uint_format(tree, hf_isakmp_protoid, tvb, offset, 1,
2446                              protocol_id, "Protocol ID: %s (%u)",
2447                              val_to_str(protocol_id, vs_proto, "UNKNOWN-PROTO-TYPE"), protocol_id);
2448   offset += 1;
2449   length -= 1;
2450
2451   spi_size = tvb_get_guint8(tvb, offset);
2452   proto_tree_add_item(tree, hf_isakmp_spisize, tvb, offset, 1, FALSE);
2453   offset += 1;
2454   length -= 1;
2455
2456   num_spis = tvb_get_ntohs(tvb, offset);
2457   proto_tree_add_item(tree, hf_isakmp_num_spis, tvb, offset, 2, FALSE);
2458   offset += 2;
2459   length -= 2;
2460
2461   for (i = 0; i < num_spis; ++i) {
2462     if (length < spi_size) {
2463       proto_tree_add_text(tree, tvb, offset, length,
2464                           "Not enough room in payload for all SPI's");
2465       break;
2466     }
2467     proto_tree_add_text(tree, tvb, offset, spi_size, "SPI: 0x%s",
2468                         tvb_bytes_to_str(tvb, offset, spi_size));
2469     offset += spi_size;
2470     length -= spi_size;
2471   }
2472 }
2473
2474 static const char*
2475 vid_to_str(tvbuff_t* tvb, int offset, int length)
2476 {
2477   const char * vendorstring;
2478   const guint8 * pVID;
2479
2480   pVID = tvb_get_ptr(tvb, offset, length);
2481
2482   if (length == VID_CISCO_FRAG_LEN
2483       && memcmp(pVID, VID_CISCO_FRAG, length) == 0)
2484     vendorstring = "Cisco Fragmentation";
2485   else
2486   if (length == VID_MS_LEN
2487       && memcmp(pVID, VID_MS_W2K_WXP, length) == 0)
2488     vendorstring = "Microsoft Win2K/WinXP";
2489   else
2490   if (memcmp(pVID, VID_CP, isakmp_min(VID_CP_LEN, length)) == 0)
2491     vendorstring = "Check Point";
2492   else
2493   if (memcmp(pVID, VID_CYBERGUARD, isakmp_min(VID_LEN, length)) == 0)
2494     vendorstring = "Cyber Guard";
2495   else
2496   if (memcmp(pVID,  VID_rfc3947, isakmp_min(VID_LEN, length)) == 0)
2497     vendorstring = "RFC 3947 Negotiation of NAT-Traversal in the IKE";
2498   else
2499   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_1_1_0, isakmp_min(VID_LEN, length)) == 0)
2500     vendorstring = "Ssh Communications Security IPSEC Express version 1.1.0";
2501   else
2502   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_1_1_1, isakmp_min(VID_LEN, length)) == 0)
2503     vendorstring = "Ssh Communications Security IPSEC Express version 1.1.1";
2504   else
2505   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_1_1_2, isakmp_min(VID_LEN, length)) == 0)
2506     vendorstring = "Ssh Communications Security IPSEC Express version 1.1.2";
2507   else
2508   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_1_2_1, isakmp_min(VID_LEN, length)) == 0)
2509     vendorstring = "Ssh Communications Security IPSEC Express version 1.2.1";
2510   else
2511   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_1_2_2, isakmp_min(VID_LEN, length)) == 0)
2512     vendorstring = "Ssh Communications Security IPSEC Express version 1.2.2";
2513   else
2514   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_2_0_0, isakmp_min(VID_LEN, length)) == 0)
2515     vendorstring = "Ssh Communications Security IPSEC Express version 2.0.0";
2516   else
2517   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_2_1_0, isakmp_min(VID_LEN, length)) == 0)
2518     vendorstring = "Ssh Communications Security IPSEC Express version 2.1.0";
2519   else
2520   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_2_1_1, isakmp_min(VID_LEN, length)) == 0)
2521     vendorstring = "Ssh Communications Security IPSEC Express version 2.1.1";
2522   else
2523   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_2_1_2, isakmp_min(VID_LEN, length)) == 0)
2524     vendorstring = "Ssh Communications Security IPSEC Express version 2.1.2";
2525   else
2526   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_3_0_0, isakmp_min(VID_LEN, length)) == 0)
2527     vendorstring = "Ssh Communications Security IPSEC Express version 3.0.0";
2528   else
2529   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_3_0_1, isakmp_min(VID_LEN, length)) == 0)
2530     vendorstring = "Ssh Communications Security IPSEC Express version 3.0.1";
2531   else
2532   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_4_0_0, isakmp_min(VID_LEN, length)) == 0)
2533     vendorstring = "Ssh Communications Security IPSEC Express version 4.0.0";
2534   else
2535   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_4_0_1, isakmp_min(VID_LEN, length)) == 0)
2536     vendorstring = "Ssh Communications Security IPSEC Express version 4.0.1";
2537   else
2538   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_4_1_0, isakmp_min(VID_LEN, length)) == 0)
2539     vendorstring = "Ssh Communications Security IPSEC Express version 4.1.0";
2540   else
2541   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_4_1_1, isakmp_min(VID_LEN, length)) == 0)
2542     vendorstring = "Ssh Communications Security IPSEC Express version 4.1.1";
2543   else
2544   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_5_0, isakmp_min(VID_LEN, length)) == 0)
2545     vendorstring = "Ssh Communications Security IPSEC Express version 5.0";
2546   else
2547   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_5_0_0, isakmp_min(VID_LEN, length)) == 0)
2548     vendorstring = "Ssh Communications Security IPSEC Express version 5.0.0";
2549   else
2550   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_5_1_0, isakmp_min(VID_LEN, length)) == 0)
2551     vendorstring = "Ssh Communications Security IPSEC Express version 5.1.0";
2552   else
2553   if (memcmp(pVID,  VID_SSH_IPSEC_EXPRESS_5_1_1, isakmp_min(VID_LEN, length)) == 0)
2554     vendorstring = "Ssh Communications Security IPSEC Express version 5.1.1";
2555   else
2556   if (memcmp(pVID,  VID_SSH_SENTINEL, isakmp_min(VID_LEN, length)) == 0)
2557     vendorstring = "SSH Sentinel";
2558   else
2559   if (memcmp(pVID,  VID_SSH_SENTINEL_1_1, isakmp_min(VID_LEN, length)) == 0)
2560     vendorstring = "SSH Sentinel 1.1";
2561   else
2562   if (memcmp(pVID,  VID_SSH_SENTINEL_1_2, isakmp_min(VID_LEN, length)) == 0)
2563     vendorstring = "SSH Sentinel 1.2";
2564   else
2565   if (memcmp(pVID,  VID_SSH_SENTINEL_1_3, isakmp_min(VID_LEN, length)) == 0)
2566     vendorstring = "SSH Sentinel 1.3";
2567   else
2568   if (memcmp(pVID,  VID_SSH_QUICKSEC_0_9_0, isakmp_min(VID_LEN, length)) == 0)
2569     vendorstring = "SSH Communications Security QuickSec 0.9.0";
2570   else
2571   if (memcmp(pVID,  VID_SSH_QUICKSEC_1_1_0, isakmp_min(VID_LEN, length)) == 0)
2572     vendorstring = "SSH Communications Security QuickSec 1.1.0";
2573   else
2574   if (memcmp(pVID,  VID_SSH_QUICKSEC_1_1_1, isakmp_min(VID_LEN, length)) == 0)
2575     vendorstring = "SSH Communications Security QuickSec 1.1.1";
2576   else
2577   if (memcmp(pVID,  VID_SSH_QUICKSEC_1_1_2, isakmp_min(VID_LEN, length)) == 0)
2578     vendorstring = "SSH Communications Security QuickSec 1.1.2";
2579   else
2580   if (memcmp(pVID,  VID_SSH_QUICKSEC_1_1_3, isakmp_min(VID_LEN, length)) == 0)
2581     vendorstring = "SSH Communications Security QuickSec 1.1.3";
2582   else
2583   if (memcmp(pVID,  VID_draft_huttunen_ipsec_esp_in_udp_01, isakmp_min(VID_LEN, length)) == 0)
2584     vendorstring = "draft-huttunen-ipsec-esp-in-udp-01.txt";
2585   else
2586   if (memcmp(pVID,  VID_draft_stenberg_ipsec_nat_traversal_01, isakmp_min(VID_LEN, length)) == 0)
2587     vendorstring = "draft-stenberg-ipsec-nat-traversal-01";
2588   else
2589   if (memcmp(pVID,  VID_draft_stenberg_ipsec_nat_traversal_02, isakmp_min(VID_LEN, length)) == 0)
2590     vendorstring = "draft-stenberg-ipsec-nat-traversal-02";
2591   else
2592   if (memcmp(pVID,  VID_draft_ietf_ipsec_nat_t_ike_00, isakmp_min(VID_LEN, length)) == 0)
2593     vendorstring = "draft-ietf-ipsec-nat-t-ike-00";
2594   else
2595   if (memcmp(pVID,  VID_draft_ietf_ipsec_nat_t_ike_01, isakmp_min(VID_LEN, length)) == 0)
2596     vendorstring = "draft-ietf-ipsec-nat-t-ike-01";
2597   else
2598   if (memcmp(pVID,  VID_draft_ietf_ipsec_nat_t_ike_02a, isakmp_min(VID_LEN, length)) == 0)
2599     vendorstring = "draft-ietf-ipsec-nat-t-ike-02";
2600   else
2601   if (memcmp(pVID,  VID_draft_ietf_ipsec_nat_t_ike_02b, isakmp_min(VID_LEN, length)) == 0)
2602     vendorstring = "draft-ietf-ipsec-nat-t-ike-02\\n"; /* \n intentional */
2603   else
2604   if (memcmp(pVID,  VID_draft_ietf_ipsec_nat_t_ike_03, isakmp_min(VID_LEN, length)) == 0)
2605     vendorstring = "draft-ietf-ipsec-nat-t-ike-03";
2606   else
2607   if (memcmp(pVID,  VID_draft_beaulieu_ike_xauth_02, isakmp_min(VID_LEN, length)) == 0)
2608     vendorstring = "draft-beaulieu-ike-xauth-02.txt";
2609   else
2610   if (memcmp(pVID,  VID_rfc3706_dpd, isakmp_min(VID_LEN, length)) == 0)
2611     vendorstring = "RFC 3706 Detecting Dead IKE Peers (DPD)";
2612   else
2613   if (memcmp(pVID,  VID_IKE_CHALLENGE_RESPONSE_1, isakmp_min(VID_LEN, length)) == 0)
2614     vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys";
2615   else
2616   if (memcmp(pVID,  VID_IKE_CHALLENGE_RESPONSE_2, isakmp_min(VID_LEN, length)) == 0)
2617     vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys";
2618   else
2619   if (memcmp(pVID,  VID_IKE_CHALLENGE_RESPONSE_REV_1, isakmp_min(VID_LEN, length)) == 0)
2620     vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys (Revised)";
2621   else
2622   if (memcmp(pVID,  VID_IKE_CHALLENGE_RESPONSE_REV_2, isakmp_min(VID_LEN, length)) == 0)
2623     vendorstring = "IKE Challenge/Response for Authenticated Cryptographic Keys (Revised)";
2624   else
2625   if (memcmp(pVID,  VID_MS_L2TP_IPSEC_VPN_CLIENT, isakmp_min(VID_LEN, length)) == 0)
2626     vendorstring = "Microsoft L2TP/IPSec VPN Client";
2627   else
2628   if (memcmp(pVID,  VID_GSS_API_1, isakmp_min(VID_LEN, length)) == 0)
2629     vendorstring = "A GSS-API Authentication Method for IKE";
2630   else
2631   if (memcmp(pVID,  VID_GSS_API_2, isakmp_min(VID_LEN, length)) == 0)
2632     vendorstring = "A GSS-API Authentication Method for IKE";
2633   else
2634   if (memcmp(pVID,  VID_GSSAPI, isakmp_min(VID_LEN, length)) == 0)
2635     vendorstring = "GSSAPI";
2636   else
2637   if (memcmp(pVID,  VID_MS_NT5_ISAKMPOAKLEY, isakmp_min(VID_LEN, length)) == 0)
2638     vendorstring = "MS NT5 ISAKMPOAKLEY";
2639   else
2640   if (memcmp(pVID,  VID_CISCO_CONCENTRATOR, isakmp_min(VID_LEN, length)) == 0)
2641     vendorstring = "CISCO-CONCENTRATOR";
2642   else
2643   if (memcmp(pVID,  VID_CISCO_UNITY_10, isakmp_min(VID_LEN, length)) == 0)
2644     vendorstring = "CISCO-UNITY-1.0";
2645   else
2646   if (memcmp(pVID,  VID_CISCO_UNITY, isakmp_min(VID_LEN, length)) == 0)
2647     vendorstring = "CISCO-UNITY";
2648   else
2649   if (memcmp(pVID,  VID_draft_ietf_ipsec_antireplay_00, isakmp_min(VID_LEN_8, length)) == 0)
2650     vendorstring = "draft-ietf-ipsec-antireplay-00.txt";
2651   else
2652   if (memcmp(pVID,  VID_draft_ietf_ipsec_heartbeats_00, isakmp_min(VID_LEN_8, length)) == 0)
2653     vendorstring = "draft-ietf-ipsec-heartbeats-00.txt";
2654   else
2655     vendorstring = tvb_bytes_to_str(tvb, offset, length);
2656
2657   return vendorstring;
2658 }
2659
2660 static void
2661 dissect_vid(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2662             proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_,
2663             int unused _U_, guint8 inner_payload _U_)
2664 {
2665   guint32 CPproduct, CPversion;
2666   const guint8 * pVID;
2667   proto_item * pt;
2668   proto_tree * ntree;
2669
2670   pVID = tvb_get_ptr(tvb, offset, length);
2671   pt = proto_tree_add_text(tree, tvb, offset, length, "Vendor ID: %s",
2672                            vid_to_str(tvb, offset, length));
2673
2674   if (memcmp(pVID, VID_CP, isakmp_min(VID_CP_LEN, length)) == 0)
2675   {
2676     offset += VID_CP_LEN;
2677     CPproduct = tvb_get_ntohl(tvb, offset);
2678     ntree = proto_item_add_subtree(pt, ett_isakmp_payload);
2679     pt = proto_tree_add_text(ntree, tvb, offset, sizeof(CPproduct), "Check Point Product: ");
2680     switch (CPproduct) {
2681       case 1: proto_item_append_text(pt, "VPN-1");
2682         break;
2683       case 2: proto_item_append_text(pt, "SecuRemote/SecureClient");
2684         break;
2685       default: proto_item_append_text(pt, "Unknown CP product!");
2686         break;
2687     }
2688     offset += sizeof(CPproduct);
2689     CPversion = tvb_get_ntohl(tvb, offset);
2690     pt = proto_tree_add_text(ntree, tvb, offset, sizeof(CPversion), "Version: ");
2691     switch (CPversion) {
2692       case 2: proto_item_append_text(pt, "4.1");
2693         break;
2694       case 3: proto_item_append_text(pt, "4.1 SP-1");
2695         break;
2696       case 4002: proto_item_append_text(pt, "4.1 (SP-2 or above)");
2697         break;
2698       case 5000: proto_item_append_text(pt, "NG");
2699         break;
2700       case 5001: proto_item_append_text(pt, "NG Feature Pack 1");
2701         break;
2702       case 5002: proto_item_append_text(pt, "NG Feature Pack 2");
2703         break;
2704       case 5003: proto_item_append_text(pt, "NG Feature Pack 3");
2705         break;
2706       case 5004: proto_item_append_text(pt, "NG with Application Intelligence");
2707         break;
2708       case 5005: proto_item_append_text(pt, "NG with Application Intelligence R55");
2709         break;
2710       default: proto_item_append_text(pt, " Unknown CP version!");
2711         break;
2712     }
2713     offset += sizeof(CPversion);
2714     proto_tree_add_text(ntree, tvb, offset, length - VID_CP_LEN - sizeof(CPproduct) - sizeof(CPversion),"Check Point Vendor ID parameters");
2715   }
2716 }
2717 /* Returns the number of bytes consumed by this option. */
2718 static int
2719 dissect_config_attribute(tvbuff_t *tvb, proto_tree *cfg_attr_type_tree, int offset, int isakmp_version)
2720 {
2721         guint optlen, cfg_attr_type, len = 0;
2722         int offset_end = 0;     
2723         proto_item *cfg_attr_type_item;
2724         proto_tree *sub_cfg_attr_type_tree = NULL;
2725
2726         cfg_attr_type = tvb_get_ntohs(tvb, offset);
2727         optlen = tvb_get_ntohs(tvb, offset+2);
2728         len = 2;
2729
2730         /* No Length ? */
2731         if (cfg_attr_type & 0x8000) {
2732               cfg_attr_type = cfg_attr_type & 0x7fff;
2733               len = 0;
2734               optlen = 2;
2735         }
2736
2737         if (isakmp_version == 1) {
2738            cfg_attr_type_item = proto_tree_add_text(cfg_attr_type_tree, tvb, offset, 2+len+optlen, "Attribute Type: (t=%d,l=%d) %s", cfg_attr_type, optlen, rval_to_str(cfg_attr_type,vs_v1_cfgattr,"Unknown Attribute Type (%02d)") );
2739            sub_cfg_attr_type_tree = proto_item_add_subtree(cfg_attr_type_item, ett_isakmp_cfg_attr);
2740            proto_tree_add_uint(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_type_v1, tvb, offset, 2, cfg_attr_type);
2741         } else if (isakmp_version == 2) {
2742            cfg_attr_type_item = proto_tree_add_text(cfg_attr_type_tree, tvb, offset, 2+len+optlen, "Attribute Type: (t=%d,l=%d) %s", cfg_attr_type, optlen, rval_to_str(cfg_attr_type,vs_v2_cfgattr,"Unknown Attribute Type (%02d)") );
2743            sub_cfg_attr_type_tree = proto_item_add_subtree(cfg_attr_type_item, ett_isakmp_cfg_attr);
2744            proto_tree_add_uint(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_type_v2, tvb, offset, 2, cfg_attr_type);      
2745         }
2746         offset += 2;
2747         if (len)
2748         {
2749            proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_length, tvb, offset, 2, FALSE);
2750            offset += 2; 
2751         }
2752         if (optlen==0)
2753         {
2754            proto_tree_add_text(sub_cfg_attr_type_tree, tvb, offset, 0,"Attribut value is empty");               
2755            return 2+len;        
2756         }
2757         proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_value, tvb, offset, optlen, FALSE);      
2758         switch (cfg_attr_type) {
2759         case INTERNAL_IP4_ADDRESS: /* 1 */
2760                 offset_end = offset + optlen;
2761
2762                 if (optlen%4 == 0)
2763                 {
2764                         while (offset_end-offset > 0)
2765                         {
2766                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_address, tvb, offset, 4, FALSE);
2767                                 offset += 4;
2768                         }
2769
2770                 }
2771                 break;
2772         case INTERNAL_IP4_NETMASK: /* 2 */
2773                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_netmask, tvb, offset, 4, FALSE);
2774                 break;
2775         case INTERNAL_IP4_DNS: /* 3 */
2776                 offset_end = offset + optlen;
2777
2778                 if (optlen%4 == 0)
2779                 {
2780                         while (offset_end-offset > 0)
2781                         {
2782                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_dns, tvb, offset, 4, FALSE);
2783                                 offset += 4;
2784                         }
2785
2786                 }
2787                 break;
2788         case INTERNAL_IP4_NBNS: /* 4 */
2789                 offset_end = offset + optlen;
2790
2791                 if (optlen%4 == 0)
2792                 {
2793                         while (offset_end-offset > 0)
2794                         {
2795                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_nbns, tvb, offset, 4, FALSE);
2796                                 offset += 4;
2797                         }
2798
2799                 }
2800                 break;
2801         case INTERNAL_ADDRESS_EXPIRY: /* 5 */
2802                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_address_expiry, tvb, offset, 4, FALSE);
2803                 break;
2804         case INTERNAL_IP4_DHCP: /* 6 */
2805                 offset_end = offset + optlen;
2806
2807                 if (optlen%4 == 0)
2808                 {
2809                         while (offset_end-offset > 0)
2810                         {
2811                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_dhcp, tvb, offset, 4, FALSE);
2812                                 offset += 4;
2813                         }
2814
2815                 }
2816                 break;
2817         case APPLICATION_VERSION: /* 7 */
2818                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_application_version, tvb, offset, optlen, FALSE);
2819                 break;
2820         case INTERNAL_IP6_ADDRESS: /* 8 */
2821                 offset_end = offset + optlen;
2822
2823                 if (optlen%16 == 0)
2824                 {
2825                         while (offset_end-offset > 0)
2826                         {
2827                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_address, tvb, offset, 16, FALSE);
2828                                 offset += 16;
2829                         }
2830
2831                 }
2832                 break;
2833         case INTERNAL_IP6_NETMASK: /* 9 Only in IKEv1 */
2834                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_netmask, tvb, offset, 18, FALSE);
2835                 break;
2836         case INTERNAL_IP6_DNS: /* 10 */
2837                 offset_end = offset + optlen;
2838
2839                 if (optlen%16 == 0)
2840                 {
2841                         while (offset_end-offset > 0)
2842                         {
2843                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_dns, tvb, offset, 16, FALSE);
2844                                 offset += 16;
2845                         }
2846
2847                 }
2848                 break;
2849         case INTERNAL_IP6_NBNS: /* 11 */
2850                 offset_end = offset + optlen;
2851
2852                 if (optlen%16 == 0)
2853                 {
2854                         while (offset_end-offset > 0)
2855                         {
2856                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_nbns, tvb, offset, 16, FALSE);
2857                                 offset += 16;
2858                         }
2859
2860                 }
2861                 break;
2862         case INTERNAL_IP6_DHCP: /* 12 */
2863                 offset_end = offset + optlen;
2864
2865                 if (optlen%16 == 0)
2866                 {
2867                         while (offset_end-offset > 0)
2868                         {
2869                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip6_dhcp, tvb, offset, 16, FALSE);
2870                                 offset += 16;
2871                         }
2872
2873                 }
2874                 break;
2875         case INTERNAL_IP4_SUBNET: /* 13 */
2876                 offset_end = offset + optlen;
2877
2878                 if (optlen%8 == 0)
2879                 {
2880                         while (offset_end-offset > 0)
2881                         {
2882                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_subnet_ip, tvb, offset, 4, FALSE);
2883                                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_internal_ip4_subnet_netmask, tvb, offset, 4, FALSE);
2884                                 offset += 8;
2885                         }
2886
2887                 }
2888                 break;
2889 /* TODO
2890 SUPPORTED_ATTRIBUTES (14) a variable   0 or multiples of 2 
2891 INTERNAL_IP6_SUBNET (15) a variable   0 or 17 octets ( This attribute is made up of two fields:
2892  the first is a sixteen-octet IPv6 address and the second is a one-octet prefix-length )
2893 */
2894         case XAUTH_TYPE: /* 16520 */
2895                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_type, tvb, offset, optlen, FALSE);
2896                 break;
2897         case XAUTH_USER_NAME: /* 16521 */
2898                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_user_name, tvb, offset, optlen, FALSE);
2899                 break;
2900         case XAUTH_USER_PASSWORD: /* 16522 */
2901                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_user_password, tvb, offset, optlen, FALSE);
2902                 break;
2903         case XAUTH_PASSCODE: /* 16523 */
2904                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_passcode, tvb, offset, optlen, FALSE);
2905                 break;
2906         case XAUTH_MESSAGE: /* 16524 */
2907                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_message, tvb, offset, optlen, FALSE);
2908                 break;
2909         case XAUTH_CHALLENGE: /* 16525 */
2910                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_challenge, tvb, offset, optlen, FALSE);
2911                 break;
2912         case XAUTH_DOMAIN: /* 16526 */
2913                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_domain, tvb, offset, optlen, FALSE);
2914                 break;
2915         case XAUTH_STATUS: /* 16527 */
2916                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_status, tvb, offset, optlen, FALSE);
2917                 break;
2918         case XAUTH_NEXT_PIN: /* 16528 */
2919                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_next_pin, tvb, offset, optlen, FALSE);
2920                 break;
2921         case XAUTH_ANSWER: /* 16527 */
2922                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_xauth_answer, tvb, offset, optlen, FALSE);
2923                 break;
2924
2925         case UNITY_BANNER: /* 28672 */
2926                 proto_tree_add_item(sub_cfg_attr_type_tree, hf_isakmp_cfg_attr_unity_banner, tvb, offset, optlen, FALSE);
2927                 break;
2928 /* TODO: Support other UNITY Attributs ! */
2929         default:
2930                 /* No Default Action */
2931                 break;
2932         }
2933         
2934         return 2+len+optlen;
2935 }
2936 static void
2937 dissect_config(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2938                proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version,
2939                int unused _U_, guint8 inner_payload _U_)
2940 {
2941   int offset_end = 0;   
2942   offset_end = offset + length;
2943   if (isakmp_version == 1) {
2944
2945     proto_tree_add_item(tree, hf_isakmp_cfg_type_v1,tvb, offset, 1, FALSE);
2946     offset += 2;
2947
2948     proto_tree_add_item(tree, hf_isakmp_cfg_identifier,tvb, offset, 1, FALSE);
2949     offset += 2;
2950
2951   } else if (isakmp_version == 2) {
2952
2953     proto_tree_add_item(tree, hf_isakmp_cfg_type_v2,tvb, offset, 1, FALSE);
2954     offset += 4;
2955
2956   }
2957
2958   while(offset < offset_end) {
2959     offset += dissect_config_attribute(tvb, tree, offset, isakmp_version);
2960 }
2961 }
2962
2963 static void
2964 dissect_nat_discovery(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2965     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
2966 {
2967   proto_tree_add_item(tree, hf_isakmp_nat_hash, tvb, offset, length, FALSE);
2968 }
2969
2970 static void
2971 dissect_nat_original_address(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
2972     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version, int unused _U_, guint8 inner_payload _U_)
2973 {
2974   guint8 id_type;
2975
2976   id_type = tvb_get_guint8(tvb, offset);
2977   if(isakmp_version == 1)
2978   {
2979      proto_tree_add_item(tree, hf_isakmp_id_type_v1, tvb, offset, 1, FALSE);
2980   }else if(isakmp_version == 2)
2981   {
2982      proto_tree_add_item(tree, hf_isakmp_id_type_v2, tvb, offset, 1, FALSE);
2983   }
2984   offset += 1;
2985   length -= 1;
2986
2987   offset += 3;          /* reserved */
2988
2989   switch (id_type) {
2990
2991   case IKE_ID_IPV4_ADDR:
2992     proto_tree_add_item(tree, hf_isakmp_nat_original_address_ipv4, tvb, offset, 4, FALSE);
2993     break;
2994
2995   case IKE_ID_IPV6_ADDR:
2996     proto_tree_add_item(tree, hf_isakmp_nat_original_address_ipv6, tvb, offset, 16, FALSE);
2997     break;
2998
2999   default:
3000     break;
3001   }
3002 }
3003
3004 static void
3005 dissect_ts(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
3006     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
3007 {
3008   guint8        num, tstype, protocol_id, addrlen;
3009   guint16       len, port;
3010
3011   proto_tree_add_text(tree, tvb, offset, length, "Traffic Selector");
3012
3013   num = tvb_get_guint8(tvb, offset);
3014   proto_item_append_text(tree," # %d", num);
3015   proto_tree_add_text(tree, tvb, offset, 1,
3016                       "Number of TSs: %u", num);
3017   offset += 4;
3018   length -= 4;
3019
3020   while (length > 0) {
3021     tstype = tvb_get_guint8(tvb, offset);
3022     proto_tree_add_text(tree, tvb, offset, 1,
3023                         "TS Type: %s (%u)",
3024                         v2_tstype2str(tstype), tstype);
3025     switch (tstype) {
3026     case IKEV2_TS_IPV4_ADDR_RANGE:
3027       addrlen = 4;
3028       break;
3029     case IKEV2_TS_IPV6_ADDR_RANGE:
3030       addrlen = 16;
3031       break;
3032     default:
3033       proto_item_append_text(tree, "unknown TS data (aborted decoding): 0x%s",
3034                              tvb_bytes_to_str(tvb, offset, length));
3035       return;
3036     }
3037
3038     /*
3039      * XXX should the remaining of the length check be done here ?
3040      * it seems other routines don't check the length.
3041      */
3042     if (length < (8 + addrlen * 2)) {
3043       proto_tree_add_text(tree, tvb, offset, length,
3044                           "Length mismatch (%u)", length);
3045       return;
3046     }
3047     offset += 1;
3048     length -= 1;
3049
3050     protocol_id = tvb_get_guint8(tvb, offset);
3051     proto_tree_add_text(tree, tvb, offset, 1,
3052                         "Protocol ID: (%u)", protocol_id);
3053     offset += 1;
3054     length -= 1;
3055
3056     len = tvb_get_ntohs(tvb, offset);
3057     proto_tree_add_text(tree, tvb, offset, 2,
3058                         "Selector Length: %u", len);
3059     offset += 2;
3060     length -= 2;
3061
3062     port = tvb_get_ntohs(tvb, offset);
3063     proto_tree_add_text(tree, tvb, offset, 2,
3064                         "Start Port: (%u)", port);
3065     offset += 2;
3066     length -= 2;
3067
3068     port = tvb_get_ntohs(tvb, offset);
3069     proto_tree_add_text(tree, tvb, offset, 2,
3070                         "End Port: (%u)", port);
3071     offset += 2;
3072     length -= 2;
3073
3074     switch (tstype) {
3075     case IKEV2_TS_IPV4_ADDR_RANGE:
3076         proto_tree_add_text(tree, tvb, offset, length,
3077                             "Starting Address: %s",
3078                             ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
3079         offset += addrlen;
3080         length -= addrlen;
3081         proto_tree_add_text(tree, tvb, offset, length,
3082                             "Ending Address: %s",
3083                             ip_to_str(tvb_get_ptr(tvb, offset, addrlen)));
3084         offset += addrlen;
3085         length -= addrlen;
3086         break;
3087     case IKEV2_TS_IPV6_ADDR_RANGE:
3088         proto_tree_add_text(tree, tvb, offset, length,
3089                             "Starting Address: %s",
3090                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, addrlen)));
3091         offset += addrlen;
3092         length -= addrlen;
3093         proto_tree_add_text(tree, tvb, offset, length,
3094                             "Ending Address: %s",
3095                             ip6_to_str((const struct e_in6_addr *)tvb_get_ptr(tvb, offset, addrlen)));
3096         offset += addrlen;
3097         length -= addrlen;
3098         break;
3099     }
3100   }
3101 }
3102
3103 static void
3104 dissect_enc(tvbuff_t *tvb,
3105             int offset,
3106             int length,
3107             proto_tree *tree,
3108             proto_tree *p _U_,
3109 #ifdef HAVE_LIBGCRYPT
3110             packet_info *pinfo,
3111 #else
3112             packet_info *pinfo _U_,
3113 #endif
3114             int isakmp_version _U_,
3115             int unused _U_,
3116 #ifdef HAVE_LIBGCRYPT
3117             guint8 inner_payload)
3118 #else
3119             guint8 inner_payload _U_)
3120 #endif
3121 {
3122 #ifdef HAVE_LIBGCRYPT
3123   ikev2_decrypt_data_t *key_info = NULL;
3124   gint iv_len, encr_data_len, icd_len, encr_key_len, decr_data_len, md_len;
3125   guint8 pad_len;
3126   guchar *iv = NULL, *encr_data = NULL, *decr_data = NULL, *entire_message = NULL, *md = NULL;
3127   gcry_cipher_hd_t cipher_hd;
3128   gcry_md_hd_t md_hd;
3129   gcry_error_t err = 0;
3130   proto_item *item = NULL, *icd_item = NULL, *encr_data_item = NULL, *padlen_item = NULL;
3131   tvbuff_t *decr_tvb = NULL;
3132   gint payloads_len;
3133   proto_tree *decr_tree = NULL, *decr_payloads_tree = NULL;
3134
3135
3136   if (pinfo->private_data) {
3137     key_info = (ikev2_decrypt_data_t*)(pinfo->private_data);
3138     encr_key_len = key_info->encr_spec->key_len;
3139     iv_len = key_info->encr_spec->iv_len;
3140     icd_len = key_info->auth_spec->trunc_len;
3141     encr_data_len = length - iv_len - icd_len;
3142
3143     /*
3144      * Zero or negative length of encrypted data shows that the user specified
3145      * wrong encryption algorithm and/or authentication algorithm.
3146      */
3147     if (encr_data_len <= 0) {
3148       item = proto_tree_add_text(tree, tvb, offset, length, "Not enough data for IV, Encrypted data and ICD.");
3149       expert_add_info_format(pinfo, item, PI_MALFORMED, PI_WARN, "Not enough data in IKEv2 Encrypted payload");
3150       PROTO_ITEM_SET_GENERATED(item);
3151       return;
3152     }
3153
3154     /*
3155      * Add the IV to the tree and store it in a packet scope buffer for later decryption
3156      * if the specified encryption algorithm uses IV.
3157      */
3158     if (iv_len) {
3159       proto_tree_add_text(tree, tvb, offset, iv_len, "Initialization Vector (%d bytes): 0x%s",
3160         iv_len, tvb_bytes_to_str(tvb, offset, iv_len));
3161       iv = ep_tvb_memdup(tvb, offset, iv_len);
3162
3163       offset += iv_len;
3164     }
3165
3166     /*
3167      * Add the encrypted portion to the tree and store it in a packet scope buffer for later decryption.
3168      */
3169     encr_data_item = proto_tree_add_text(tree, tvb, offset, encr_data_len, "Encrypted Data (%d bytes)", encr_data_len);
3170     encr_data = ep_tvb_memdup(tvb, offset, encr_data_len);
3171     offset += encr_data_len;
3172
3173     /*
3174      * Add the ICD (Integrity Checksum Data) to the tree before decryption to ensure
3175      * the ICD be displayed even if the decryption fails.
3176      */
3177     if (icd_len) {
3178       icd_item = proto_tree_add_text(tree, tvb, offset, icd_len, "Integrity Checksum Data (%d bytes) ", icd_len);
3179
3180       /*
3181        * Recalculate ICD value if the specified authentication algorithm allows it.
3182        */
3183       if (key_info->auth_spec->gcry_alg) {
3184         err = gcry_md_open(&md_hd, key_info->auth_spec->gcry_alg, key_info->auth_spec->gcry_flag);
3185         if (err) {
3186           REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %d: gcry_md_open failed: %s",
3187             key_info->auth_spec->gcry_alg, gcry_strerror(err)));
3188         }
3189         err = gcry_md_setkey(md_hd, key_info->auth_key, key_info->auth_spec->key_len);
3190         if (err) {
3191           REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %s, key length %u: gcry_md_setkey failed: %s",
3192             gcry_md_algo_name(key_info->auth_spec->gcry_alg), key_info->auth_spec->key_len, gcry_strerror(err)));
3193         }
3194
3195         /* Calculate hash over the bytes from the beginning of the ISAKMP header to the right before the ICD. */
3196         entire_message = ep_tvb_memdup(tvb, 0, offset);
3197         gcry_md_write(md_hd, entire_message, offset);
3198         md = gcry_md_read(md_hd, 0);
3199         md_len = gcry_md_get_algo_dlen(key_info->auth_spec->gcry_alg);
3200         if (md_len < icd_len) {
3201           gcry_md_close(md_hd);
3202           REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 hashing error: algorithm %s: gcry_md_get_algo_dlen returned %d which is smaller than icd length %d",
3203             gcry_md_algo_name(key_info->auth_spec->gcry_alg), md_len, icd_len));
3204         }
3205         if (tvb_memeql(tvb, offset, md, icd_len) == 0) {
3206           proto_item_append_text(icd_item, "[correct]");
3207         } else {
3208           proto_item_append_text(icd_item, "[incorrect, should be %s]", bytes_to_str(md, icd_len));
3209           expert_add_info_format(pinfo, icd_item, PI_CHECKSUM, PI_WARN, "IKEv2 Integrity Checksum Data is incorrect");
3210         }
3211         gcry_md_close(md_hd);
3212       } else {
3213         proto_item_append_text(icd_item, "[not validated]");
3214       }
3215       offset += icd_len;
3216     }
3217
3218     /*
3219      * Confirm encrypted data length is multiple of block size.
3220      */
3221     if (encr_data_len % key_info->encr_spec->block_len != 0) {
3222       proto_item_append_text(encr_data_item, "[Invalid length, should be a multiple of block size (%u)]",
3223         key_info->encr_spec->block_len);
3224       expert_add_info_format(pinfo, encr_data_item, PI_MALFORMED, PI_WARN, "Encrypted data length isn't a multiple of block size");
3225       return;
3226     }
3227
3228     /*
3229      * Allocate buffer for decrypted data.
3230      */
3231     decr_data = (guchar*)g_malloc(encr_data_len);
3232     decr_data_len = encr_data_len;
3233
3234     /*
3235      * If the cipher is NULL, just copy the encrypted data to the decrypted data buffer.
3236      * And otherwise perform decryption with libgcrypt.
3237      */
3238     if (key_info->encr_spec->number == IKEV2_ENCR_NULL) {
3239       memcpy(decr_data, encr_data, decr_data_len);
3240     } else {
3241       err = gcry_cipher_open(&cipher_hd, key_info->encr_spec->gcry_alg, key_info->encr_spec->gcry_mode, 0);
3242       if (err) {
3243         g_free(decr_data);
3244         REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, mode %d: gcry_cipher_open failed: %s",
3245           key_info->encr_spec->gcry_alg, key_info->encr_spec->gcry_mode, gcry_strerror(err)));
3246       }
3247       err = gcry_cipher_setkey(cipher_hd, key_info->encr_key, key_info->encr_spec->key_len);
3248       if (err) {
3249         g_free(decr_data);
3250         REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, key length %d:  gcry_cipher_setkey failed: %s",
3251           key_info->encr_spec->gcry_alg, key_info->encr_spec->key_len, gcry_strerror(err)));
3252       }
3253       err = gcry_cipher_setiv(cipher_hd, iv, iv_len);
3254       if (err) {
3255         g_free(decr_data);
3256         REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d, iv length %d:  gcry_cipher_setiv failed: %s",
3257           key_info->encr_spec->gcry_alg, iv_len, gcry_strerror(err)));
3258       }
3259       err = gcry_cipher_decrypt(cipher_hd, decr_data, decr_data_len, encr_data, encr_data_len);
3260       if (err) {
3261         g_free(decr_data);
3262         REPORT_DISSECTOR_BUG(ep_strdup_printf("IKEv2 decryption error: algorithm %d:  gcry_cipher_decrypt failed: %s",
3263           key_info->encr_spec->gcry_alg, gcry_strerror(err)));
3264       }
3265       gcry_cipher_close(cipher_hd);
3266     }
3267
3268
3269     decr_tvb = tvb_new_real_data(decr_data, decr_data_len, decr_data_len);
3270     tvb_set_free_cb(decr_tvb, g_free);
3271     tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
3272     add_new_data_source(pinfo, decr_tvb, "Decrypted Data");
3273     item = proto_tree_add_text(tree, decr_tvb, 0, decr_data_len, "Decrypted Data (%d bytes)", decr_data_len);
3274     /* Move the ICD item to the bottom of the tree. */
3275     if (icd_item) {
3276       proto_tree_move_item(tree, item, icd_item);
3277     }
3278     decr_tree = proto_item_add_subtree(item, ett_isakmp_decrypted_data);
3279
3280     pad_len = tvb_get_guint8(decr_tvb, decr_data_len - 1);
3281     payloads_len = decr_data_len - 1 - pad_len;
3282
3283     if (payloads_len > 0) {
3284       item = proto_tree_add_text(decr_tree, decr_tvb, 0, payloads_len, "Contained Payloads (total %d bytes)", payloads_len);
3285       decr_payloads_tree = proto_item_add_subtree(item, ett_isakmp_decrypted_payloads);
3286     }
3287
3288     padlen_item = proto_tree_add_text(decr_tree, decr_tvb, payloads_len + pad_len, 1, "Pad Length: %d", pad_len);
3289     if (pad_len > 0) {
3290       if (payloads_len < 0) {
3291         proto_item_append_text(padlen_item, " [too long]");
3292         expert_add_info_format(pinfo, padlen_item, PI_MALFORMED, PI_WARN, "Pad length is too big");
3293       } else {
3294         item = proto_tree_add_text(decr_tree, decr_tvb, payloads_len, pad_len, "Padding (%d bytes)", pad_len);
3295         proto_tree_move_item(decr_tree, item, padlen_item);
3296       }
3297     }
3298
3299     /*
3300      * We dissect the inner payloads at last in order to ensure displaying Padding, Pad Length and ICD
3301      * even if the dissection fails. This may occur when the user specify wrong encryption key.
3302      */
3303     if (decr_payloads_tree) {
3304       dissect_payloads(decr_tvb, decr_payloads_tree, decr_tree, isakmp_version, inner_payload, 0, payloads_len, pinfo);
3305     }
3306   }else{
3307 #endif /* HAVE_LIBGCRYPT */
3308     proto_tree_add_text(tree, tvb, offset, 4, "Initialization Vector: 0x%s",
3309                         tvb_bytes_to_str(tvb, offset, 4));
3310     proto_tree_add_text(tree, tvb, offset + 4, length, "Encrypted Data");
3311 #ifdef HAVE_LIBGCRYPT
3312   }
3313 #endif /* HAVE_LIBGCRYPT */
3314 }
3315
3316 static void
3317 dissect_eap(tvbuff_t *tvb, int offset, int length, proto_tree *tree,
3318     proto_tree *p _U_, packet_info *pinfo _U_, int isakmp_version _U_, int unused _U_, guint8 inner_payload _U_)
3319 {
3320   tvbuff_t *eap_tvb = NULL;
3321
3322   eap_tvb = tvb_new_subset(tvb, offset,length, length );
3323   if ((eap_tvb != NULL)&& eap_handle != NULL){
3324           call_dissector(eap_handle, eap_tvb, pinfo, tree);
3325   }else{
3326           proto_tree_add_text(tree, tvb, offset, length, "EAP Message");
3327   }
3328 }
3329
3330 static const char *
3331 payloadtype2str(int isakmp_version, guint8 type)
3332 {
3333   struct payload_func *f;
3334
3335   if ((f = getpayload_func(type, isakmp_version)) != NULL)
3336     return f->str;
3337
3338   if (isakmp_version == 1) {
3339     if (type < 128)
3340       return "RESERVED";
3341     return "Private USE";
3342   } else if (isakmp_version == 2) {
3343     if (type > 127)
3344       return "PRIVATE USE";
3345     if (type > 48)
3346       return "RESERVED TO IANA";
3347     return "RESERVED";
3348   }
3349   return "UNKNOWN-ISAKMP-VERSION";
3350 }
3351
3352 static const char *
3353 exchtype2str(int isakmp_version, guint8 type)
3354 {
3355   static const value_string vs_v1_exchange[] = {
3356     { 0,        "NONE" },
3357     { 1,        "Base" },
3358     { 2,        "Identity Protection (Main Mode)" },
3359     { 3,        "Authentication Only" },
3360     { 4,        "Aggressive" },
3361     { 5,        "Informational" },
3362     { 6,        "Transaction (Config Mode)" },
3363     { 32,       "Quick Mode" },
3364     { 33,       "New Group Mode" },
3365     { 0,        NULL },
3366   };
3367
3368   static const value_string vs_v2_exchange[] = {
3369     { 34,       "IKE_SA_INIT" },
3370     { 35,       "IKE_AUTH " },
3371     { 36,       "CREATE_CHILD_SA" },
3372     { 37,       "INFORMATIONAL" },
3373     { 0,        NULL },
3374   };
3375
3376   if (isakmp_version == 1) {
3377     if (type > 6 && type < 32)
3378       return "ISAKMP Future Use";
3379     if (type > 33 && type < 240)
3380       return "DOI Specific Use";
3381     return val_to_str(type, vs_v1_exchange, "Private Use");
3382   } else if (isakmp_version == 2) {
3383     if (type < 34)
3384       return "RESERVED";
3385     if (type > 37 && type < 240)
3386       return "Reserved for IKEv2+";
3387     return val_to_str(type, vs_v2_exchange, "Reserved for private use");
3388   }
3389   return "UNKNOWN-ISAKMP-VERSION";
3390 }
3391
3392 static const char *
3393 doitype2str(guint32 type)
3394 {
3395   if (type == 1) return "IPSEC";
3396   return "Unknown DOI Type";
3397 }
3398
3399 static const char *
3400 msgtype2str(int isakmp_version, guint16 type)
3401 {
3402   static const value_string vs_v1_notifmsg[] = {
3403     { 0,        "<UNKNOWN>" },
3404     { 1,        "INVALID-PAYLOAD-TYPE" },
3405     { 2,        "DOI-NOT-SUPPORTED" },
3406     { 3,        "SITUATION-NOT-SUPPORTED" },
3407     { 4,        "INVALID-COOKIE" },
3408     { 5,        "INVALID-MAJOR-VERSION" },
3409     { 6,        "INVALID-MINOR-VERSION" },
3410     { 7,        "INVALID-EXCHANGE-TYPE" },
3411     { 8,        "INVALID-FLAGS" },
3412     { 9,        "INVALID-MESSAGE-ID" },
3413     { 10,       "INVALID-PROTOCOL-ID" },
3414     { 11,       "INVALID-SPI" },
3415     { 12,       "INVALID-TRANSFORM-ID" },
3416     { 13,       "ATTRIBUTES-NOT-SUPPORTED" },
3417     { 14,       "NO-PROPOSAL-CHOSEN" },
3418     { 15,       "BAD-PROPOSAL-SYNTAX" },
3419     { 16,       "PAYLOAD-MALFORMED" },
3420     { 17,       "INVALID-KEY-INFORMATION" },
3421     { 18,       "INVALID-ID-INFORMATION" },
3422     { 19,       "INVALID-CERT-ENCODING" },
3423     { 20,       "INVALID-CERTIFICATE" },
3424     { 21,       "CERT-TYPE-UNSUPPORTED" },
3425     { 22,       "INVALID-CERT-AUTHORITY" },
3426     { 23,       "INVALID-HASH-INFORMATION" },
3427     { 24,       "AUTHENTICATION-FAILED" },
3428     { 25,       "INVALID-SIGNATURE" },
3429     { 26,       "ADDRESS-NOTIFICATION" },
3430     { 27,       "NOTIFY-SA-LIFETIME" },
3431     { 28,       "CERTIFICATE-UNAVAILABLE" },
3432     { 29,       "UNSUPPORTED-EXCHANGE-TYPE" },
3433     { 30,       "UNEQUAL-PAYLOAD-LENGTHS" },
3434     { 8192,     "RESERVED" },
3435     { 16384,    "CONNECTED" },
3436     { 24576,    "RESPONDER-LIFETIME" },
3437     { 24577,    "REPLAY-STATUS" },
3438     { 24578,    "INITIAL-CONTACT" },
3439     { 0,        NULL },
3440   };
3441
3442   static const value_string vs_v2_notifmsg[] = {
3443     {     0,    "RESERVED" },
3444     {     4,    "INVALID_IKE_SPI" },
3445     {     5,    "INVALID_MAJOR_VERSION" },
3446     {     7,    "INVALID_SYNTAX" },
3447     {     9,    "INVALID_MESSAGE_ID" },
3448     {    11,    "INVALID_SPI" },
3449     {    14,    "NO_PROPOSAL_CHOSEN" },
3450     {    17,    "INVALID_KE_PAYLOAD" },
3451     {    24,    "AUTHENTICATION_FAILED" },
3452     {    34,    "SINGLE_PAIR_REQUIRED" },
3453     {    35,    "NO_ADDITIONAL_SAS" },
3454     {    36,    "INTERNAL_ADDRESS_FAILURE" },
3455     {    37,    "FAILED_CP_REQUIRED" },
3456     {    38,    "TS_UNACCEPTABLE" },
3457     {    39,    "INVALID_SELECTORS" },
3458     {    40,    "UNACCEPTABLE_ADDRESSES" },
3459     {    41,    "UNEXPECTED_NAT_DETECTED" },
3460     { 16384,    "INITIAL_CONTACT" },
3461     { 16385,    "SET_WINDOW_SIZE" },
3462     { 16386,    "ADDITIONAL_TS_POSSIBLE" },
3463     { 16387,    "IPCOMP_SUPPORTED" },
3464     { 16388,    "NAT_DETECTION_SOURCE_IP" },
3465     { 16389,    "NAT_DETECTION_DESTINATION_IP" },
3466     { 16390,    "COOKIE" },
3467     { 16391,    "USE_TRANSPORT_MODE" },
3468     { 16392,    "HTTP_CERT_LOOKUP_SUPPORTED" },
3469     { 16393,    "REKEY_SA" },
3470     { 16394,    "ESP_TFC_PADDING_NOT_SUPPORTED" },
3471     { 16395,    "NON_FIRST_FRAGMENTS_ALSO" },
3472     { 16396,    "MOBIKE_SUPPORTED" },
3473     { 16397,    "ADDITIONAL_IP4_ADDRESS" },
3474     { 16398,    "ADDITIONAL_IP6_ADDRESS" },
3475     { 16399,    "NO_ADDITIONAL_ADDRESSES" },
3476     { 16400,    "UPDATE_SA_ADDRESSES" },
3477     { 16401,    "COOKIE2" },
3478     { 16402,    "NO_NATS_ALLOWED" },
3479     { 0,        NULL },
3480   };
3481
3482   if (isakmp_version == 1) {
3483     if (type > 30 && type < 8192)
3484       return "RESERVED (Future Use)";
3485     if (type > 8192 && type < 16384)
3486       return "Private Use";
3487     if (type > 16384 && type < 24576)
3488       return "RESERVED (Future Use) - status";
3489     if (type > 24578 && type < 32768)
3490       return "DOI-specific codes";
3491     if (type > 32767 && type < 40960)
3492       return "Private Use - status";
3493     if (type > 40959 && type < 65535)
3494       return "RESERVED (Future Use) - status (2)";
3495     return val_to_str(type, vs_v1_notifmsg, "UNKNOWN-NOTIFY-MESSAGE-TYPE");
3496   } else if (isakmp_version == 2) {
3497     if (type >= 42 && type <= 8191)
3498       return "RESERVED TO IANA - Error types";
3499     if (type >= 16403 && type <= 40959)
3500       return "RESERVED TO IANA - STATUS TYPES";
3501     if (type >= 8192 && type <= 16383)
3502       return "Private Use - Errors";
3503     if (type >= 40960)
3504       return "Private Use - STATUS TYPES";
3505     return val_to_str(type, vs_v2_notifmsg, "UNKNOWN-NOTIFY-MESSAGE-TYPE");
3506   }
3507   return "UNKNOWN-ISAKMP-VERSION";
3508 }
3509
3510 static const char *
3511 situation2str(guint32 type)
3512 {
3513
3514 #define SIT_MSG_NUM     1024
3515 #define SIT_IDENTITY    0x01
3516 #define SIT_SECRECY     0x02
3517 #define SIT_INTEGRITY   0x04
3518
3519   static char   msg[SIT_MSG_NUM];
3520   int           n = 0;
3521   const char *  sep = "";
3522   int           ret;
3523
3524   if (type & SIT_IDENTITY) {
3525     ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sIDENTITY", sep);
3526     if (ret >= SIT_MSG_NUM-n) {
3527       /* Truncated. */
3528       return msg;
3529     }
3530     n += ret;
3531     sep = " & ";
3532   }
3533   if (type & SIT_SECRECY) {
3534     if (n >= SIT_MSG_NUM) {
3535       /* No more room. */
3536       return msg;
3537     }
3538     ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sSECRECY", sep);
3539     if (ret >= SIT_MSG_NUM-n) {
3540       /* Truncated. */
3541       return msg;
3542     }
3543     n += ret;
3544     sep = " & ";
3545   }
3546   if (type & SIT_INTEGRITY) {
3547     if (n >= SIT_MSG_NUM) {
3548       /* No more room. */
3549       return msg;
3550     }
3551     ret = g_snprintf(msg, SIT_MSG_NUM-n, "%sINTEGRITY", sep);
3552     if (ret >= SIT_MSG_NUM-n) {
3553       /* Truncated. */
3554       return msg;
3555     }
3556     n += ret;
3557     sep = " & ";
3558   }
3559
3560   return msg;
3561 }
3562
3563 static const char *
3564 v2_attrval2str(guint16 att_type)
3565 {
3566   switch (att_type) {
3567   case 14:
3568     return "Key-Length";
3569   default:
3570     return "UNKNOWN-ATTRIBUTE-TYPE";
3571   }
3572 }
3573
3574 static const char *
3575 v1_attrval2str(int ike_p1, guint16 att_type, guint32 value)
3576 {
3577   static const value_string vs_v1_attrval_lttype[] = {
3578     { 0,        "RESERVED" },
3579     { 1,        "Seconds" },
3580     { 2,        "Kilobytes" },
3581     { 0,        NULL },
3582   };
3583
3584   static const value_string vs_v1_attrval_encap[] = {
3585     { 0,        "RESERVED" },
3586     { 1,        "Tunnel" },
3587     { 2,        "Transport" },
3588     { 3,        "UDP-Encapsulated-Tunnel" }, /* http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-05.txt */
3589     { 4,        "UDP-Encapsulated-Transport" }, /* http://www.ietf.org/internet-drafts/draft-ietf-ipsec-nat-t-ike-05.txt */
3590     { 61440,    "Check Point IPSec UDP Encapsulation" },
3591     { 61443,    "UDP-Encapsulated-Tunnel (draft)" },
3592     { 61444,    "UDP-Encapsulated-Transport (draft)" },
3593     { 0,        NULL },
3594   };
3595
3596   static const value_string vs_v1_attrval_auth[] = {
3597     { 0,        "RESERVED" },
3598     { 1,        "HMAC-MD5" },
3599     { 2,        "HMAC-SHA" },
3600     { 3,        "DES-MAC" },
3601     { 4,        "KPDK" },
3602     { 5,        "HMAC-SHA2-256" },
3603     { 6,        "HMAC-SHA2-384" },
3604     { 7,        "HMAC-SHA2-512" },
3605     { 0,        NULL },
3606   };
3607
3608   static const value_string vs_v1_attrval_enc[] = {
3609     { 0,                        "RESERVED" },
3610     { ENC_DES_CBC,              "DES-CBC" },
3611     { ENC_IDEA_CBC,             "IDEA-CBC" },
3612     { ENC_BLOWFISH_CBC,         "BLOWFISH-CBC" },
3613     { ENC_RC5_R16_B64_CBC,      "RC5-R16-B64-CBC" },
3614     { ENC_3DES_CBC,             "3DES-CBC" },
3615     { ENC_CAST_CBC,             "CAST-CBC" },
3616     { ENC_AES_CBC,              "AES-CBC" },
3617     { 0,        NULL },
3618   };
3619
3620   static const value_string vs_v1_attrval_hash[] = {
3621     { 0,                "RESERVED" },
3622     { HMAC_MD5,         "MD5" },
3623     { HMAC_SHA,         "SHA" },
3624     { HMAC_TIGER,       "TIGER" },
3625     { HMAC_SHA2_256,    "SHA2-256" },
3626     { HMAC_SHA2_384,    "SHA2-384" },
3627     { HMAC_SHA2_512,    "SHA2-512" },
3628     { 0,        NULL },
3629   };
3630
3631   static const value_string vs_v1_attrval_authmeth[] = {
3632     { 0,        "RESERVED" },
3633     { 1,        "PSK" },
3634     { 2,        "DSS-SIG" },
3635     { 3,        "RSA-SIG" },
3636     { 4,        "RSA-ENC" },
3637     { 5,        "RSA-Revised-ENC" },
3638     { 6,        "Encryption with El-Gamal" },
3639     { 7,        "Revised encryption with El-Gamal" },
3640     { 8,        "ECDSA signatures" },
3641     { 9,        "AES-XCBC-MAC" },
3642     { 64221,    "HybridInitRSA" },
3643     { 64222,    "HybridRespRSA" },
3644     { 64223,    "HybridInitDSS" },
3645     { 64224,    "HybridRespDSS" },
3646     { 65001,    "XAUTHInitPreShared" },
3647     { 65002,    "XAUTHRespPreShared" },
3648     { 65003,    "XAUTHInitDSS" },
3649     { 65004,    "XAUTHRespDSS" },
3650     { 65005,    "XAUTHInitRSA" },
3651     { 65006,    "XAUTHRespRSA" },
3652     { 65007,    "XAUTHInitRSAEncryption" },
3653     { 65008,    "XAUTHRespRSAEncryption" },
3654     { 65009,    "XAUTHInitRSARevisedEncryption" },
3655     { 65010,    "XAUTHRespRSARevisedEncryption" },
3656     { 0,        NULL },
3657   };
3658
3659   static const value_string vs_v1_attrval_grpdesc[] = {
3660     { 0,        "UNDEFINED - 0" },
3661     { 1,        "Default 768-bit MODP group" },
3662     { 2,        "Alternate 1024-bit MODP group" },
3663     { 3,        "EC2N group on GP[2^155] group" },
3664     { 4,        "EC2N group on GP[2^185] group" },
3665     { 5,        "1536 bit MODP group" },
3666     { 6,        "EC2N group over GF[2^163]" },
3667     { 7,        "EC2N group over GF[2^163]" },
3668     { 8,        "EC2N group over GF[2^283]" },
3669     { 9,        "EC2N group over GF[2^283]" },
3670     { 10,       "EC2N group over GF[2^409]" },
3671     { 11,       "EC2N group over GF[2^409]" },
3672     { 12,       "EC2N group over GF[2^571]" },
3673     { 13,       "EC2N group over GF[2^571]" },
3674     { 14,       "2048 bit MODP group" },
3675     { 15,       "3072 bit MODP group" },
3676     { 16,       "4096 bit MODP group" },
3677     { 17,       "6144 bit MODP group" },
3678     { 18,       "8192 bit MODP group" },
3679     { 19,       "256-bit random curve group" },
3680     { 20,       "384-bit random curve group" },
3681     { 21,       "521-bit random curve group" },
3682     { 22,       "192-bit random curve group" },
3683     { 23,       "EC2N group over GF[2^163]" },
3684     { 24,       "224-bit random curve group" },
3685     { 25,       "EC2N group over GF[2^233]" },
3686     { 26,       "EC2N group over GF[2^233]" },
3687     { 0,        NULL }
3688   };
3689
3690   static const value_string vs_v1_attrval_grptype[] = {
3691     { 0,        "UNDEFINED - 0" },
3692     { 1,        "MODP" },
3693     { 2,        "ECP" },
3694     { 3,        "EC2N" },
3695     { 0,        NULL },
3696   };
3697
3698   static const value_string vs_v1_attrval_lifetype[] = {
3699     { 0,        "UNDEFINED - 0" },
3700     { 1,        "Seconds" },
3701     { 2,        "Kilobytes" },
3702     { 0,        NULL },
3703   };
3704
3705   if (value == 0) return "RESERVED";
3706
3707   if (!ike_p1) {
3708     switch (att_type) {
3709       case 1:
3710         return val_to_str(value, vs_v1_attrval_lttype, "UNKNOWN-LIFETIME-TYPE");
3711       case 2:
3712         return "Duration-Value";
3713       case 3:
3714         return "Group-Value";
3715       case 4:
3716         return val_to_str(value, vs_v1_attrval_encap, "UNKNOWN-ENCAPSULATION-VALUE");
3717       case 5:
3718         return val_to_str(value, vs_v1_attrval_auth, "UNKNOWN-AUTHENTICATION-VALUE");
3719       case 6:
3720         return "Key-Length";
3721       case 7:
3722         return "Key-Rounds";
3723       case 8:
3724         return "Compress-Dictionary-size";
3725       case 9:
3726         return "Compress Private Algorithm";
3727       default:
3728         return "UNKNOWN-ATTRIBUTE-TYPE";
3729     }
3730   }
3731   else {
3732     switch (att_type) {
3733       case 1:
3734         return val_to_str(value, vs_v1_attrval_enc, "UNKNOWN-ENCRYPTION-ALG");
3735       case 2:
3736         return val_to_str(value, vs_v1_attrval_hash, "UNKNOWN-HASH-ALG");
3737       case 3:
3738         return val_to_str(value, vs_v1_attrval_authmeth, "UNKNOWN-AUTH-METHOD");
3739       case 4:
3740         return val_to_str(value, vs_v1_attrval_grpdesc, "UNKNOWN-GROUP-DESCRIPTION");
3741       case 6:
3742       case 7:
3743       case 8:
3744       case 9:
3745       case 10:
3746       case 16:
3747         return "Group-Value";
3748       case 5:
3749         return val_to_str(value, vs_v1_attrval_grptype, "UNKNOWN-GROUP-TYPE");
3750       case 11:
3751         return val_to_str(value, vs_v1_attrval_lifetype, "UNKNOWN-LIFE-TYPE");
3752       case 12:
3753         return "Duration-Value";
3754       case 13:
3755         return "PRF-Value";
3756       case 14:
3757         return "Key-Length";
3758       case 15:
3759         return "Field-Size";
3760       default:
3761         return "UNKNOWN-ATTRIBUTE-TYPE";
3762     }
3763   }
3764 }
3765 static const char *
3766 v2_tstype2str(guint8 type)
3767 {
3768   static const value_string vs_v2_tstype[] = {
3769     { IKEV2_TS_IPV4_ADDR_RANGE, "TS_IPV4_ADDR_RANGE" },
3770     { IKEV2_TS_IPV6_ADDR_RANGE, "TS_IPV6_ADDR_RANGE" },
3771     { 0,        NULL },
3772   };
3773
3774   if (type <= 6)
3775     return "RESERVED";
3776   if (type >= 9 && type <= 240)
3777     return "RESERVED TO IANA";
3778   if (type >= 241)
3779     return "PRIVATE USE";
3780   return val_to_str(type, vs_v2_tstype, "UNKNOWN-TS-TYPE");
3781 }
3782
3783 static const char *
3784 v2_auth2str(guint8 type)
3785 {
3786   static const value_string vs_v2_authmeth[] = {
3787     { 0,        "RESERVED TO IANA" },
3788     { 1,        "RSA Digital Signature" },
3789     { 2,        "Shared Key Message Integrity Code" },
3790     { 3,        "DSS Digital Signature" },
3791     { 0,        NULL },
3792   };
3793
3794   if (type >= 4 && type <= 200)
3795     return "RESERVED TO IANA";
3796   if (type >= 201)
3797     return "PRIVATE USE";
3798   return val_to_str(type, vs_v2_authmeth, "UNKNOWN-AUTHMETHOD-TYPE");
3799 }
3800 /*
3801 static const char *
3802 cfgattr2str(int isakmp_version, guint16 ident)
3803 {
3804   static const value_string vs_v1_cfgattr[] = {
3805     { 0,        "RESERVED" },
3806     { 1,        "INTERNAL_IP4_ADDRESS" },
3807     { 2,        "INTERNAL_IP4_NETMASK" },
3808     { 3,        "INTERNAL_IP4_DNS" },
3809     { 4,        "INTERNAL_IP4_NBNS" },
3810     { 5,        "INTERNAL_ADDRESS_EXPIREY" },
3811     { 6,        "INTERNAL_IP4_DHCP" },
3812     { 7,        "APPLICATION_VERSION" },
3813     { 8,        "INTERNAL_IP6_ADDRESS" },
3814     { 9,        "INTERNAL_IP6_NETMASK" },
3815     { 10,       "INTERNAL_IP6_DNS" },
3816     { 11,       "INTERNAL_IP6_NBNS" },
3817     { 12,       "INTERNAL_IP6_DHCP" },
3818     { 13,       "INTERNAL_IP4_SUBNET" },
3819     { 14,       "SUPPORTED_ATTRIBUTES" },
3820     { 16520,    "XAUTH_TYPE" },
3821     { 16521,    "XAUTH_USER_NAME" },
3822     { 16522,    "XAUTH_USER_PASSWORD" },
3823     { 16523,    "XAUTH_PASSCODE" },
3824     { 16524,    "XAUTH_MESSAGE" },
3825     { 16525,    "XAUTH_CHALLANGE" },
3826     { 16526,    "XAUTH_DOMAIN" },
3827     { 16527,    "XAUTH_STATUS" },
3828     { 16528,    "XAUTH_NEXT_PIN" },
3829     { 16529,    "XAUTH_ANSWER" },
3830     { 0,        NULL },
3831   };
3832
3833   static const value_string vs_v2_cfgattr[] = {
3834     { 0,        "RESERVED" },
3835     { 1,        "INTERNAL_IP4_ADDRESS" },
3836     { 2,        "INTERNAL_IP4_NETMASK" },
3837     { 3,        "INTERNAL_IP4_DNS" },
3838     { 4,        "INTERNAL_IP4_NBNS" },
3839     { 5,        "INTERNAL_ADDRESS_EXPIREY" },
3840     { 6,        "INTERNAL_IP4_DHCP" },
3841     { 7,        "APPLICATION_VERSION" },
3842     { 8,        "INTERNAL_IP6_ADDRESS" },
3843     { 9,        "RESERVED" },
3844     { 10,       "INTERNAL_IP6_DNS" },
3845     { 11,       "INTERNAL_IP6_NBNS" },
3846     { 12,       "INTERNAL_IP6_DHCP" },
3847     { 13,       "INTERNAL_IP4_SUBNET" },
3848     { 14,       "SUPPORTED_ATTRIBUTES" },
3849     { 15,       "INTERNAL_IP6_SUBNET" },
3850     { 0,        NULL },
3851   };
3852
3853   if (isakmp_version == 1) {
3854     if (ident >= 15 && ident <= 16383)
3855       return "Future use";
3856     if (ident >= 16384 && ident <= 16519)
3857       return "PRIVATE USE";
3858     if (ident >= 16530 && ident <= 32767)
3859       return "PRIVATE USE";
3860     return val_to_str(ident, vs_v1_cfgattr, "UNKNOWN-CFG-ATTRIBUTE");
3861   } else if (isakmp_version == 2) {
3862     if (ident >= 16 && ident <= 16383)
3863       return "RESERVED TO IANA";
3864     if (ident >= 16384 && ident <= 32767)
3865       return "PRIVATE USE";
3866     return val_to_str(ident, vs_v2_cfgattr, "UNKNOWN-CFG-ATTRIBUTE");
3867   }
3868   return "UNKNOWN-ISAKMP-VERSION";
3869 }
3870 */
3871 static const char *
3872 certtype2str(int isakmp_version, guint8 type)
3873 {
3874   static const value_string vs_v1_certtype[] = {
3875     { 0,        "NONE" },
3876     { 1,        "PKCS #7 wrapped X.509 certificate" },
3877     { 2,        "PGP Certificate" },
3878     { 3,        "DNS Signed Key" },
3879     { 4,        "X.509 Certificate - Signature" },
3880     { 5,        "X.509 Certificate - Key Exchange" },
3881     { 6,        "Kerberos Tokens" },
3882     { 7,        "Certificate Revocation List (CRL)" },
3883     { 8,        "Authority Revocation List (ARL)" },
3884     { 9,        "SPKI Certificate" },
3885     { 10,       "X.509 Certificate - Attribute" },
3886     { 0,        NULL },
3887   };
3888
3889   static const value_string vs_v2_certtype[] = {
3890     { 0,        "RESERVED" },
3891     { 1,        "PKCS #7 wrapped X.509 certificate" },
3892     { 2,        "PGP Certificate" },
3893     { 3,        "DNS Signed Key" },
3894     { 4,        "X.509 Certificate - Signature" },
3895     { 5,        "*undefined by any document*" },
3896     { 6,        "Kerberos Tokens" },
3897     { 7,        "Certificate Revocation List (CRL)" },
3898     { 8,        "Authority Revocation List (ARL)" },
3899     { 9,        "SPKI Certificate" },
3900     { 10,       "X.509 Certificate - Attribute" },
3901     { 11,       "Raw RSA Key" },
3902     { 12,       "Hash and URL of X.509 certificate" },
3903     { 13,       "Hash and URL of X.509 bundle" },
3904     { 0,        NULL },
3905   };
3906
3907   if (isakmp_version == 1)
3908     return val_to_str(type, vs_v1_certtype, "RESERVED");
3909   else if (isakmp_version == 2) {
3910     if (type >= 14 && type <= 200)
3911       return "RESERVED to IANA";
3912     if (type >= 201)
3913       return "PRIVATE USE";
3914     return val_to_str(type, vs_v2_certtype, "RESERVED");
3915   }
3916   return "UNKNOWN-ISAKMP-VERSION";
3917 }
3918
3919 static gboolean
3920 get_num(tvbuff_t *tvb, int offset, guint16 len, guint32 *num_p)
3921 {
3922   switch (len) {
3923   case 1:
3924     *num_p = tvb_get_guint8(tvb, offset);
3925     break;
3926   case 2:
3927     *num_p = tvb_get_ntohs(tvb, offset);
3928     break;
3929   case 3:
3930     *num_p = tvb_get_ntoh24(tvb, offset);
3931     break;
3932   case 4:
3933     *num_p = tvb_get_ntohl(tvb, offset);
3934     break;
3935   default:
3936     return FALSE;
3937   }
3938
3939   return TRUE;
3940 }
3941
3942 /*
3943  * Protocol initialization
3944  */
3945
3946 #ifdef HAVE_LIBGCRYPT
3947 static guint
3948 isakmp_hash_func(gconstpointer c) {
3949   guint8 *i_cookie = (guint8 *) c;
3950   guint   val = 0, keychunk, i;
3951
3952   /* XOR our icookie down to the size of a guint */
3953   for (i = 0; i < COOKIE_SIZE - (COOKIE_SIZE % sizeof(keychunk)); i += sizeof(keychunk)) {
3954     memcpy(&keychunk, &i_cookie[i], sizeof(keychunk));
3955     val ^= keychunk;
3956   }
3957
3958   return val;
3959 }
3960
3961 static gint
3962 isakmp_equal_func(gconstpointer ic1, gconstpointer ic2) {
3963
3964   if (memcmp(ic1, ic2, COOKIE_SIZE) == 0)
3965     return 1;
3966
3967   return 0;
3968 }
3969
3970 static guint ikev2_key_hash_func(gconstpointer k) {
3971   const ikev2_uat_data_key_t *key = (const ikev2_uat_data_key_t*)k;
3972   guint hash = 0, keychunk, i;
3973
3974   /* XOR our icookie down to the size of a guint */
3975   for (i = 0; i < key->spii_len - (key->spii_len % sizeof(keychunk)); i += sizeof(keychunk)) {
3976     memcpy(&keychunk, &key->spii[i], sizeof(keychunk));
3977     hash ^= keychunk;
3978   }
3979   for (i = 0; i < key->spir_len - (key->spir_len % sizeof(keychunk)); i += sizeof(keychunk)) {
3980     memcpy(&keychunk, &key->spir[i], sizeof(keychunk));
3981     hash ^= keychunk;
3982   }
3983
3984   return hash;
3985 }
3986
3987 static gint ikev2_key_equal_func(gconstpointer k1, gconstpointer k2) {
3988   const ikev2_uat_data_key_t *key1 = k1, *key2 = k2;
3989   if (key1->spii_len != key2->spii_len) return 0;
3990   if (key1->spir_len != key2->spir_len) return 0;
3991   if (memcmp(key1->spii, key2->spii, key1->spii_len) != 0) return 0;
3992   if (memcmp(key1->spir, key2->spir, key1->spir_len) != 0) return 0;
3993
3994   return 1;
3995 }
3996 #endif /* HAVE_LIBGCRYPT */
3997
3998 #ifdef HAVE_LIBGCRYPT
3999 #if GLIB_CHECK_VERSION(2,10,0)
4000 static gboolean
4001 free_cookie(gpointer key_arg, gpointer value, gpointer user_data _U_)
4002 {
4003   guint8 *ic_key = key_arg;
4004   decrypt_data_t *decr = value;
4005
4006   g_slice_free1(COOKIE_SIZE, ic_key);
4007   g_slice_free1(sizeof(decrypt_data_t), decr);
4008   return TRUE;
4009 }
4010 #endif
4011 #endif
4012
4013 static void
4014 isakmp_init_protocol(void) {
4015 #ifdef HAVE_LIBGCRYPT
4016   guint i;
4017 #endif /* HAVE_LIBGCRYPT */
4018   fragment_table_init(&isakmp_fragment_table);
4019   reassembled_table_init(&isakmp_reassembled_table);
4020
4021 #ifdef HAVE_LIBGCRYPT
4022   if (isakmp_hash) {
4023 #if GLIB_CHECK_VERSION(2,10,0)
4024     g_hash_table_foreach_remove(isakmp_hash, free_cookie, NULL);
4025 #endif
4026     g_hash_table_destroy(isakmp_hash);
4027   }
4028 #if GLIB_CHECK_VERSION(2,10,0)
4029 #else
4030   if (isakmp_key_data)
4031     g_mem_chunk_destroy(isakmp_key_data);
4032   if (isakmp_decrypt_data)
4033     g_mem_chunk_destroy(isakmp_decrypt_data);
4034
4035   isakmp_key_data = g_mem_chunk_new("isakmp_key_data",
4036         COOKIE_SIZE, 5 * COOKIE_SIZE,
4037         G_ALLOC_AND_FREE);
4038   isakmp_decrypt_data = g_mem_chunk_new("isakmp_decrypt_data",
4039         sizeof(decrypt_data_t), 5 * sizeof(decrypt_data_t),
4040         G_ALLOC_AND_FREE);
4041 #endif
4042   isakmp_hash = g_hash_table_new(isakmp_hash_func, isakmp_equal_func);
4043   if (log_f)
4044     fclose(log_f);
4045   log_f = ws_fopen(pluto_log_path, "r");
4046
4047   scan_pluto_log();
4048
4049   if (ikev2_key_hash) {
4050     g_hash_table_destroy(ikev2_key_hash);
4051   }
4052
4053   ikev2_key_hash = g_hash_table_new(ikev2_key_hash_func, ikev2_key_equal_func);
4054   for (i = 0; i < num_ikev2_uat_data; i++) {
4055     g_hash_table_insert(ikev2_key_hash, &(ikev2_uat_data[i].key), &(ikev2_uat_data[i]));
4056   }
4057 #endif /* HAVE_LIBGCRYPT */
4058 }
4059
4060 static void
4061 isakmp_prefs_apply_cb(void) {
4062 #ifdef HAVE_LIBGCRYPT
4063   isakmp_init_protocol();
4064 #endif /* HAVE_LIBGCRYPT */
4065 }
4066
4067 #ifdef HAVE_LIBGCRYPT
4068 UAT_BUFFER_CB_DEF(ikev2_users, spii, ikev2_uat_data_t, key.spii, key.spii_len)
4069 UAT_BUFFER_CB_DEF(ikev2_users, spir, ikev2_uat_data_t, key.spir, key.spir_len)
4070 UAT_BUFFER_CB_DEF(ikev2_users, sk_ei, ikev2_uat_data_t, sk_ei, sk_ei_len)
4071 UAT_BUFFER_CB_DEF(ikev2_users, sk_er, ikev2_uat_data_t, sk_er, sk_er_len)
4072 UAT_VS_DEF(ikev2_users, encr_alg, ikev2_uat_data_t, IKEV2_ENCR_3DES, IKEV2_ENCR_3DES_STR)
4073 UAT_BUFFER_CB_DEF(ikev2_users, sk_ai, ikev2_uat_data_t, sk_ai, sk_ai_len)
4074 UAT_BUFFER_CB_DEF(ikev2_users, sk_ar, ikev2_uat_data_t, sk_ar, sk_ar_len)
4075 UAT_VS_DEF(ikev2_users, auth_alg, ikev2_uat_data_t, IKEV2_AUTH_HMAC_SHA1_96, IKEV2_AUTH_HMAC_SHA1_96_STR)
4076
4077 static void ikev2_uat_data_update_cb(void* p, const char** err) {
4078   ikev2_uat_data_t *ud = p;
4079
4080   if (ud->key.spii_len != COOKIE_SIZE) {
4081     *err = ep_strdup_printf("Length of Initiator's SPI must be %d octets (%d hex characters).", COOKIE_SIZE, COOKIE_SIZE * 2);
4082     return;
4083   }
4084
4085   if (ud->key.spir_len != COOKIE_SIZE) {
4086     *err = ep_strdup_printf("Length of Responder's SPI must be %d octets (%d hex characters).", COOKIE_SIZE, COOKIE_SIZE * 2);
4087     return;
4088   }
4089
4090   if ((ud->encr_spec = ikev2_decrypt_find_encr_spec(ud->encr_alg)) == NULL) {
4091     REPORT_DISSECTOR_BUG("Couldn't get IKEv2 encryption algorithm spec.");
4092   }
4093
4094   if ((ud->auth_spec = ikev2_decrypt_find_auth_spec(ud->auth_alg)) == NULL) {
4095     REPORT_DISSECTOR_BUG("Couldn't get IKEv2 authentication algorithm spec.");
4096   }
4097
4098   if (ud->sk_ei_len != ud->encr_spec->key_len) {
4099     *err = ep_strdup_printf("Length of SK_ei (%u octets) does not match the key length (%u octets) of the selected encryption algorithm.",
4100              ud->sk_ei_len, ud->encr_spec->key_len);
4101     return;
4102   }
4103
4104   if (ud->sk_er_len != ud->encr_spec->key_len) {
4105     *err = ep_strdup_printf("Length of SK_er (%u octets) does not match the key length (%u octets) of the selected encryption algorithm.",
4106              ud->sk_er_len, ud->encr_spec->key_len);
4107     return;
4108   }
4109
4110   if (ud->sk_ai_len != ud->auth_spec->key_len) {
4111     *err = ep_strdup_printf("Length of SK_ai (%u octets) does not match the key length (%u octets) of the selected integrity algorithm.",
4112              ud->sk_ai_len, ud->auth_spec->key_len);
4113     return;
4114   }
4115
4116   if (ud->sk_ar_len != ud->auth_spec->key_len) {
4117     *err = ep_strdup_printf("Length of SK_ar (%u octets) does not match the key length (%u octets) of the selected integrity algorithm.",
4118              ud->sk_ar_len, ud->auth_spec->key_len);
4119     return;
4120   }
4121 }
4122 #endif /* HAVE_LIBGCRYPT */
4123
4124 void
4125 proto_register_isakmp(void)
4126 {
4127   module_t *isakmp_module;
4128
4129   static hf_register_info hf[] = {
4130     { &hf_isakmp_icookie,
4131       { "Initiator cookie", "isakmp.icookie",
4132         FT_BYTES, BASE_NONE, NULL, 0x0,
4133         "ISAKMP Initiator Cookie", HFILL }},
4134     { &hf_isakmp_rcookie,
4135       { "Responder cookie", "isakmp.rcookie",
4136         FT_BYTES, BASE_NONE, NULL, 0x0,
4137         "ISAKMP Responder Cookie", HFILL }},
4138     { &hf_isakmp_nextpayload,
4139       { "Next payload", "isakmp.nextpayload",
4140         FT_UINT8, BASE_DEC, NULL, 0x0,
4141         "ISAKMP Next Payload", HFILL }},
4142     { &hf_isakmp_version,
4143       { "Version", "isakmp.version",
4144         FT_UINT8, BASE_HEX, NULL, 0x0,
4145         "ISAKMP Version (major + minor)", HFILL }},
4146     { &hf_isakmp_exchangetype,
4147       { "Exchange type", "isakmp.exchangetype",
4148         FT_UINT8, BASE_DEC, NULL, 0x0,
4149         "ISAKMP Exchange Type", HFILL }},
4150     { &hf_isakmp_flags,
4151       { "Flags", "isakmp.flags",
4152         FT_UINT8, BASE_HEX, NULL, 0x0,
4153         "ISAKMP Flags", HFILL }},
4154     { &hf_isakmp_flag_e,
4155       { "Encryption", "isakmp.flag_e",
4156         FT_BOOLEAN, 8, TFS(&flag_e), E_FLAG,
4157         "Encryption Bit", HFILL }},
4158     { &hf_isakmp_flag_c,
4159       { "Commit", "isakmp.flag_c",
4160         FT_BOOLEAN, 8, TFS(&flag_c), C_FLAG,
4161         "Commit Bit", HFILL }},
4162     { &hf_isakmp_flag_a,
4163       { "Authentication", "isakmp.flag_a",
4164         FT_BOOLEAN, 8, TFS(&flag_a), A_FLAG,
4165         "Authentication Bit", HFILL }},
4166     { &hf_isakmp_flag_i,
4167       { "Initiator", "isakmp.flag_i",
4168         FT_BOOLEAN, 8, TFS(&flag_i), I_FLAG,
4169         "Initiator Bit", HFILL }},
4170     { &hf_isakmp_flag_v,
4171       { "Version", "isakmp.flag_v",
4172         FT_BOOLEAN, 8, TFS(&flag_v), V_FLAG,
4173         "Version Bit", HFILL }},
4174     { &hf_isakmp_flag_r,
4175       { "Response", "isakmp.flag_r",
4176         FT_BOOLEAN, 8, TFS(&flag_r), R_FLAG,
4177         "Response Bit", HFILL }},
4178     { &hf_isakmp_messageid,
4179       { "Message ID", "isakmp.messageid",
4180         FT_UINT32, BASE_HEX, NULL, 0x0,
4181         "ISAKMP Message ID", HFILL }},
4182     { &hf_isakmp_length,
4183       { "Length", "isakmp.length",
4184         FT_UINT32, BASE_DEC, NULL, 0x0,
4185         "ISAKMP Length", HFILL }},
4186     { &hf_isakmp_payloadlen,
4187       { "Payload length", "isakmp.payloadlength",
4188         FT_UINT16, BASE_DEC, NULL, 0x0,
4189         "ISAKMP Payload Length", HFILL }},
4190     { &hf_isakmp_doi,
4191       { "Domain of interpretation", "isakmp.doi",
4192         FT_UINT32, BASE_DEC, NULL, 0x0,
4193         "ISAKMP Domain of Interpretation", HFILL }},
4194     { &hf_isakmp_sa_situation,
4195       { "Situation", "isakmp.sa.situation",
4196         FT_BYTES, BASE_NONE, NULL, 0x0,
4197         "ISAKMP SA Situation", HFILL }},
4198     { &hf_isakmp_prop_number,
4199       { "Proposal number", "isakmp.prop.number",
4200         FT_UINT8, BASE_DEC, NULL, 0x0,
4201         "ISAKMP Proposal Number", HFILL }},
4202     { &hf_isakmp_spisize,
4203       { "SPI Size", "isakmp.spisize",
4204         FT_UINT8, BASE_DEC, NULL, 0x0,
4205         "ISAKMP SPI Size", HFILL }},
4206     { &hf_isakmp_prop_transforms,
4207       { "Proposal transforms", "isakmp.prop.transforms",
4208         FT_UINT8, BASE_DEC, NULL, 0x0,
4209         "ISAKMP Proposal Transforms", HFILL }},
4210     { &hf_isakmp_trans_number,
4211       { "Transform number", "isakmp.trans.number",
4212         FT_UINT8, BASE_DEC, NULL, 0x0,
4213         "ISAKMP Transform Number", HFILL }},
4214     { &hf_isakmp_trans_id,
4215       { "Transform ID", "isakmp.trans.id",
4216         FT_UINT8, BASE_DEC, NULL, 0x0,
4217         "ISAKMP Transform ID", HFILL }},
4218     { &hf_isakmp_id_type_v1,
4219       { "ID type", "isakmp.id.type",
4220         FT_UINT8, BASE_DEC, RVALS(&vs_v1_id_type), 0x0,
4221         "ISAKMP (v1) ID Type", HFILL }},
4222     { &hf_isakmp_id_type_v2,
4223       { "ID type", "isakmp.id.type",
4224         FT_UINT8, BASE_DEC, RVALS(&vs_v2_id_type), 0x0,
4225         "ISAKMP (v2) ID Type", HFILL }},
4226     { &hf_isakmp_protoid,
4227       { "Protocol ID", "isakmp.protoid",
4228         FT_UINT8, BASE_DEC, NULL, 0x0,
4229         "ISAKMP Protocol ID", HFILL }},
4230     { &hf_isakmp_id_port,
4231       { "Port", "isakmp.id.port",
4232         FT_UINT16, BASE_DEC, NULL, 0x0,
4233         "ISAKMP ID Port", HFILL }},
4234     { &hf_isakmp_cert_encoding,
4235       { "Port", "isakmp.cert.encoding",
4236         FT_UINT8, BASE_DEC, NULL, 0x0,
4237         "ISAKMP Certificate Encoding", HFILL }},
4238     { &hf_isakmp_certificate,
4239       { "Certificate", "isakmp.certificate",
4240         FT_NONE, BASE_NONE, NULL, 0x0,
4241         "ISAKMP Certificate Encoding", HFILL }},
4242     { &hf_isakmp_certreq_type,
4243       { "Port", "isakmp.certreq.type",
4244         FT_UINT8, BASE_DEC, NULL, 0x0,
4245         "ISAKMP Certificate Request Type", HFILL }},
4246     { &hf_isakmp_notify_msgtype,
4247       { "Port", "isakmp.notify.msgtype",
4248         FT_UINT8, BASE_DEC, NULL, 0x0,
4249         "ISAKMP Notify Message Type", HFILL }},
4250     { &hf_isakmp_num_spis,
4251       { "Port", "isakmp.spinum",
4252         FT_UINT16, BASE_DEC, NULL, 0x0,
4253         "ISAKMP Number of SPIs", HFILL }},
4254     { &hf_isakmp_cisco_frag_packetid,
4255       { "Frag ID", "isakmp.frag.packetid",
4256         FT_UINT16, BASE_HEX, NULL, 0x0,
4257         "ISAKMP fragment packet-id", HFILL }},
4258     { &hf_isakmp_cisco_frag_seq,
4259       { "Frag seq", "isakmp.frag.packetid",
4260         FT_UINT8, BASE_DEC, NULL, 0x0,
4261         "ISAKMP fragment number", HFILL }},
4262     { &hf_isakmp_cisco_frag_last,
4263       { "Frag last", "isakmp.frag.last",
4264         FT_UINT8, BASE_DEC, VALS(frag_last_vals), 0x0,
4265         "ISAKMP last fragment", HFILL }},
4266     { &hf_isakmp_fragments,
4267             {"Message fragments", "isakmp.fragments",
4268             FT_NONE, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4269     { &hf_isakmp_fragment,
4270             {"Message fragment", "isakmp.fragment",
4271             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4272     { &hf_isakmp_fragment_overlap,
4273             {"Message fragment overlap", "isakmp.fragment.overlap",
4274             FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4275     { &hf_isakmp_fragment_overlap_conflicts,
4276             {"Message fragment overlapping with conflicting data",
4277             "isakmp.fragment.overlap.conflicts",
4278             FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4279     { &hf_isakmp_fragment_multiple_tails,
4280             {"Message has multiple tail fragments",
4281             "isakmp.fragment.multiple_tails",
4282             FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4283     { &hf_isakmp_fragment_too_long_fragment,
4284             {"Message fragment too long", "isakmp.fragment.too_long_fragment",
4285             FT_BOOLEAN, BASE_NONE, NULL, 0x0, NULL, HFILL } },
4286     { &hf_isakmp_fragment_error,
4287             {"Message defragmentation error", "isakmp.fragment.error",
4288             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4289     { &hf_isakmp_reassembled_in,
4290             {"Reassembled in", "isakmp.reassembled.in",
4291             FT_FRAMENUM, BASE_NONE, NULL, 0x00, NULL, HFILL } },
4292     { &hf_isakmp_reassembled_length,
4293             {"Reassembled ISAKMP length", "isakmp.reassembled.length",
4294             FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } },
4295     { &hf_isakmp_certificate_authority,
4296       { "Certificate Authority Distinguished Name", "ike.cert_authority_dn", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }
4297     },
4298     { &hf_isakmp_v2_certificate_authority,
4299       { "Certificate Authority", "ike.cert_authority", FT_BYTES, BASE_NONE, NULL, 0x0, "SHA-1 hash of the Certificate Authority", HFILL }
4300     },
4301     { &hf_isakmp_nat_keepalive,
4302       { "NAT Keepalive", "ike.nat_keepalive", FT_NONE, BASE_NONE, NULL, 0x0, "NAT Keepalive packet", HFILL }
4303     },
4304    { &hf_isakmp_nat_hash,
4305       { "HASH of the address and port", "ike.nat_hash",
4306         FT_BYTES, BASE_NONE, NULL, 0x00,
4307         NULL, HFILL }},
4308    { &hf_isakmp_nat_original_address_ipv4,
4309       { "NAT Original IPv4 Address",    "ike.nat_original_address_ipv4",
4310         FT_IPv4, BASE_NONE, NULL, 0x00,
4311         NULL, HFILL }},
4312    { &hf_isakmp_nat_original_address_ipv6,
4313       { "NAT Original IPv6 Address",    "ike.nat_original_address_ipv6",
4314         FT_IPv6, BASE_NONE, NULL, 0x00,
4315         NULL, HFILL }},
4316
4317     { &hf_isakmp_cfg_type_v1,
4318       { "Type", "isakmp.cfg.type_v1",
4319          FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v1_cfgtype), 0x0,
4320          "ISAKMP (v1) Config Type", HFILL }},
4321     { &hf_isakmp_cfg_identifier,
4322       { "Identifier", "isakmp.cfg.identifier",
4323          FT_UINT16, BASE_DEC, NULL, 0x0,
4324          "ISAKMP (v1) Config Identifier", HFILL }},
4325     { &hf_isakmp_cfg_type_v2,
4326       { "Type", "isakmp.cfg.type_v2",
4327          FT_UINT8, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v2_cfgtype), 0x0,
4328          "ISAKMP (v2) Config Type", HFILL }},
4329         /* Attributes Type */
4330    { &hf_isakmp_cfg_attr_type_v1,
4331       { "Type", "isakmp.cfg.attr.type_v1",
4332         FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v1_cfgattr), 0x00,
4333         "ISAKMP (v1) Config Attribute type", HFILL }},
4334    { &hf_isakmp_cfg_attr_type_v2,
4335       { "Type", "isakmp.cfg.attr.type_v2",
4336         FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&vs_v2_cfgattr), 0x00,
4337         "ISAKMP (v2) Config Attribute type", HFILL }},
4338    { &hf_isakmp_cfg_attr_length,
4339       { "Length",       "isakmp.cfg.attr.length",
4340         FT_UINT16, BASE_DEC, NULL, 0x00,
4341         "ISAKMP Config Attribute length", HFILL }},
4342    { &hf_isakmp_cfg_attr_value,
4343       { "Value",        "isakmp.cfg.attr.value",
4344         FT_BYTES, BASE_NONE, NULL, 0x00,
4345         "ISAKMP Config Attribute value", HFILL }},
4346   { &hf_isakmp_cfg_attr_internal_ip4_address,
4347       { "INTERNAL IP4 ADDRESS", "isakmp.cfg.attr.internal_ip4_address",
4348         FT_IPv4, BASE_NONE, NULL, 0x00,
4349         " An IPv4 address on the internal network", HFILL }},
4350  { &hf_isakmp_cfg_attr_internal_ip4_netmask,
4351       { "INTERNAL IP4 NETMASK", "isakmp.cfg.attr.internal_ip4_netmask",
4352         FT_IPv4, BASE_NONE, NULL, 0x00,
4353         "The internal network's netmask", HFILL }},
4354  { &hf_isakmp_cfg_attr_internal_ip4_dns,
4355       { "INTERNAL IP4 DNS",     "isakmp.cfg.attr.internal_ip4_dns",
4356         FT_IPv4, BASE_NONE, NULL, 0x00,
4357         "An IPv4 address of a DNS server within the network", HFILL }},
4358  { &hf_isakmp_cfg_attr_internal_ip4_nbns,
4359       { "INTERNAL IP4 NBNS",    "isakmp.cfg.attr.internal_ip4_nbns",
4360         FT_IPv4, BASE_NONE, NULL, 0x00,
4361         "An IPv4 address of a NetBios Name Server (WINS) within the network", HFILL }},
4362  { &hf_isakmp_cfg_attr_internal_address_expiry,
4363       { "INTERNAL ADDRESS EXPIRY (Secs)",       "isakmp.cfg.attr.internal_address_expiry",
4364         FT_UINT32, BASE_DEC, NULL, 0x00,
4365         "Specifies the number of seconds that the host can use the internal IP address", HFILL }},
4366  { &hf_isakmp_cfg_attr_internal_ip4_dhcp,
4367       { "INTERNAL IP4 DHCP",    "isakmp.cfg.attr.internal_ip4_dhcp",
4368         FT_IPv4, BASE_NONE, NULL, 0x00,
4369         "the host to send any internal DHCP requests to the address", HFILL }},
4370   { &hf_isakmp_cfg_attr_application_version,
4371       { "APPLICATION VERSION",  "isakmp.cfg.attr.application_version",
4372         FT_STRING, BASE_NONE, NULL, 0x00,
4373         "The version or application information of the IPsec host", HFILL }},
4374   { &hf_isakmp_cfg_attr_internal_ip6_address,
4375       { "INTERNAL IP6 ADDRESS", "isakmp.cfg.attr.internal_ip6_address",
4376         FT_IPv4, BASE_NONE, NULL, 0x00,
4377         " An IPv6 address on the internal network", HFILL }},
4378  { &hf_isakmp_cfg_attr_internal_ip6_netmask,
4379       { "INTERNAL IP4 NETMASK", "isakmp.cfg.attr.internal_ip6_netmask",
4380         FT_IPv6, BASE_NONE, NULL, 0x00,
4381         "The internal network's netmask", HFILL }},
4382  { &hf_isakmp_cfg_attr_internal_ip6_dns,
4383       { "INTERNAL IP6 DNS",     "isakmp.cfg.attr.internal_ip6_dns",
4384         FT_IPv6, BASE_NONE, NULL, 0x00,
4385         "An IPv6 address of a DNS server within the network", HFILL }},
4386  { &hf_isakmp_cfg_attr_internal_ip6_nbns,
4387       { "INTERNAL IP6 NBNS",    "isakmp.cfg.attr.internal_ip6_nbns",
4388         FT_IPv6, BASE_NONE, NULL, 0x00,
4389         "An IPv6 address of a NetBios Name Server (WINS) within the network", HFILL }},
4390  { &hf_isakmp_cfg_attr_internal_ip6_dhcp,
4391       { "INTERNAL IP6 DHCP",    "isakmp.cfg.attr.internal_ip6_dhcp",
4392         FT_IPv6, BASE_NONE, NULL, 0x00,
4393         "the host to send any internal DHCP requests to the address", HFILL }},
4394  { &hf_isakmp_cfg_attr_internal_ip4_subnet_ip,
4395       { "INTERNAL IP4 SUBNET (IP)",     "isakmp.cfg.attr.internal_ip4_subnet_ip",
4396         FT_IPv4, BASE_NONE, NULL, 0x00,
4397         "The protected sub-networks that this edge-device protects (IP)", HFILL }},
4398  { &hf_isakmp_cfg_attr_internal_ip4_subnet_netmask,
4399       { "INTERNAL IP4 SUBNET (NETMASK)",        "isakmp.cfg.attr.internal_ip4_subnet_netmask",
4400         FT_IPv4, BASE_NONE, NULL, 0x00,
4401         "The protected sub-networks that this edge-device protects (IP)", HFILL }},
4402   { &hf_isakmp_cfg_attr_xauth_type,
4403       { "XAUTH TYPE",   "isakmp.cfg.attr.xauth.type",
4404         FT_UINT16, BASE_RANGE_STRING | BASE_DEC, RVALS(&cfgattr_xauth_type), 0x00,
4405         "The type of extended authentication requested", HFILL }},
4406
4407   { &hf_isakmp_cfg_attr_xauth_user_name,
4408       { "XAUTH USER NAME",      "isakmp.cfg.attr.xauth.user_name",
4409         FT_STRING, BASE_NONE, NULL, 0x00,
4410         "The user name", HFILL }},
4411
4412   { &hf_isakmp_cfg_attr_xauth_user_password,
4413       { "XAUTH USER PASSWORD",  "isakmp.cfg.attr.xauth.user_password",
4414         FT_STRING, BASE_NONE, NULL, 0x00,
4415         "The user's password", HFILL }},
4416   { &hf_isakmp_cfg_attr_xauth_passcode,
4417       { "XAUTH PASSCODE",       "isakmp.cfg.attr.xauth.passcode",
4418         FT_STRING, BASE_NONE, NULL, 0x00,
4419         "A token card's passcode", HFILL }},
4420   { &hf_isakmp_cfg_attr_xauth_message,
4421       { "XAUTH MESSAGE",        "isakmp.cfg.attr.xauth.message",
4422         FT_STRING, BASE_NONE, NULL, 0x00,
4423         "A textual message from an edge device to an IPSec host", HFILL }},
4424   { &hf_isakmp_cfg_attr_xauth_challenge,
4425       { "XAUTH CHALLENGE",      "isakmp.cfg.attr.xauth.challenge",
4426         FT_STRING, BASE_NONE, NULL, 0x00,
4427         "A challenge string sent from the edge device to the IPSec host for it to include in its calculation of a password", HFILL }},
4428
4429   { &hf_isakmp_cfg_attr_xauth_domain,
4430       { "XAUTH DOMAIN", "isakmp.cfg.attr.xauth.domain",
4431         FT_STRING, BASE_NONE, NULL, 0x00,
4432         "The domain to be authenticated in", HFILL }},
4433   { &hf_isakmp_cfg_attr_xauth_status,
4434       { "XAUTH STATUS", "isakmp.cfg.attr.xauth.status",
4435         FT_UINT16, BASE_DEC, VALS(cfgattr_xauth_status), 0x00,
4436         "A variable that is used to denote authentication success or failure", HFILL }},
4437   { &hf_isakmp_cfg_attr_xauth_next_pin,
4438       { "XAUTH TYPE",   "isakmp.cfg.attr.xauth.next_pin",
4439         FT_STRING, BASE_NONE, NULL, 0x00,
4440         "A variable which is used when the edge device is requesting that the user choose a new pin number", HFILL }},
4441   { &hf_isakmp_cfg_attr_xauth_answer,
4442       { "XAUTH ANSWER", "isakmp.cfg.attr.xauth.answer",
4443         FT_STRING, BASE_NONE, NULL, 0x00,
4444         "A variable length ASCII string used to send input to the edge device", HFILL }},
4445   { &hf_isakmp_cfg_attr_unity_banner,
4446       { "UNITY BANNER", "isakmp.cfg.attr.unity.banner",
4447         FT_STRING, BASE_NONE, NULL, 0x00,
4448         "Banner", HFILL }},
4449   };
4450
4451
4452   static gint *ett[] = {
4453     &ett_isakmp,
4454     &ett_isakmp_flags,
4455     &ett_isakmp_payload,
4456     &ett_isakmp_fragment,
4457     &ett_isakmp_fragments,
4458     &ett_isakmp_cfg_attr,
4459 #ifdef HAVE_LIBGCRYPT
4460     &ett_isakmp_decrypted_data,
4461     &ett_isakmp_decrypted_payloads
4462 #endif /* HAVE_LIBGCRYPT */
4463   };
4464 #ifdef HAVE_LIBGCRYPT
4465   static uat_field_t ikev2_uat_flds[] = {
4466     UAT_FLD_BUFFER(ikev2_users, spii, "Initiator's SPI", "Initiator's SPI value of the IKE_SA"),
4467     UAT_FLD_BUFFER(ikev2_users, spir, "Responder's SPI", "Responder's SPI value of the IKE_SA"),
4468     UAT_FLD_BUFFER(ikev2_users, sk_ei, "SK_ei", "Key used to encrypt/decrypt IKEv2 packets from initiator to responder"),
4469     UAT_FLD_BUFFER(ikev2_users, sk_er, "SK_er", "Key used to encrypt/decrypt IKEv2 packets from responder to initiator"),
4470     UAT_FLD_VS(ikev2_users, encr_alg, "Encryption algorithm", vs_ikev2_encr_algs, "Encryption algorithm of IKE_SA"),
4471     UAT_FLD_BUFFER(ikev2_users, sk_ai, "SK_ai", "Key used to calculate Integrity Checksum Data for IKEv2 packets from initiator to responder"),
4472     UAT_FLD_BUFFER(ikev2_users, sk_ar, "SK_ar", "Key used to calculate Integrity Checksum Data for IKEv2 packets from responder to initiator"),
4473     UAT_FLD_VS(ikev2_users, auth_alg, "Integrity algorithm", vs_ikev2_auth_algs, "Integrity algorithm of IKE_SA"),
4474     UAT_END_FIELDS
4475   };
4476 #endif /* HAVE_LIBGCRYPT */
4477   proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol",
4478                                                "ISAKMP", "isakmp");
4479   proto_register_field_array(proto_isakmp, hf, array_length(hf));
4480   proto_register_subtree_array(ett, array_length(ett));
4481   register_init_routine(&isakmp_init_protocol);
4482
4483   register_dissector("isakmp", dissect_isakmp, proto_isakmp);
4484
4485   isakmp_module = prefs_register_protocol(proto_isakmp, isakmp_prefs_apply_cb);
4486 #ifdef HAVE_LIBGCRYPT
4487   prefs_register_string_preference(isakmp_module, "log",
4488     "Log Filename",
4489     "Path to a pluto log file containing DH secret information",
4490     &pluto_log_path);
4491
4492   ikev2_uat = uat_new("IKEv2 Decryption Table",
4493       sizeof(ikev2_uat_data_t),
4494       "ikev2_decryption_table",
4495       TRUE,
4496       (void*)&ikev2_uat_data,
4497       &num_ikev2_uat_data,
4498       UAT_CAT_CRYPTO,
4499       "ChIKEv2DecryptionSection",
4500       NULL,
4501       ikev2_uat_data_update_cb,
4502       NULL,
4503       ikev2_uat_flds);
4504
4505   prefs_register_uat_preference(isakmp_module,
4506       "ikev2_decryption_table",
4507       "IKEv2 Decryption Table",
4508       "Table of IKE_SA security parameters for decryption of IKEv2 packets",
4509       ikev2_uat);
4510
4511 #endif /* HAVE_LIBGCRYPT */
4512 }
4513
4514 void
4515 proto_reg_handoff_isakmp(void)
4516 {
4517   dissector_handle_t isakmp_handle;
4518
4519   isakmp_handle = find_dissector("isakmp");
4520   eap_handle = find_dissector("eap");
4521   dissector_add("udp.port", UDP_PORT_ISAKMP, isakmp_handle);
4522   dissector_add("tcp.port", TCP_PORT_ISAKMP, isakmp_handle);
4523 }