1/*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31/* \summary: Internet Security Association and Key Management Protocol (ISAKMP) printer */
32
33/* specification: RFC 2407, RFC 2408, RFC 5996 */
34
35#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif
38
39/* The functions from print-esp.c used in this file are only defined when both
40 * OpenSSL and evp.h are detected. Employ the same preprocessor device here.
41 */
42#ifndef HAVE_OPENSSL_EVP_H
43#undef HAVE_LIBCRYPTO
44#endif
45
46#include "netdissect-stdinc.h"
47
48#include <string.h>
49
50#include "netdissect-ctype.h"
51
52#include "netdissect.h"
53#include "addrtoname.h"
54#include "extract.h"
55
56#include "ip.h"
57#include "ip6.h"
58#include "ipproto.h"
59
60typedef nd_byte cookie_t[8];
61typedef nd_byte msgid_t[4];
62
63#define PORT_ISAKMP 500
64
65/* 3.1 ISAKMP Header Format (IKEv1 and IKEv2)
66         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
67        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
68        !                          Initiator                            !
69        !                            Cookie                             !
70        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
71        !                          Responder                            !
72        !                            Cookie                             !
73        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74        !  Next Payload ! MjVer ! MnVer ! Exchange Type !     Flags     !
75        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76        !                          Message ID                           !
77        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
78        !                            Length                             !
79        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80*/
81struct isakmp {
82	cookie_t i_ck;		/* Initiator Cookie */
83	cookie_t r_ck;		/* Responder Cookie */
84	nd_uint8_t np;		/* Next Payload Type */
85	nd_uint8_t vers;
86#define ISAKMP_VERS_MAJOR	0xf0
87#define ISAKMP_VERS_MAJOR_SHIFT	4
88#define ISAKMP_VERS_MINOR	0x0f
89#define ISAKMP_VERS_MINOR_SHIFT	0
90	nd_uint8_t etype;	/* Exchange Type */
91	nd_uint8_t flags;	/* Flags */
92	msgid_t msgid;
93	nd_uint32_t len;	/* Length */
94};
95
96/* Next Payload Type */
97#define ISAKMP_NPTYPE_NONE   0 /* NONE*/
98#define ISAKMP_NPTYPE_SA     1 /* Security Association */
99#define ISAKMP_NPTYPE_P      2 /* Proposal */
100#define ISAKMP_NPTYPE_T      3 /* Transform */
101#define ISAKMP_NPTYPE_KE     4 /* Key Exchange */
102#define ISAKMP_NPTYPE_ID     5 /* Identification */
103#define ISAKMP_NPTYPE_CERT   6 /* Certificate */
104#define ISAKMP_NPTYPE_CR     7 /* Certificate Request */
105#define ISAKMP_NPTYPE_HASH   8 /* Hash */
106#define ISAKMP_NPTYPE_SIG    9 /* Signature */
107#define ISAKMP_NPTYPE_NONCE 10 /* Nonce */
108#define ISAKMP_NPTYPE_N     11 /* Notification */
109#define ISAKMP_NPTYPE_D     12 /* Delete */
110#define ISAKMP_NPTYPE_VID   13 /* Vendor ID */
111#define ISAKMP_NPTYPE_v2E   46 /* v2 Encrypted payload */
112
113#define IKEv1_MAJOR_VERSION  1
114#define IKEv1_MINOR_VERSION  0
115
116#define IKEv2_MAJOR_VERSION  2
117#define IKEv2_MINOR_VERSION  0
118
119/* Flags */
120#define ISAKMP_FLAG_E 0x01 /* Encryption Bit */
121#define ISAKMP_FLAG_C 0x02 /* Commit Bit */
122#define ISAKMP_FLAG_extra 0x04
123
124/* IKEv2 */
125#define ISAKMP_FLAG_I (1 << 3)  /* (I)nitiator */
126#define ISAKMP_FLAG_V (1 << 4)  /* (V)ersion   */
127#define ISAKMP_FLAG_R (1 << 5)  /* (R)esponse  */
128
129
130/* 3.2 Payload Generic Header
131         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
132        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
133        ! Next Payload  !   RESERVED    !         Payload Length        !
134        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135*/
136struct isakmp_gen {
137	nd_uint8_t  np;       /* Next Payload */
138	nd_uint8_t  critical; /* bit 7 - critical, rest is RESERVED */
139	nd_uint16_t len;      /* Payload Length */
140};
141
142/* 3.3 Data Attributes
143         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
144        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
145        !A!       Attribute Type        !    AF=0  Attribute Length     !
146        !F!                             !    AF=1  Attribute Value      !
147        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148        .                   AF=0  Attribute Value                       .
149        .                   AF=1  Not Transmitted                       .
150        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
151*/
152struct isakmp_data {
153	nd_uint16_t type;     /* defined by DOI-spec, and Attribute Format */
154	nd_uint16_t lorv;     /* if f equal 1, Attribute Length */
155	                      /* if f equal 0, Attribute Value */
156	/* if f equal 1, Attribute Value */
157};
158
159/* 3.4 Security Association Payload */
160	/* MAY NOT be used, because of being defined in ipsec-doi. */
161	/*
162	If the current payload is the last in the message,
163	then the value of the next payload field will be 0.
164	This field MUST NOT contain the
165	values for the Proposal or Transform payloads as they are considered
166	part of the security association negotiation.  For example, this
167	field would contain the value "10" (Nonce payload) in the first
168	message of a Base Exchange (see Section 4.4) and the value "0" in the
169	first message of an Identity Protect Exchange (see Section 4.5).
170	*/
171struct ikev1_pl_sa {
172	struct isakmp_gen h;
173	nd_uint32_t doi; /* Domain of Interpretation */
174	nd_uint32_t sit; /* Situation */
175};
176
177/* 3.5 Proposal Payload */
178	/*
179	The value of the next payload field MUST only contain the value "2"
180	or "0".  If there are additional Proposal payloads in the message,
181	then this field will be 2.  If the current Proposal payload is the
182	last within the security association proposal, then this field will
183	be 0.
184	*/
185struct ikev1_pl_p {
186	struct isakmp_gen h;
187	nd_uint8_t p_no;      /* Proposal # */
188	nd_uint8_t prot_id;   /* Protocol */
189	nd_uint8_t spi_size;  /* SPI Size */
190	nd_uint8_t num_t;     /* Number of Transforms */
191	/* SPI */
192};
193
194/* 3.6 Transform Payload */
195	/*
196	The value of the next payload field MUST only contain the value "3"
197	or "0".  If there are additional Transform payloads in the proposal,
198	then this field will be 3.  If the current Transform payload is the
199	last within the proposal, then this field will be 0.
200	*/
201struct ikev1_pl_t {
202	struct isakmp_gen h;
203	nd_uint8_t  t_no;        /* Transform # */
204	nd_uint8_t  t_id;        /* Transform-Id */
205	nd_byte     reserved[2]; /* RESERVED2 */
206	/* SA Attributes */
207};
208
209/* 3.7 Key Exchange Payload */
210struct ikev1_pl_ke {
211	struct isakmp_gen h;
212	/* Key Exchange Data */
213};
214
215/* 3.8 Identification Payload */
216	/* MUST NOT to be used, because of being defined in ipsec-doi. */
217struct ikev1_pl_id {
218	struct isakmp_gen h;
219	union {
220		nd_uint8_t  id_type;   /* ID Type */
221		nd_uint32_t doi_data;  /* DOI Specific ID Data */
222	} d;
223	/* Identification Data */
224};
225
226/* 3.9 Certificate Payload */
227struct ikev1_pl_cert {
228	struct isakmp_gen h;
229	nd_uint8_t encode; /* Cert Encoding */
230	nd_uint8_t cert;   /* Certificate Data */
231		/*
232		This field indicates the type of
233		certificate or certificate-related information contained in the
234		Certificate Data field.
235		*/
236};
237
238/* 3.10 Certificate Request Payload */
239struct ikev1_pl_cr {
240	struct isakmp_gen h;
241	nd_uint8_t num_cert; /* # Cert. Types */
242	/*
243	Certificate Types (variable length)
244	  -- Contains a list of the types of certificates requested,
245	  sorted in order of preference.  Each individual certificate
246	  type is 1 octet.  This field is NOT requiredo
247	*/
248	/* # Certificate Authorities (1 octet) */
249	/* Certificate Authorities (variable length) */
250};
251
252/* 3.11 Hash Payload */
253	/* may not be used, because of having only data. */
254struct ikev1_pl_hash {
255	struct isakmp_gen h;
256	/* Hash Data */
257};
258
259/* 3.12 Signature Payload */
260	/* may not be used, because of having only data. */
261struct ikev1_pl_sig {
262	struct isakmp_gen h;
263	/* Signature Data */
264};
265
266/* 3.13 Nonce Payload */
267	/* may not be used, because of having only data. */
268struct ikev1_pl_nonce {
269	struct isakmp_gen h;
270	/* Nonce Data */
271};
272
273/* 3.14 Notification Payload */
274struct ikev1_pl_n {
275	struct isakmp_gen h;
276	nd_uint32_t doi;      /* Domain of Interpretation */
277	nd_uint8_t  prot_id;  /* Protocol-ID */
278	nd_uint8_t  spi_size; /* SPI Size */
279	nd_uint16_t type;     /* Notify Message Type */
280	/* SPI */
281	/* Notification Data */
282};
283
284/* 3.14.1 Notify Message Types */
285/* NOTIFY MESSAGES - ERROR TYPES */
286#define ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE           1
287#define ISAKMP_NTYPE_DOI_NOT_SUPPORTED              2
288#define ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED        3
289#define ISAKMP_NTYPE_INVALID_COOKIE                 4
290#define ISAKMP_NTYPE_INVALID_MAJOR_VERSION          5
291#define ISAKMP_NTYPE_INVALID_MINOR_VERSION          6
292#define ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE          7
293#define ISAKMP_NTYPE_INVALID_FLAGS                  8
294#define ISAKMP_NTYPE_INVALID_MESSAGE_ID             9
295#define ISAKMP_NTYPE_INVALID_PROTOCOL_ID            10
296#define ISAKMP_NTYPE_INVALID_SPI                    11
297#define ISAKMP_NTYPE_INVALID_TRANSFORM_ID           12
298#define ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED       13
299#define ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN             14
300#define ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX            15
301#define ISAKMP_NTYPE_PAYLOAD_MALFORMED              16
302#define ISAKMP_NTYPE_INVALID_KEY_INFORMATION        17
303#define ISAKMP_NTYPE_INVALID_ID_INFORMATION         18
304#define ISAKMP_NTYPE_INVALID_CERT_ENCODING          19
305#define ISAKMP_NTYPE_INVALID_CERTIFICATE            20
306#define ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX        21
307#define ISAKMP_NTYPE_INVALID_CERT_AUTHORITY         22
308#define ISAKMP_NTYPE_INVALID_HASH_INFORMATION       23
309#define ISAKMP_NTYPE_AUTHENTICATION_FAILED          24
310#define ISAKMP_NTYPE_INVALID_SIGNATURE              25
311#define ISAKMP_NTYPE_ADDRESS_NOTIFICATION           26
312
313/* 3.15 Delete Payload */
314struct ikev1_pl_d {
315	struct isakmp_gen h;
316	nd_uint32_t doi;      /* Domain of Interpretation */
317	nd_uint8_t  prot_id;  /* Protocol-Id */
318	nd_uint8_t  spi_size; /* SPI Size */
319	nd_uint16_t num_spi;  /* # of SPIs */
320	/* SPI(es) */
321};
322
323/* IKEv2 (RFC4306) */
324
325/* 3.3  Security Association Payload -- generic header */
326/* 3.3.1.  Proposal Substructure */
327struct ikev2_p {
328	struct isakmp_gen h;
329	nd_uint8_t p_no;      /* Proposal # */
330	nd_uint8_t prot_id;   /* Protocol */
331	nd_uint8_t spi_size;  /* SPI Size */
332	nd_uint8_t num_t;     /* Number of Transforms */
333};
334
335/* 3.3.2.  Transform Substructure */
336struct ikev2_t {
337	struct isakmp_gen h;
338	nd_uint8_t  t_type;    /* Transform Type (ENCR,PRF,INTEG,etc.*/
339	nd_byte     res2;      /* reserved byte */
340	nd_uint16_t t_id;     /* Transform ID */
341};
342
343enum ikev2_t_type {
344	IV2_T_ENCR = 1,
345	IV2_T_PRF  = 2,
346	IV2_T_INTEG= 3,
347	IV2_T_DH   = 4,
348	IV2_T_ESN  = 5
349};
350
351/* 3.4.  Key Exchange Payload */
352struct ikev2_ke {
353	struct isakmp_gen h;
354	nd_uint16_t  ke_group;
355	nd_uint16_t  ke_res1;
356	/* KE data */
357};
358
359
360/* 3.5.  Identification Payloads */
361enum ikev2_id_type {
362	ID_IPV4_ADDR=1,
363	ID_FQDN=2,
364	ID_RFC822_ADDR=3,
365	ID_IPV6_ADDR=5,
366	ID_DER_ASN1_DN=9,
367	ID_DER_ASN1_GN=10,
368	ID_KEY_ID=11
369};
370struct ikev2_id {
371	struct isakmp_gen h;
372	nd_uint8_t type;        /* ID type */
373	nd_byte    res1;
374	nd_byte    res2[2];
375	/* SPI */
376	/* Notification Data */
377};
378
379/* 3.10 Notification Payload */
380struct ikev2_n {
381	struct isakmp_gen h;
382	nd_uint8_t  prot_id;  /* Protocol-ID */
383	nd_uint8_t  spi_size; /* SPI Size */
384	nd_uint16_t type;     /* Notify Message Type */
385};
386
387enum ikev2_n_type {
388	IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD            = 1,
389	IV2_NOTIFY_INVALID_IKE_SPI                         = 4,
390	IV2_NOTIFY_INVALID_MAJOR_VERSION                   = 5,
391	IV2_NOTIFY_INVALID_SYNTAX                          = 7,
392	IV2_NOTIFY_INVALID_MESSAGE_ID                      = 9,
393	IV2_NOTIFY_INVALID_SPI                             =11,
394	IV2_NOTIFY_NO_PROPOSAL_CHOSEN                      =14,
395	IV2_NOTIFY_INVALID_KE_PAYLOAD                      =17,
396	IV2_NOTIFY_AUTHENTICATION_FAILED                   =24,
397	IV2_NOTIFY_SINGLE_PAIR_REQUIRED                    =34,
398	IV2_NOTIFY_NO_ADDITIONAL_SAS                       =35,
399	IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE                =36,
400	IV2_NOTIFY_FAILED_CP_REQUIRED                      =37,
401	IV2_NOTIFY_INVALID_SELECTORS                       =39,
402	IV2_NOTIFY_INITIAL_CONTACT                         =16384,
403	IV2_NOTIFY_SET_WINDOW_SIZE                         =16385,
404	IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE                  =16386,
405	IV2_NOTIFY_IPCOMP_SUPPORTED                        =16387,
406	IV2_NOTIFY_NAT_DETECTION_SOURCE_IP                 =16388,
407	IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP            =16389,
408	IV2_NOTIFY_COOKIE                                  =16390,
409	IV2_NOTIFY_USE_TRANSPORT_MODE                      =16391,
410	IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED              =16392,
411	IV2_NOTIFY_REKEY_SA                                =16393,
412	IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED           =16394,
413	IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO                =16395
414};
415
416struct notify_messages {
417	uint16_t type;
418	char     *msg;
419};
420
421/* 3.8 Authentication Payload */
422struct ikev2_auth {
423	struct isakmp_gen h;
424	nd_uint8_t  auth_method;  /* Protocol-ID */
425	nd_byte     reserved[3];
426	/* authentication data */
427};
428
429enum ikev2_auth_type {
430	IV2_RSA_SIG = 1,
431	IV2_SHARED  = 2,
432	IV2_DSS_SIG = 3
433};
434
435/* refer to RFC 2409 */
436
437#if 0
438/* isakmp sa structure */
439struct oakley_sa {
440	uint8_t  proto_id;            /* OAKLEY */
441	vchar_t   *spi;                /* spi */
442	uint8_t  dhgrp;               /* DH; group */
443	uint8_t  auth_t;              /* method of authentication */
444	uint8_t  prf_t;               /* type of prf */
445	uint8_t  hash_t;              /* type of hash */
446	uint8_t  enc_t;               /* type of cipher */
447	uint8_t  life_t;              /* type of duration of lifetime */
448	uint32_t ldur;                /* life duration */
449};
450#endif
451
452/* refer to RFC 2407 */
453
454#define IPSEC_DOI 1
455
456/* 4.2 IPSEC Situation Definition */
457#define IPSECDOI_SIT_IDENTITY_ONLY           0x00000001
458#define IPSECDOI_SIT_SECRECY                 0x00000002
459#define IPSECDOI_SIT_INTEGRITY               0x00000004
460
461/* 4.4.1 IPSEC Security Protocol Identifiers */
462  /* 4.4.2 IPSEC ISAKMP Transform Values */
463#define IPSECDOI_PROTO_ISAKMP                        1
464#define   IPSECDOI_KEY_IKE                             1
465
466/* 4.4.1 IPSEC Security Protocol Identifiers */
467#define IPSECDOI_PROTO_IPSEC_AH                      2
468  /* 4.4.3 IPSEC AH Transform Values */
469#define   IPSECDOI_AH_MD5                              2
470#define   IPSECDOI_AH_SHA                              3
471#define   IPSECDOI_AH_DES                              4
472#define   IPSECDOI_AH_SHA2_256                         5
473#define   IPSECDOI_AH_SHA2_384                         6
474#define   IPSECDOI_AH_SHA2_512                         7
475
476/* 4.4.1 IPSEC Security Protocol Identifiers */
477#define IPSECDOI_PROTO_IPSEC_ESP                     3
478  /* 4.4.4 IPSEC ESP Transform Identifiers */
479#define   IPSECDOI_ESP_DES_IV64                        1
480#define   IPSECDOI_ESP_DES                             2
481#define   IPSECDOI_ESP_3DES                            3
482#define   IPSECDOI_ESP_RC5                             4
483#define   IPSECDOI_ESP_IDEA                            5
484#define   IPSECDOI_ESP_CAST                            6
485#define   IPSECDOI_ESP_BLOWFISH                        7
486#define   IPSECDOI_ESP_3IDEA                           8
487#define   IPSECDOI_ESP_DES_IV32                        9
488#define   IPSECDOI_ESP_RC4                            10
489#define   IPSECDOI_ESP_NULL                           11
490#define   IPSECDOI_ESP_RIJNDAEL				12
491#define   IPSECDOI_ESP_AES				12
492
493/* 4.4.1 IPSEC Security Protocol Identifiers */
494#define IPSECDOI_PROTO_IPCOMP                        4
495  /* 4.4.5 IPSEC IPCOMP Transform Identifiers */
496#define   IPSECDOI_IPCOMP_OUI                          1
497#define   IPSECDOI_IPCOMP_DEFLATE                      2
498#define   IPSECDOI_IPCOMP_LZS                          3
499
500/* 4.5 IPSEC Security Association Attributes */
501#define IPSECDOI_ATTR_SA_LTYPE                1 /* B */
502#define   IPSECDOI_ATTR_SA_LTYPE_DEFAULT        1
503#define   IPSECDOI_ATTR_SA_LTYPE_SEC            1
504#define   IPSECDOI_ATTR_SA_LTYPE_KB             2
505#define IPSECDOI_ATTR_SA_LDUR                 2 /* V */
506#define   IPSECDOI_ATTR_SA_LDUR_DEFAULT         28800 /* 8 hours */
507#define IPSECDOI_ATTR_GRP_DESC                3 /* B */
508#define IPSECDOI_ATTR_ENC_MODE                4 /* B */
509	/* default value: host dependent */
510#define   IPSECDOI_ATTR_ENC_MODE_TUNNEL         1
511#define   IPSECDOI_ATTR_ENC_MODE_TRNS           2
512#define IPSECDOI_ATTR_AUTH                    5 /* B */
513	/* 0 means not to use authentication. */
514#define   IPSECDOI_ATTR_AUTH_HMAC_MD5           1
515#define   IPSECDOI_ATTR_AUTH_HMAC_SHA1          2
516#define   IPSECDOI_ATTR_AUTH_DES_MAC            3
517#define   IPSECDOI_ATTR_AUTH_KPDK               4 /*RFC-1826(Key/Pad/Data/Key)*/
518	/*
519	 * When negotiating ESP without authentication, the Auth
520	 * Algorithm attribute MUST NOT be included in the proposal.
521	 * When negotiating ESP without confidentiality, the Auth
522	 * Algorithm attribute MUST be included in the proposal and
523	 * the ESP transform ID must be ESP_NULL.
524	*/
525#define IPSECDOI_ATTR_KEY_LENGTH              6 /* B */
526#define IPSECDOI_ATTR_KEY_ROUNDS              7 /* B */
527#define IPSECDOI_ATTR_COMP_DICT_SIZE          8 /* B */
528#define IPSECDOI_ATTR_COMP_PRIVALG            9 /* V */
529
530/* 4.6.1 Security Association Payload */
531struct ipsecdoi_sa {
532	struct isakmp_gen h;
533	nd_uint32_t doi; /* Domain of Interpretation */
534	nd_uint32_t sit; /* Situation */
535};
536
537struct ipsecdoi_secrecy_h {
538	nd_uint16_t len;
539	nd_uint16_t reserved;
540};
541
542/* 4.6.2.1 Identification Type Values */
543struct ipsecdoi_id {
544	struct isakmp_gen h;
545	nd_uint8_t  type;	/* ID Type */
546	nd_uint8_t  proto_id;	/* Protocol ID */
547	nd_uint16_t port;	/* Port */
548	/* Identification Data */
549};
550
551#define IPSECDOI_ID_IPV4_ADDR                        1
552#define IPSECDOI_ID_FQDN                             2
553#define IPSECDOI_ID_USER_FQDN                        3
554#define IPSECDOI_ID_IPV4_ADDR_SUBNET                 4
555#define IPSECDOI_ID_IPV6_ADDR                        5
556#define IPSECDOI_ID_IPV6_ADDR_SUBNET                 6
557#define IPSECDOI_ID_IPV4_ADDR_RANGE                  7
558#define IPSECDOI_ID_IPV6_ADDR_RANGE                  8
559#define IPSECDOI_ID_DER_ASN1_DN                      9
560#define IPSECDOI_ID_DER_ASN1_GN                      10
561#define IPSECDOI_ID_KEY_ID                           11
562
563/* 4.6.3 IPSEC DOI Notify Message Types */
564/* Notify Messages - Status Types */
565#define IPSECDOI_NTYPE_RESPONDER_LIFETIME                  24576
566#define IPSECDOI_NTYPE_REPLAY_STATUS                       24577
567#define IPSECDOI_NTYPE_INITIAL_CONTACT                     24578
568
569#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \
570		netdissect_options *ndo, u_char tpay,	              \
571		const struct isakmp_gen *ext,			      \
572		u_int item_len, \
573		const u_char *end_pointer, \
574		uint32_t phase,\
575		uint32_t doi0, \
576		uint32_t proto0, int depth)
577
578DECLARE_PRINTER(v1_sa);
579DECLARE_PRINTER(v1_p);
580DECLARE_PRINTER(v1_t);
581DECLARE_PRINTER(v1_ke);
582DECLARE_PRINTER(v1_id);
583DECLARE_PRINTER(v1_cert);
584DECLARE_PRINTER(v1_cr);
585DECLARE_PRINTER(v1_sig);
586DECLARE_PRINTER(v1_hash);
587DECLARE_PRINTER(v1_nonce);
588DECLARE_PRINTER(v1_n);
589DECLARE_PRINTER(v1_d);
590DECLARE_PRINTER(v1_vid);
591
592DECLARE_PRINTER(v2_sa);
593DECLARE_PRINTER(v2_ke);
594DECLARE_PRINTER(v2_ID);
595DECLARE_PRINTER(v2_cert);
596DECLARE_PRINTER(v2_cr);
597DECLARE_PRINTER(v2_auth);
598DECLARE_PRINTER(v2_nonce);
599DECLARE_PRINTER(v2_n);
600DECLARE_PRINTER(v2_d);
601DECLARE_PRINTER(v2_vid);
602DECLARE_PRINTER(v2_TS);
603DECLARE_PRINTER(v2_cp);
604DECLARE_PRINTER(v2_eap);
605
606static const u_char *ikev2_e_print(netdissect_options *ndo,
607				   const struct isakmp *base,
608				   u_char tpay,
609				   const struct isakmp_gen *ext,
610				   u_int item_len,
611				   const u_char *end_pointer,
612				   uint32_t phase,
613				   uint32_t doi0,
614				   uint32_t proto0, int depth);
615
616
617static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
618	const u_char *,	uint32_t, uint32_t, uint32_t, int);
619static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
620	const u_char *, uint32_t, uint32_t, uint32_t, int);
621
622static const u_char *ikev2_sub_print(netdissect_options *ndo,
623				     const struct isakmp *base,
624				     u_char np, const struct isakmp_gen *ext,
625				     const u_char *ep, uint32_t phase,
626				     uint32_t doi, uint32_t proto,
627				     int depth);
628
629
630static char *numstr(u_int);
631
632static void
633ikev1_print(netdissect_options *ndo,
634	    const u_char *bp,  u_int length,
635	    const u_char *bp2, const struct isakmp *base);
636
637#define MAXINITIATORS	20
638static int ninitiator = 0;
639union inaddr_u {
640	nd_ipv4 in4;
641	nd_ipv6 in6;
642};
643static struct {
644	cookie_t initiator;
645	u_int version;
646	union inaddr_u iaddr;
647	union inaddr_u raddr;
648} cookiecache[MAXINITIATORS];
649
650/* protocol id */
651static const char *protoidstr[] = {
652	NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
653};
654
655/* isakmp->np */
656static const char *npstr[] = {
657	"none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
658	"sig", "nonce", "n", "d", "vid",      /* 9 - 13 */
659	"pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
660	"pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
661	"pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
662	"pay29", "pay30", "pay31", "pay32",          /* 29- 32 */
663	"v2sa",  "v2ke",  "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
664	"v2cr",  "v2auth","v2nonce", "v2n",   "v2d",   /* 38- 42 */
665	"v2vid", "v2TSi", "v2TSr", "v2e",   "v2cp",  /* 43- 47 */
666	"v2eap",                                     /* 48 */
667
668};
669
670/* isakmp->np */
671static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
672				 const struct isakmp_gen *ext,
673				 u_int item_len,
674				 const u_char *end_pointer,
675				 uint32_t phase,
676				 uint32_t doi0,
677				 uint32_t proto0, int depth) = {
678	NULL,
679	ikev1_sa_print,
680	ikev1_p_print,
681	ikev1_t_print,
682	ikev1_ke_print,
683	ikev1_id_print,
684	ikev1_cert_print,
685	ikev1_cr_print,
686	ikev1_hash_print,
687	ikev1_sig_print,
688	ikev1_nonce_print,
689	ikev1_n_print,
690	ikev1_d_print,
691	ikev1_vid_print,                  /* 13 */
692	NULL, NULL, NULL, NULL, NULL,     /* 14- 18 */
693	NULL, NULL, NULL, NULL, NULL,     /* 19- 23 */
694	NULL, NULL, NULL, NULL, NULL,     /* 24- 28 */
695	NULL, NULL, NULL, NULL,           /* 29- 32 */
696	ikev2_sa_print,                 /* 33 */
697	ikev2_ke_print,                 /* 34 */
698	ikev2_ID_print,                 /* 35 */
699	ikev2_ID_print,                 /* 36 */
700	ikev2_cert_print,               /* 37 */
701	ikev2_cr_print,                 /* 38 */
702	ikev2_auth_print,               /* 39 */
703	ikev2_nonce_print,              /* 40 */
704	ikev2_n_print,                  /* 41 */
705	ikev2_d_print,                  /* 42 */
706	ikev2_vid_print,                /* 43 */
707	ikev2_TS_print,                 /* 44 */
708	ikev2_TS_print,                 /* 45 */
709	NULL, /* ikev2_e_print,*/       /* 46 - special */
710	ikev2_cp_print,                 /* 47 */
711	ikev2_eap_print,                /* 48 */
712};
713
714/* isakmp->etype */
715static const char *etypestr[] = {
716/* IKEv1 exchange types */
717	"none", "base", "ident", "auth", "agg", "inf", NULL, NULL,  /* 0-7 */
718	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /*  8-15 */
719	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 16-23 */
720	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 24-31 */
721	"oakley-quick", "oakley-newgroup",               /* 32-33 */
722/* IKEv2 exchange types */
723	"ikev2_init", "ikev2_auth", "child_sa", "inf2"   /* 34-37 */
724};
725
726#define STR_OR_ID(x, tab) \
727	(((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)])	? tab[(x)] : numstr(x))
728#define PROTOIDSTR(x)	STR_OR_ID(x, protoidstr)
729#define NPSTR(x)	STR_OR_ID(x, npstr)
730#define ETYPESTR(x)	STR_OR_ID(x, etypestr)
731
732#define CHECKLEN(p, np)							\
733		if (ep < (const u_char *)(p)) {				\
734			ND_PRINT(" [|%s]", NPSTR(np));		\
735			goto done;					\
736		}
737
738
739#define NPFUNC(x) \
740	(((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
741		? npfunc[(x)] : NULL)
742
743static int
744iszero(netdissect_options *ndo, const u_char *p, size_t l)
745{
746	while (l != 0) {
747		if (GET_U_1(p))
748			return 0;
749		p++;
750		l--;
751	}
752	return 1;
753}
754
755/* find cookie from initiator cache */
756static int
757cookie_find(const cookie_t *in)
758{
759	int i;
760
761	for (i = 0; i < MAXINITIATORS; i++) {
762		if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
763			return i;
764	}
765
766	return -1;
767}
768
769/* record initiator */
770static void
771cookie_record(netdissect_options *ndo, const cookie_t *in, const u_char *bp2)
772{
773	int i;
774	const struct ip *ip;
775	const struct ip6_hdr *ip6;
776
777	i = cookie_find(in);
778	if (0 <= i) {
779		ninitiator = (i + 1) % MAXINITIATORS;
780		return;
781	}
782
783	ip = (const struct ip *)bp2;
784	switch (IP_V(ip)) {
785	case 4:
786		cookiecache[ninitiator].version = 4;
787		UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in4,
788				 ip->ip_src, sizeof(nd_ipv4));
789		UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in4,
790				 ip->ip_dst, sizeof(nd_ipv4));
791		break;
792	case 6:
793		ip6 = (const struct ip6_hdr *)bp2;
794		cookiecache[ninitiator].version = 6;
795		UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in6,
796				 ip6->ip6_src, sizeof(nd_ipv6));
797		UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in6,
798				 ip6->ip6_dst, sizeof(nd_ipv6));
799		break;
800	default:
801		return;
802	}
803	UNALIGNED_MEMCPY(&cookiecache[ninitiator].initiator, in, sizeof(*in));
804	ninitiator = (ninitiator + 1) % MAXINITIATORS;
805}
806
807#define cookie_isinitiator(ndo, x, y)	cookie_sidecheck(ndo, (x), (y), 1)
808#define cookie_isresponder(ndo, x, y)	cookie_sidecheck(ndo, (x), (y), 0)
809static int
810cookie_sidecheck(netdissect_options *ndo, int i, const u_char *bp2, int initiator)
811{
812	const struct ip *ip;
813	const struct ip6_hdr *ip6;
814
815	ip = (const struct ip *)bp2;
816	switch (IP_V(ip)) {
817	case 4:
818		if (cookiecache[i].version != 4)
819			return 0;
820		if (initiator) {
821			if (UNALIGNED_MEMCMP(ip->ip_src, &cookiecache[i].iaddr.in4, sizeof(nd_ipv4)) == 0)
822				return 1;
823		} else {
824			if (UNALIGNED_MEMCMP(ip->ip_src, &cookiecache[i].raddr.in4, sizeof(nd_ipv4)) == 0)
825				return 1;
826		}
827		break;
828	case 6:
829		if (cookiecache[i].version != 6)
830			return 0;
831		ip6 = (const struct ip6_hdr *)bp2;
832		if (initiator) {
833			if (UNALIGNED_MEMCMP(ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(nd_ipv6)) == 0)
834				return 1;
835		} else {
836			if (UNALIGNED_MEMCMP(ip6->ip6_src, &cookiecache[i].raddr.in6, sizeof(nd_ipv6)) == 0)
837				return 1;
838		}
839		break;
840	default:
841		break;
842	}
843
844	return 0;
845}
846
847static void
848hexprint(netdissect_options *ndo, const uint8_t *loc, size_t len)
849{
850	const uint8_t *p;
851	size_t i;
852
853	p = loc;
854	for (i = 0; i < len; i++)
855		ND_PRINT("%02x", p[i] & 0xff);
856}
857
858static int
859rawprint(netdissect_options *ndo, const uint8_t *loc, size_t len)
860{
861	ND_TCHECK_LEN(loc, len);
862
863	hexprint(ndo, loc, len);
864	return 1;
865trunc:
866	return 0;
867}
868
869
870/*
871 * returns false if we run out of data buffer
872 */
873static int ike_show_somedata(netdissect_options *ndo,
874			     const u_char *cp, const u_char *ep)
875{
876	/* there is too much data, just show some of it */
877	const u_char *end = ep - 20;
878	size_t  elen = 20;
879	size_t  len = ep - cp;
880	if(len > 10) {
881		len = 10;
882	}
883
884	/* really shouldn't happen because of above */
885	if(end < cp + len) {
886		end = cp+len;
887		elen = ep - end;
888	}
889
890	ND_PRINT(" data=(");
891	if(!rawprint(ndo, (const uint8_t *)(cp), len)) goto trunc;
892	ND_PRINT("...");
893	if(elen) {
894		if(!rawprint(ndo, (const uint8_t *)(end), elen)) goto trunc;
895	}
896	ND_PRINT(")");
897	return 1;
898
899trunc:
900	return 0;
901}
902
903struct attrmap {
904	const char *type;
905	u_int nvalue;
906	const char *value[30];	/*XXX*/
907};
908
909static const u_char *
910ikev1_attrmap_print(netdissect_options *ndo,
911		    const u_char *p, const u_char *ep2,
912		    const struct attrmap *map, size_t nmap)
913{
914	u_int totlen;
915	uint32_t t, v;
916
917	if (GET_U_1(p) & 0x80)
918		totlen = 4;
919	else {
920		totlen = 4 + GET_BE_U_2(p + 2);
921	}
922	if (ep2 < p + totlen) {
923		ND_PRINT("[|attr]");
924		return ep2 + 1;
925	}
926
927	ND_PRINT("(");
928	t = GET_BE_U_2(p) & 0x7fff;
929	if (map && t < nmap && map[t].type)
930		ND_PRINT("type=%s ", map[t].type);
931	else
932		ND_PRINT("type=#%u ", t);
933	if (GET_U_1(p) & 0x80) {
934		ND_PRINT("value=");
935		v = GET_BE_U_2(p + 2);
936		if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
937			ND_PRINT("%s", map[t].value[v]);
938		else {
939			if (!rawprint(ndo, (const uint8_t *)(p + 2), 2)) {
940				ND_PRINT(")");
941				goto trunc;
942			}
943		}
944	} else {
945		ND_PRINT("len=%u value=", totlen - 4);
946		if (!rawprint(ndo, (const uint8_t *)(p + 4), totlen - 4)) {
947			ND_PRINT(")");
948			goto trunc;
949		}
950	}
951	ND_PRINT(")");
952	return p + totlen;
953
954trunc:
955	return NULL;
956}
957
958static const u_char *
959ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep2)
960{
961	u_int totlen;
962	uint32_t t;
963
964	if (GET_U_1(p) & 0x80)
965		totlen = 4;
966	else {
967		totlen = 4 + GET_BE_U_2(p + 2);
968	}
969	if (ep2 < p + totlen) {
970		ND_PRINT("[|attr]");
971		return ep2 + 1;
972	}
973
974	ND_PRINT("(");
975	t = GET_BE_U_2(p) & 0x7fff;
976	ND_PRINT("type=#%u ", t);
977	if (GET_U_1(p) & 0x80) {
978		ND_PRINT("value=");
979		t = GET_U_1(p + 2);
980		if (!rawprint(ndo, (const uint8_t *)(p + 2), 2)) {
981			ND_PRINT(")");
982			goto trunc;
983		}
984	} else {
985		ND_PRINT("len=%u value=", totlen - 4);
986		if (!rawprint(ndo, (const uint8_t *)(p + 4), totlen - 4)) {
987			ND_PRINT(")");
988			goto trunc;
989		}
990	}
991	ND_PRINT(")");
992	return p + totlen;
993
994trunc:
995	return NULL;
996}
997
998static const u_char *
999ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
1000	       const struct isakmp_gen *ext,
1001		u_int item_len _U_,
1002		const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
1003		uint32_t proto0, int depth)
1004{
1005	const struct ikev1_pl_sa *p;
1006	uint32_t doi, sit, ident;
1007	const u_char *cp, *np;
1008	int t;
1009
1010	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_SA));
1011
1012	p = (const struct ikev1_pl_sa *)ext;
1013	ND_TCHECK_SIZE(p);
1014	doi = GET_BE_U_4(p->doi);
1015	sit = GET_BE_U_4(p->sit);
1016	if (doi != 1) {
1017		ND_PRINT(" doi=%u", doi);
1018		ND_PRINT(" situation=%u", sit);
1019		return (const u_char *)(p + 1);
1020	}
1021
1022	ND_PRINT(" doi=ipsec");
1023	ND_PRINT(" situation=");
1024	t = 0;
1025	if (sit & 0x01) {
1026		ND_PRINT("identity");
1027		t++;
1028	}
1029	if (sit & 0x02) {
1030		ND_PRINT("%ssecrecy", t ? "+" : "");
1031		t++;
1032	}
1033	if (sit & 0x04)
1034		ND_PRINT("%sintegrity", t ? "+" : "");
1035
1036	np = (const u_char *)ext + sizeof(struct ikev1_pl_sa);
1037	if (sit != 0x01) {
1038		ident = GET_BE_U_4(ext + 1);
1039		ND_PRINT(" ident=%u", ident);
1040		np += sizeof(ident);
1041	}
1042
1043	ext = (const struct isakmp_gen *)np;
1044	ND_TCHECK_SIZE(ext);
1045
1046	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
1047		depth);
1048
1049	return cp;
1050trunc:
1051	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA));
1052	return NULL;
1053}
1054
1055static const u_char *
1056ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
1057	      const struct isakmp_gen *ext, u_int item_len _U_,
1058	       const u_char *ep, uint32_t phase, uint32_t doi0,
1059	       uint32_t proto0 _U_, int depth)
1060{
1061	const struct ikev1_pl_p *p;
1062	const u_char *cp;
1063	uint8_t spi_size;
1064
1065	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_P));
1066
1067	p = (const struct ikev1_pl_p *)ext;
1068	ND_TCHECK_SIZE(p);
1069	ND_PRINT(" #%u protoid=%s transform=%u",
1070		  GET_U_1(p->p_no), PROTOIDSTR(GET_U_1(p->prot_id)),
1071		  GET_U_1(p->num_t));
1072	spi_size = GET_U_1(p->spi_size);
1073	if (spi_size) {
1074		ND_PRINT(" spi=");
1075		if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size))
1076			goto trunc;
1077	}
1078
1079	ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + spi_size);
1080	ND_TCHECK_SIZE(ext);
1081
1082	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1083			     GET_U_1(p->prot_id), depth);
1084
1085	return cp;
1086trunc:
1087	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P));
1088	return NULL;
1089}
1090
1091static const char *ikev1_p_map[] = {
1092	NULL, "ike",
1093};
1094
1095static const char *ikev2_t_type_map[]={
1096	NULL, "encr", "prf", "integ", "dh", "esn"
1097};
1098
1099static const char *ah_p_map[] = {
1100	NULL, "(reserved)", "md5", "sha", "1des",
1101	"sha2-256", "sha2-384", "sha2-512",
1102};
1103
1104static const char *prf_p_map[] = {
1105	NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
1106	"aes128_xcbc"
1107};
1108
1109static const char *integ_p_map[] = {
1110	NULL, "hmac-md5", "hmac-sha", "dec-mac",
1111	"kpdk-md5", "aes-xcbc"
1112};
1113
1114static const char *esn_p_map[] = {
1115	"no-esn", "esn"
1116};
1117
1118static const char *dh_p_map[] = {
1119	NULL, "modp768",
1120	"modp1024",    /* group 2 */
1121	"EC2N 2^155",  /* group 3 */
1122	"EC2N 2^185",  /* group 4 */
1123	"modp1536",    /* group 5 */
1124	"iana-grp06", "iana-grp07", /* reserved */
1125	"iana-grp08", "iana-grp09",
1126	"iana-grp10", "iana-grp11",
1127	"iana-grp12", "iana-grp13",
1128	"modp2048",    /* group 14 */
1129	"modp3072",    /* group 15 */
1130	"modp4096",    /* group 16 */
1131	"modp6144",    /* group 17 */
1132	"modp8192",    /* group 18 */
1133};
1134
1135static const char *esp_p_map[] = {
1136	NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
1137	"blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
1138};
1139
1140static const char *ipcomp_p_map[] = {
1141	NULL, "oui", "deflate", "lzs",
1142};
1143
1144static const struct attrmap ipsec_t_map[] = {
1145	{ NULL,	0, { NULL } },
1146	{ "lifetype", 3, { NULL, "sec", "kb", }, },
1147	{ "life", 0, { NULL } },
1148	{ "group desc", 18,	{ NULL, "modp768",
1149				  "modp1024",    /* group 2 */
1150				  "EC2N 2^155",  /* group 3 */
1151				  "EC2N 2^185",  /* group 4 */
1152				  "modp1536",    /* group 5 */
1153				  "iana-grp06", "iana-grp07", /* reserved */
1154				  "iana-grp08", "iana-grp09",
1155				  "iana-grp10", "iana-grp11",
1156				  "iana-grp12", "iana-grp13",
1157				  "modp2048",    /* group 14 */
1158				  "modp3072",    /* group 15 */
1159				  "modp4096",    /* group 16 */
1160				  "modp6144",    /* group 17 */
1161				  "modp8192",    /* group 18 */
1162		}, },
1163	{ "enc mode", 3, { NULL, "tunnel", "transport", }, },
1164	{ "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
1165	{ "keylen", 0, { NULL } },
1166	{ "rounds", 0, { NULL } },
1167	{ "dictsize", 0, { NULL } },
1168	{ "privalg", 0, { NULL } },
1169};
1170
1171static const struct attrmap encr_t_map[] = {
1172	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 0, 1 */
1173	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 2, 3 */
1174	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 4, 5 */
1175	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 6, 7 */
1176	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 8, 9 */
1177	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 10,11*/
1178	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 12,13*/
1179	{ "keylen", 14, { NULL }},
1180};
1181
1182static const struct attrmap oakley_t_map[] = {
1183	{ NULL,	0, { NULL } },
1184	{ "enc", 8,	{ NULL, "1des", "idea", "blowfish", "rc5",
1185			  "3des", "cast", "aes", }, },
1186	{ "hash", 7,	{ NULL, "md5", "sha1", "tiger",
1187			  "sha2-256", "sha2-384", "sha2-512", }, },
1188	{ "auth", 6,	{ NULL, "preshared", "dss", "rsa sig", "rsa enc",
1189			  "rsa enc revised", }, },
1190	{ "group desc", 18,	{ NULL, "modp768",
1191				  "modp1024",    /* group 2 */
1192				  "EC2N 2^155",  /* group 3 */
1193				  "EC2N 2^185",  /* group 4 */
1194				  "modp1536",    /* group 5 */
1195				  "iana-grp06", "iana-grp07", /* reserved */
1196				  "iana-grp08", "iana-grp09",
1197				  "iana-grp10", "iana-grp11",
1198				  "iana-grp12", "iana-grp13",
1199				  "modp2048",    /* group 14 */
1200				  "modp3072",    /* group 15 */
1201				  "modp4096",    /* group 16 */
1202				  "modp6144",    /* group 17 */
1203				  "modp8192",    /* group 18 */
1204		}, },
1205	{ "group type", 4,	{ NULL, "MODP", "ECP", "EC2N", }, },
1206	{ "group prime", 0, { NULL } },
1207	{ "group gen1", 0, { NULL } },
1208	{ "group gen2", 0, { NULL } },
1209	{ "group curve A", 0, { NULL } },
1210	{ "group curve B", 0, { NULL } },
1211	{ "lifetype", 3,	{ NULL, "sec", "kb", }, },
1212	{ "lifeduration", 0, { NULL } },
1213	{ "prf", 0, { NULL } },
1214	{ "keylen", 0, { NULL } },
1215	{ "field", 0, { NULL } },
1216	{ "order", 0, { NULL } },
1217};
1218
1219static const u_char *
1220ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
1221	      const struct isakmp_gen *ext, u_int item_len,
1222	      const u_char *ep, uint32_t phase _U_, uint32_t doi _U_,
1223	      uint32_t proto, int depth _U_)
1224{
1225	const struct ikev1_pl_t *p;
1226	const u_char *cp;
1227	const char *idstr;
1228	const struct attrmap *map;
1229	size_t nmap;
1230	const u_char *ep2;
1231
1232	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_T));
1233
1234	p = (const struct ikev1_pl_t *)ext;
1235	ND_TCHECK_SIZE(p);
1236
1237	switch (proto) {
1238	case 1:
1239		idstr = STR_OR_ID(GET_U_1(p->t_id), ikev1_p_map);
1240		map = oakley_t_map;
1241		nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1242		break;
1243	case 2:
1244		idstr = STR_OR_ID(GET_U_1(p->t_id), ah_p_map);
1245		map = ipsec_t_map;
1246		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1247		break;
1248	case 3:
1249		idstr = STR_OR_ID(GET_U_1(p->t_id), esp_p_map);
1250		map = ipsec_t_map;
1251		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1252		break;
1253	case 4:
1254		idstr = STR_OR_ID(GET_U_1(p->t_id), ipcomp_p_map);
1255		map = ipsec_t_map;
1256		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1257		break;
1258	default:
1259		idstr = NULL;
1260		map = NULL;
1261		nmap = 0;
1262		break;
1263	}
1264
1265	if (idstr)
1266		ND_PRINT(" #%u id=%s ", GET_U_1(p->t_no), idstr);
1267	else
1268		ND_PRINT(" #%u id=%u ", GET_U_1(p->t_no), GET_U_1(p->t_id));
1269	cp = (const u_char *)(p + 1);
1270	ep2 = (const u_char *)p + item_len;
1271	while (cp < ep && cp < ep2) {
1272		if (map && nmap)
1273			cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
1274		else
1275			cp = ikev1_attr_print(ndo, cp, ep2);
1276		if (cp == NULL)
1277			goto trunc;
1278	}
1279	if (ep < ep2)
1280		ND_PRINT("...");
1281	return cp;
1282trunc:
1283	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_T));
1284	return NULL;
1285}
1286
1287static const u_char *
1288ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
1289	       const struct isakmp_gen *ext, u_int item_len,
1290	       const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1291	       uint32_t proto _U_, int depth _U_)
1292{
1293	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_KE));
1294
1295	ND_TCHECK_SIZE(ext);
1296	/*
1297	 * Our caller has ensured that the length is >= 4.
1298	 */
1299	ND_PRINT(" key len=%u", item_len - 4);
1300	if (2 < ndo->ndo_vflag && item_len > 4) {
1301		/* Print the entire payload in hex */
1302		ND_PRINT(" ");
1303		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1304			goto trunc;
1305	}
1306	return (const u_char *)ext + item_len;
1307trunc:
1308	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE));
1309	return NULL;
1310}
1311
1312static const u_char *
1313ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
1314	       const struct isakmp_gen *ext, u_int item_len,
1315	       const u_char *ep _U_, uint32_t phase, uint32_t doi _U_,
1316	       uint32_t proto _U_, int depth _U_)
1317{
1318#define USE_IPSECDOI_IN_PHASE1	1
1319	const struct ikev1_pl_id *p;
1320	static const char *idtypestr[] = {
1321		"IPv4", "IPv4net", "IPv6", "IPv6net",
1322	};
1323	static const char *ipsecidtypestr[] = {
1324		NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
1325		"IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
1326		"keyid",
1327	};
1328	u_int len;
1329	const u_char *data;
1330
1331	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_ID));
1332
1333	p = (const struct ikev1_pl_id *)ext;
1334	ND_TCHECK_SIZE(p);
1335	if (sizeof(*p) < item_len) {
1336		data = (const u_char *)(p + 1);
1337		len = item_len - sizeof(*p);
1338	} else {
1339		data = NULL;
1340		len = 0;
1341	}
1342
1343#if 0 /*debug*/
1344	ND_PRINT(" [phase=%u doi=%u proto=%u]", phase, doi, proto);
1345#endif
1346	switch (phase) {
1347#ifndef USE_IPSECDOI_IN_PHASE1
1348	case 1:
1349#endif
1350	default:
1351		ND_PRINT(" idtype=%s",
1352			 STR_OR_ID(GET_U_1(p->d.id_type), idtypestr));
1353		ND_PRINT(" doi_data=%u",
1354			  GET_BE_U_4(p->d.doi_data) & 0xffffff);
1355		break;
1356
1357#ifdef USE_IPSECDOI_IN_PHASE1
1358	case 1:
1359#endif
1360	case 2:
1361	    {
1362		const struct ipsecdoi_id *doi_p;
1363		const char *p_name;
1364		uint8_t type, proto_id;
1365
1366		doi_p = (const struct ipsecdoi_id *)ext;
1367		ND_TCHECK_SIZE(doi_p);
1368		type = GET_U_1(doi_p->type);
1369		ND_PRINT(" idtype=%s", STR_OR_ID(type, ipsecidtypestr));
1370		/* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
1371		proto_id = GET_U_1(doi_p->proto_id);
1372		if (!ndo->ndo_nflag && proto_id && (p_name = netdb_protoname(proto_id)) != NULL)
1373			ND_PRINT(" protoid=%s", p_name);
1374		else
1375			ND_PRINT(" protoid=%u", proto_id);
1376		ND_PRINT(" port=%u", GET_BE_U_2(doi_p->port));
1377		if (!len)
1378			break;
1379		if (data == NULL)
1380			goto trunc;
1381		ND_TCHECK_LEN(data, len);
1382		switch (type) {
1383		case IPSECDOI_ID_IPV4_ADDR:
1384			if (len < 4)
1385				ND_PRINT(" len=%u [bad: < 4]", len);
1386			else
1387				ND_PRINT(" len=%u %s", len, GET_IPADDR_STRING(data));
1388			len = 0;
1389			break;
1390		case IPSECDOI_ID_FQDN:
1391		case IPSECDOI_ID_USER_FQDN:
1392		    {
1393			u_int i;
1394			ND_PRINT(" len=%u ", len);
1395			for (i = 0; i < len; i++)
1396				fn_print_char(ndo, GET_U_1(data + i));
1397			len = 0;
1398			break;
1399		    }
1400		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1401		    {
1402			const u_char *mask;
1403			if (len < 8)
1404				ND_PRINT(" len=%u [bad: < 8]", len);
1405			else {
1406				mask = data + sizeof(nd_ipv4);
1407				ND_PRINT(" len=%u %s/%u.%u.%u.%u", len,
1408					  GET_IPADDR_STRING(data),
1409					  GET_U_1(mask), GET_U_1(mask + 1),
1410					  GET_U_1(mask + 2),
1411					  GET_U_1(mask + 3));
1412			}
1413			len = 0;
1414			break;
1415		    }
1416		case IPSECDOI_ID_IPV6_ADDR:
1417			if (len < 16)
1418				ND_PRINT(" len=%u [bad: < 16]", len);
1419			else
1420				ND_PRINT(" len=%u %s", len, GET_IP6ADDR_STRING(data));
1421			len = 0;
1422			break;
1423		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1424		    {
1425			const u_char *mask;
1426			if (len < 32)
1427				ND_PRINT(" len=%u [bad: < 32]", len);
1428			else {
1429				mask = (const u_char *)(data + sizeof(nd_ipv6));
1430				/*XXX*/
1431				ND_PRINT(" len=%u %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len,
1432					  GET_IP6ADDR_STRING(data),
1433					  GET_U_1(mask), GET_U_1(mask + 1),
1434					  GET_U_1(mask + 2),
1435					  GET_U_1(mask + 3),
1436					  GET_U_1(mask + 4),
1437					  GET_U_1(mask + 5),
1438					  GET_U_1(mask + 6),
1439					  GET_U_1(mask + 7),
1440					  GET_U_1(mask + 8),
1441					  GET_U_1(mask + 9),
1442					  GET_U_1(mask + 10),
1443					  GET_U_1(mask + 11),
1444					  GET_U_1(mask + 12),
1445					  GET_U_1(mask + 13),
1446					  GET_U_1(mask + 14),
1447					  GET_U_1(mask + 15));
1448			}
1449			len = 0;
1450			break;
1451		    }
1452		case IPSECDOI_ID_IPV4_ADDR_RANGE:
1453			if (len < 8)
1454				ND_PRINT(" len=%u [bad: < 8]", len);
1455			else {
1456				ND_PRINT(" len=%u %s-%s", len,
1457					  GET_IPADDR_STRING(data),
1458					  GET_IPADDR_STRING(data + sizeof(nd_ipv4)));
1459			}
1460			len = 0;
1461			break;
1462		case IPSECDOI_ID_IPV6_ADDR_RANGE:
1463			if (len < 32)
1464				ND_PRINT(" len=%u [bad: < 32]", len);
1465			else {
1466				ND_PRINT(" len=%u %s-%s", len,
1467					  GET_IP6ADDR_STRING(data),
1468					  GET_IP6ADDR_STRING(data + sizeof(nd_ipv6)));
1469			}
1470			len = 0;
1471			break;
1472		case IPSECDOI_ID_DER_ASN1_DN:
1473		case IPSECDOI_ID_DER_ASN1_GN:
1474		case IPSECDOI_ID_KEY_ID:
1475			break;
1476		}
1477		break;
1478	    }
1479	}
1480	if (data && len) {
1481		ND_PRINT(" len=%u", len);
1482		if (2 < ndo->ndo_vflag) {
1483			ND_PRINT(" ");
1484			if (!rawprint(ndo, (const uint8_t *)data, len))
1485				goto trunc;
1486		}
1487	}
1488	return (const u_char *)ext + item_len;
1489trunc:
1490	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID));
1491	return NULL;
1492}
1493
1494static const u_char *
1495ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
1496		 const struct isakmp_gen *ext, u_int item_len,
1497		 const u_char *ep _U_, uint32_t phase _U_,
1498		 uint32_t doi0 _U_,
1499		 uint32_t proto0 _U_, int depth _U_)
1500{
1501	const struct ikev1_pl_cert *p;
1502	static const char *certstr[] = {
1503		"none",	"pkcs7", "pgp", "dns",
1504		"x509sign", "x509ke", "kerberos", "crl",
1505		"arl", "spki", "x509attr",
1506	};
1507
1508	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
1509
1510	p = (const struct ikev1_pl_cert *)ext;
1511	ND_TCHECK_SIZE(p);
1512	/*
1513	 * Our caller has ensured that the length is >= 4.
1514	 */
1515	ND_PRINT(" len=%u", item_len - 4);
1516	ND_PRINT(" type=%s", STR_OR_ID(GET_U_1(p->encode), certstr));
1517	if (2 < ndo->ndo_vflag && 4 < item_len) {
1518		/* Print the entire payload in hex */
1519		ND_PRINT(" ");
1520		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1521			goto trunc;
1522	}
1523	return (const u_char *)ext + item_len;
1524trunc:
1525	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT));
1526	return NULL;
1527}
1528
1529static const u_char *
1530ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
1531	       const struct isakmp_gen *ext, u_int item_len,
1532	       const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1533	       uint32_t proto0 _U_, int depth _U_)
1534{
1535	const struct ikev1_pl_cert *p;
1536	static const char *certstr[] = {
1537		"none",	"pkcs7", "pgp", "dns",
1538		"x509sign", "x509ke", "kerberos", "crl",
1539		"arl", "spki", "x509attr",
1540	};
1541
1542	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_CR));
1543
1544	p = (const struct ikev1_pl_cert *)ext;
1545	ND_TCHECK_SIZE(p);
1546	/*
1547	 * Our caller has ensured that the length is >= 4.
1548	 */
1549	ND_PRINT(" len=%u", item_len - 4);
1550	ND_PRINT(" type=%s", STR_OR_ID(GET_U_1(p->encode), certstr));
1551	if (2 < ndo->ndo_vflag && 4 < item_len) {
1552		/* Print the entire payload in hex */
1553		ND_PRINT(" ");
1554		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1555			goto trunc;
1556	}
1557	return (const u_char *)ext + item_len;
1558trunc:
1559	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR));
1560	return NULL;
1561}
1562
1563static const u_char *
1564ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
1565		 const struct isakmp_gen *ext, u_int item_len,
1566		 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1567		 uint32_t proto _U_, int depth _U_)
1568{
1569	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
1570
1571	ND_TCHECK_SIZE(ext);
1572	/*
1573	 * Our caller has ensured that the length is >= 4.
1574	 */
1575	ND_PRINT(" len=%u", item_len - 4);
1576	if (2 < ndo->ndo_vflag && 4 < item_len) {
1577		/* Print the entire payload in hex */
1578		ND_PRINT(" ");
1579		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1580			goto trunc;
1581	}
1582	return (const u_char *)ext + item_len;
1583trunc:
1584	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH));
1585	return NULL;
1586}
1587
1588static const u_char *
1589ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
1590		const struct isakmp_gen *ext, u_int item_len,
1591		const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1592		uint32_t proto _U_, int depth _U_)
1593{
1594	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
1595
1596	ND_TCHECK_SIZE(ext);
1597	/*
1598	 * Our caller has ensured that the length is >= 4.
1599	 */
1600	ND_PRINT(" len=%u", item_len - 4);
1601	if (2 < ndo->ndo_vflag && 4 < item_len) {
1602		/* Print the entire payload in hex */
1603		ND_PRINT(" ");
1604		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1605			goto trunc;
1606	}
1607	return (const u_char *)ext + item_len;
1608trunc:
1609	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG));
1610	return NULL;
1611}
1612
1613static const u_char *
1614ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
1615		  const struct isakmp_gen *ext,
1616		  u_int item_len,
1617		  const u_char *ep,
1618		  uint32_t phase _U_, uint32_t doi _U_,
1619		  uint32_t proto _U_, int depth _U_)
1620{
1621	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
1622
1623	ND_TCHECK_SIZE(ext);
1624	/*
1625	 * Our caller has ensured that the length is >= 4.
1626	 */
1627	ND_PRINT(" n len=%u", item_len - 4);
1628	if (item_len > 4) {
1629		if (ndo->ndo_vflag > 2) {
1630			ND_PRINT(" ");
1631			if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1632				goto trunc;
1633		} else if (ndo->ndo_vflag > 1) {
1634			ND_PRINT(" ");
1635			if (!ike_show_somedata(ndo, (const u_char *)(ext + 1), ep))
1636				goto trunc;
1637		}
1638	}
1639	return (const u_char *)ext + item_len;
1640trunc:
1641	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE));
1642	return NULL;
1643}
1644
1645static const u_char *
1646ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
1647	      const struct isakmp_gen *ext, u_int item_len,
1648	      const u_char *ep, uint32_t phase _U_, uint32_t doi0 _U_,
1649	      uint32_t proto0 _U_, int depth _U_)
1650{
1651	const struct ikev1_pl_n *p;
1652	const u_char *cp;
1653	const u_char *ep2;
1654	uint32_t doi;
1655	uint32_t proto;
1656	uint16_t type;
1657	uint8_t spi_size;
1658	static const char *notify_error_str[] = {
1659		NULL,				"INVALID-PAYLOAD-TYPE",
1660		"DOI-NOT-SUPPORTED",		"SITUATION-NOT-SUPPORTED",
1661		"INVALID-COOKIE",		"INVALID-MAJOR-VERSION",
1662		"INVALID-MINOR-VERSION",	"INVALID-EXCHANGE-TYPE",
1663		"INVALID-FLAGS",		"INVALID-MESSAGE-ID",
1664		"INVALID-PROTOCOL-ID",		"INVALID-SPI",
1665		"INVALID-TRANSFORM-ID",		"ATTRIBUTES-NOT-SUPPORTED",
1666		"NO-PROPOSAL-CHOSEN",		"BAD-PROPOSAL-SYNTAX",
1667		"PAYLOAD-MALFORMED",		"INVALID-KEY-INFORMATION",
1668		"INVALID-ID-INFORMATION",	"INVALID-CERT-ENCODING",
1669		"INVALID-CERTIFICATE",		"CERT-TYPE-UNSUPPORTED",
1670		"INVALID-CERT-AUTHORITY",	"INVALID-HASH-INFORMATION",
1671		"AUTHENTICATION-FAILED",	"INVALID-SIGNATURE",
1672		"ADDRESS-NOTIFICATION",		"NOTIFY-SA-LIFETIME",
1673		"CERTIFICATE-UNAVAILABLE",	"UNSUPPORTED-EXCHANGE-TYPE",
1674		"UNEQUAL-PAYLOAD-LENGTHS",
1675	};
1676	static const char *ipsec_notify_error_str[] = {
1677		"RESERVED",
1678	};
1679	static const char *notify_status_str[] = {
1680		"CONNECTED",
1681	};
1682	static const char *ipsec_notify_status_str[] = {
1683		"RESPONDER-LIFETIME",		"REPLAY-STATUS",
1684		"INITIAL-CONTACT",
1685	};
1686/* NOTE: these macro must be called with x in proper range */
1687
1688/* 0 - 8191 */
1689#define NOTIFY_ERROR_STR(x) \
1690	STR_OR_ID((x), notify_error_str)
1691
1692/* 8192 - 16383 */
1693#define IPSEC_NOTIFY_ERROR_STR(x) \
1694	STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1695
1696/* 16384 - 24575 */
1697#define NOTIFY_STATUS_STR(x) \
1698	STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1699
1700/* 24576 - 32767 */
1701#define IPSEC_NOTIFY_STATUS_STR(x) \
1702	STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1703
1704	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_N));
1705
1706	p = (const struct ikev1_pl_n *)ext;
1707	ND_TCHECK_SIZE(p);
1708	doi = GET_BE_U_4(p->doi);
1709	proto = GET_U_1(p->prot_id);
1710	if (doi != 1) {
1711		ND_PRINT(" doi=%u", doi);
1712		ND_PRINT(" proto=%u", proto);
1713		type = GET_BE_U_2(p->type);
1714		if (type < 8192)
1715			ND_PRINT(" type=%s", NOTIFY_ERROR_STR(type));
1716		else if (type < 16384)
1717			ND_PRINT(" type=%s", numstr(type));
1718		else if (type < 24576)
1719			ND_PRINT(" type=%s", NOTIFY_STATUS_STR(type));
1720		else
1721			ND_PRINT(" type=%s", numstr(type));
1722		spi_size = GET_U_1(p->spi_size);
1723		if (spi_size) {
1724			ND_PRINT(" spi=");
1725			if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size))
1726				goto trunc;
1727		}
1728		return (const u_char *)(p + 1) + spi_size;
1729	}
1730
1731	ND_PRINT(" doi=ipsec");
1732	ND_PRINT(" proto=%s", PROTOIDSTR(proto));
1733	type = GET_BE_U_2(p->type);
1734	if (type < 8192)
1735		ND_PRINT(" type=%s", NOTIFY_ERROR_STR(type));
1736	else if (type < 16384)
1737		ND_PRINT(" type=%s", IPSEC_NOTIFY_ERROR_STR(type));
1738	else if (type < 24576)
1739		ND_PRINT(" type=%s", NOTIFY_STATUS_STR(type));
1740	else if (type < 32768)
1741		ND_PRINT(" type=%s", IPSEC_NOTIFY_STATUS_STR(type));
1742	else
1743		ND_PRINT(" type=%s", numstr(type));
1744	spi_size = GET_U_1(p->spi_size);
1745	if (spi_size) {
1746		ND_PRINT(" spi=");
1747		if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size))
1748			goto trunc;
1749	}
1750
1751	cp = (const u_char *)(p + 1) + spi_size;
1752	ep2 = (const u_char *)p + item_len;
1753
1754	if (cp < ep) {
1755		switch (type) {
1756		case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1757		    {
1758			const struct attrmap *map = oakley_t_map;
1759			size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1760			ND_PRINT(" attrs=(");
1761			while (cp < ep && cp < ep2) {
1762				cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
1763				if (cp == NULL) {
1764					ND_PRINT(")");
1765					goto trunc;
1766				}
1767			}
1768			ND_PRINT(")");
1769			break;
1770		    }
1771		case IPSECDOI_NTYPE_REPLAY_STATUS:
1772			ND_PRINT(" status=(");
1773			ND_PRINT("replay detection %sabled",
1774				  GET_BE_U_4(cp) ? "en" : "dis");
1775			ND_PRINT(")");
1776			break;
1777		default:
1778			/*
1779			 * XXX - fill in more types here; see, for example,
1780			 * draft-ietf-ipsec-notifymsg-04.
1781			 */
1782			if (ndo->ndo_vflag > 3) {
1783				ND_PRINT(" data=(");
1784				if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
1785					goto trunc;
1786				ND_PRINT(")");
1787			} else {
1788				if (!ike_show_somedata(ndo, cp, ep))
1789					goto trunc;
1790			}
1791			break;
1792		}
1793	}
1794	return (const u_char *)ext + item_len;
1795trunc:
1796	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_N));
1797	return NULL;
1798}
1799
1800static const u_char *
1801ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
1802	      const struct isakmp_gen *ext, u_int item_len _U_,
1803	      const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1804	      uint32_t proto0 _U_, int depth _U_)
1805{
1806	const struct ikev1_pl_d *p;
1807	const uint8_t *q;
1808	uint32_t doi;
1809	uint32_t proto;
1810	uint8_t spi_size;
1811	uint16_t num_spi;
1812	u_int i;
1813
1814	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_D));
1815
1816	p = (const struct ikev1_pl_d *)ext;
1817	ND_TCHECK_SIZE(p);
1818	doi = GET_BE_U_4(p->doi);
1819	proto = GET_U_1(p->prot_id);
1820	if (doi != 1) {
1821		ND_PRINT(" doi=%u", doi);
1822		ND_PRINT(" proto=%u", proto);
1823	} else {
1824		ND_PRINT(" doi=ipsec");
1825		ND_PRINT(" proto=%s", PROTOIDSTR(proto));
1826	}
1827	spi_size = GET_U_1(p->spi_size);
1828	ND_PRINT(" spilen=%u", spi_size);
1829	num_spi = GET_BE_U_2(p->num_spi);
1830	ND_PRINT(" nspi=%u", num_spi);
1831	ND_PRINT(" spi=");
1832	q = (const uint8_t *)(p + 1);
1833	for (i = 0; i < num_spi; i++) {
1834		if (i != 0)
1835			ND_PRINT(",");
1836		if (!rawprint(ndo, (const uint8_t *)q, spi_size))
1837			goto trunc;
1838		q += spi_size;
1839	}
1840	return q;
1841trunc:
1842	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_D));
1843	return NULL;
1844}
1845
1846static const u_char *
1847ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
1848		const struct isakmp_gen *ext,
1849		u_int item_len, const u_char *ep _U_,
1850		uint32_t phase _U_, uint32_t doi _U_,
1851		uint32_t proto _U_, int depth _U_)
1852{
1853	ND_PRINT("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1854
1855	ND_TCHECK_SIZE(ext);
1856	/*
1857	 * Our caller has ensured that the length is >= 4.
1858	 */
1859	ND_PRINT(" len=%u", item_len - 4);
1860	if (2 < ndo->ndo_vflag && 4 < item_len) {
1861		/* Print the entire payload in hex */
1862		ND_PRINT(" ");
1863		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1864			goto trunc;
1865	}
1866	return (const u_char *)ext + item_len;
1867trunc:
1868	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID));
1869	return NULL;
1870}
1871
1872/************************************************************/
1873/*                                                          */
1874/*              IKE v2 - rfc4306 - dissector                */
1875/*                                                          */
1876/************************************************************/
1877
1878static void
1879ikev2_pay_print(netdissect_options *ndo, const char *payname, uint8_t critical)
1880{
1881	ND_PRINT("%s%s:", payname, critical&0x80 ? "[C]" : "");
1882}
1883
1884static const u_char *
1885ikev2_gen_print(netdissect_options *ndo, u_char tpay,
1886		const struct isakmp_gen *ext, u_int item_len)
1887{
1888	const struct isakmp_gen *p = (const struct isakmp_gen *)ext;
1889
1890	ND_TCHECK_SIZE(ext);
1891	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(p->critical));
1892
1893	/*
1894	 * Our caller has ensured that the length is >= 4.
1895	 */
1896	ND_PRINT(" len=%u", item_len - 4);
1897	if (2 < ndo->ndo_vflag && 4 < item_len) {
1898		/* Print the entire payload in hex */
1899		ND_PRINT(" ");
1900		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1901			goto trunc;
1902	}
1903	return (const u_char *)ext + item_len;
1904trunc:
1905	ND_PRINT(" [|%s]", NPSTR(tpay));
1906	return NULL;
1907}
1908
1909static const u_char *
1910ikev2_t_print(netdissect_options *ndo, int tcount,
1911	      const struct isakmp_gen *ext, u_int item_len,
1912	      const u_char *ep)
1913{
1914	const struct ikev2_t *p;
1915	uint16_t  t_id;
1916	uint8_t t_type;
1917	const u_char *cp;
1918	const char *idstr;
1919	const struct attrmap *map;
1920	size_t nmap;
1921	const u_char *ep2;
1922
1923	p = (const struct ikev2_t *)ext;
1924	ND_TCHECK_SIZE(p);
1925	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), GET_U_1(p->h.critical));
1926
1927	t_id = GET_BE_U_2(p->t_id);
1928
1929	map = NULL;
1930	nmap = 0;
1931
1932	t_type = GET_U_1(p->t_type);
1933	switch (t_type) {
1934	case IV2_T_ENCR:
1935		idstr = STR_OR_ID(t_id, esp_p_map);
1936		map = encr_t_map;
1937		nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
1938		break;
1939
1940	case IV2_T_PRF:
1941		idstr = STR_OR_ID(t_id, prf_p_map);
1942		break;
1943
1944	case IV2_T_INTEG:
1945		idstr = STR_OR_ID(t_id, integ_p_map);
1946		break;
1947
1948	case IV2_T_DH:
1949		idstr = STR_OR_ID(t_id, dh_p_map);
1950		break;
1951
1952	case IV2_T_ESN:
1953		idstr = STR_OR_ID(t_id, esn_p_map);
1954		break;
1955
1956	default:
1957		idstr = NULL;
1958		break;
1959	}
1960
1961	if (idstr)
1962		ND_PRINT(" #%u type=%s id=%s ", tcount,
1963			  STR_OR_ID(t_type, ikev2_t_type_map),
1964			  idstr);
1965	else
1966		ND_PRINT(" #%u type=%s id=%u ", tcount,
1967			  STR_OR_ID(t_type, ikev2_t_type_map),
1968			  t_id);
1969	cp = (const u_char *)(p + 1);
1970	ep2 = (const u_char *)p + item_len;
1971	while (cp < ep && cp < ep2) {
1972		if (map && nmap) {
1973			cp = ikev1_attrmap_print(ndo, cp, ep2, map, nmap);
1974		} else
1975			cp = ikev1_attr_print(ndo, cp, ep2);
1976		if (cp == NULL)
1977			goto trunc;
1978	}
1979	if (ep < ep2)
1980		ND_PRINT("...");
1981	return cp;
1982trunc:
1983	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_T));
1984	return NULL;
1985}
1986
1987static const u_char *
1988ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
1989	      const struct isakmp_gen *ext, u_int oprop_length,
1990	      const u_char *ep, int depth)
1991{
1992	const struct ikev2_p *p;
1993	u_int prop_length;
1994	uint8_t spi_size;
1995	const u_char *cp;
1996	int i;
1997	int tcount;
1998	u_char np;
1999	u_int item_len;
2000
2001	p = (const struct ikev2_p *)ext;
2002	ND_TCHECK_SIZE(p);
2003
2004	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), GET_U_1(p->h.critical));
2005
2006	/*
2007	 * ikev2_sa_print() guarantees that this is >= 4.
2008	 */
2009	prop_length = oprop_length - 4;
2010	ND_PRINT(" #%u protoid=%s transform=%u len=%u",
2011		  GET_U_1(p->p_no),  PROTOIDSTR(GET_U_1(p->prot_id)),
2012		  GET_U_1(p->num_t), oprop_length);
2013	cp = (const u_char *)(p + 1);
2014
2015	spi_size = GET_U_1(p->spi_size);
2016	if (spi_size) {
2017		if (prop_length < spi_size)
2018			goto toolong;
2019		ND_PRINT(" spi=");
2020		if (!rawprint(ndo, (const uint8_t *)cp, spi_size))
2021			goto trunc;
2022		cp += spi_size;
2023		prop_length -= spi_size;
2024	}
2025
2026	/*
2027	 * Print the transforms.
2028	 */
2029	tcount = 0;
2030	for (np = ISAKMP_NPTYPE_T; np != 0; np = GET_U_1(ext->np)) {
2031		tcount++;
2032		ext = (const struct isakmp_gen *)cp;
2033		if (prop_length < sizeof(*ext))
2034			goto toolong;
2035		ND_TCHECK_SIZE(ext);
2036
2037		/*
2038		 * Since we can't have a payload length of less than 4 bytes,
2039		 * we need to bail out here if the generic header is nonsensical
2040		 * or truncated, otherwise we could loop forever processing
2041		 * zero-length items or otherwise misdissect the packet.
2042		 */
2043		item_len = GET_BE_U_2(ext->len);
2044		if (item_len <= 4)
2045			goto trunc;
2046
2047		if (prop_length < item_len)
2048			goto toolong;
2049		ND_TCHECK_LEN(cp, item_len);
2050
2051		depth++;
2052		ND_PRINT("\n");
2053		for (i = 0; i < depth; i++)
2054			ND_PRINT("    ");
2055		ND_PRINT("(");
2056		if (np == ISAKMP_NPTYPE_T) {
2057			cp = ikev2_t_print(ndo, tcount, ext, item_len, ep);
2058			if (cp == NULL) {
2059				/* error, already reported */
2060				return NULL;
2061			}
2062		} else {
2063			ND_PRINT("%s", NPSTR(np));
2064			cp += item_len;
2065		}
2066		ND_PRINT(")");
2067		depth--;
2068		prop_length -= item_len;
2069	}
2070	return cp;
2071toolong:
2072	/*
2073	 * Skip the rest of the proposal.
2074	 */
2075	cp += prop_length;
2076	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P));
2077	return cp;
2078trunc:
2079	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_P));
2080	return NULL;
2081}
2082
2083static const u_char *
2084ikev2_sa_print(netdissect_options *ndo, u_char tpay,
2085		const struct isakmp_gen *ext1,
2086		u_int osa_length, const u_char *ep,
2087		uint32_t phase _U_, uint32_t doi _U_,
2088		uint32_t proto _U_, int depth)
2089{
2090	const struct isakmp_gen *ext;
2091	u_int sa_length;
2092	const u_char *cp;
2093	int i;
2094	int pcount;
2095	u_char np;
2096	u_int item_len;
2097
2098	ND_TCHECK_SIZE(ext1);
2099	ikev2_pay_print(ndo, "sa", GET_U_1(ext1->critical));
2100
2101	/*
2102	 * ikev2_sub0_print() guarantees that this is >= 4.
2103	 */
2104	osa_length= GET_BE_U_2(ext1->len);
2105	sa_length = osa_length - 4;
2106	ND_PRINT(" len=%u", sa_length);
2107
2108	/*
2109	 * Print the payloads.
2110	 */
2111	cp = (const u_char *)(ext1 + 1);
2112	pcount = 0;
2113	for (np = ISAKMP_NPTYPE_P; np != 0; np = GET_U_1(ext->np)) {
2114		pcount++;
2115		ext = (const struct isakmp_gen *)cp;
2116		if (sa_length < sizeof(*ext))
2117			goto toolong;
2118		ND_TCHECK_SIZE(ext);
2119
2120		/*
2121		 * Since we can't have a payload length of less than 4 bytes,
2122		 * we need to bail out here if the generic header is nonsensical
2123		 * or truncated, otherwise we could loop forever processing
2124		 * zero-length items or otherwise misdissect the packet.
2125		 */
2126		item_len = GET_BE_U_2(ext->len);
2127		if (item_len <= 4)
2128			goto trunc;
2129
2130		if (sa_length < item_len)
2131			goto toolong;
2132		ND_TCHECK_LEN(cp, item_len);
2133
2134		depth++;
2135		ND_PRINT("\n");
2136		for (i = 0; i < depth; i++)
2137			ND_PRINT("    ");
2138		ND_PRINT("(");
2139		if (np == ISAKMP_NPTYPE_P) {
2140			cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
2141					   ep, depth);
2142			if (cp == NULL) {
2143				/* error, already reported */
2144				return NULL;
2145			}
2146		} else {
2147			ND_PRINT("%s", NPSTR(np));
2148			cp += item_len;
2149		}
2150		ND_PRINT(")");
2151		depth--;
2152		sa_length -= item_len;
2153	}
2154	return cp;
2155toolong:
2156	/*
2157	 * Skip the rest of the SA.
2158	 */
2159	cp += sa_length;
2160	ND_PRINT(" [|%s]", NPSTR(tpay));
2161	return cp;
2162trunc:
2163	ND_PRINT(" [|%s]", NPSTR(tpay));
2164	return NULL;
2165}
2166
2167static const u_char *
2168ikev2_ke_print(netdissect_options *ndo, u_char tpay,
2169		const struct isakmp_gen *ext,
2170		u_int item_len, const u_char *ep _U_,
2171		uint32_t phase _U_, uint32_t doi _U_,
2172		uint32_t proto _U_, int depth _U_)
2173{
2174	const struct ikev2_ke *k;
2175
2176	k = (const struct ikev2_ke *)ext;
2177	ND_TCHECK_SIZE(k);
2178	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(k->h.critical));
2179
2180	if (item_len < 8) {
2181		ND_PRINT(" len=%u < 8", item_len);
2182		return (const u_char *)ext + item_len;
2183	}
2184	ND_PRINT(" len=%u group=%s", item_len - 8,
2185		  STR_OR_ID(GET_BE_U_2(k->ke_group), dh_p_map));
2186
2187	if (2 < ndo->ndo_vflag && 8 < item_len) {
2188		ND_PRINT(" ");
2189		if (!rawprint(ndo, (const uint8_t *)(k + 1), item_len - 8))
2190			goto trunc;
2191	}
2192	return (const u_char *)ext + item_len;
2193trunc:
2194	ND_PRINT(" [|%s]", NPSTR(tpay));
2195	return NULL;
2196}
2197
2198static const u_char *
2199ikev2_ID_print(netdissect_options *ndo, u_char tpay,
2200		const struct isakmp_gen *ext,
2201		u_int item_len, const u_char *ep _U_,
2202		uint32_t phase _U_, uint32_t doi _U_,
2203		uint32_t proto _U_, int depth _U_)
2204{
2205	const struct ikev2_id *idp;
2206	u_int idtype_len, i;
2207	unsigned int dumpascii, dumphex;
2208	const unsigned char *typedata;
2209
2210	idp = (const struct ikev2_id *)ext;
2211	ND_TCHECK_SIZE(idp);
2212	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(idp->h.critical));
2213
2214	/*
2215	 * Our caller has ensured that the length is >= 4.
2216	 */
2217	ND_PRINT(" len=%u", item_len - 4);
2218	if (2 < ndo->ndo_vflag && 4 < item_len) {
2219		/* Print the entire payload in hex */
2220		ND_PRINT(" ");
2221		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
2222			goto trunc;
2223	}
2224
2225	idtype_len =item_len - sizeof(struct ikev2_id);
2226	dumpascii = 0;
2227	dumphex   = 0;
2228	typedata  = (const unsigned char *)(ext)+sizeof(struct ikev2_id);
2229
2230	switch(GET_U_1(idp->type)) {
2231	case ID_IPV4_ADDR:
2232		ND_PRINT(" ipv4:");
2233		dumphex=1;
2234		break;
2235	case ID_FQDN:
2236		ND_PRINT(" fqdn:");
2237		dumpascii=1;
2238		break;
2239	case ID_RFC822_ADDR:
2240		ND_PRINT(" rfc822:");
2241		dumpascii=1;
2242		break;
2243	case ID_IPV6_ADDR:
2244		ND_PRINT(" ipv6:");
2245		dumphex=1;
2246		break;
2247	case ID_DER_ASN1_DN:
2248		ND_PRINT(" dn:");
2249		dumphex=1;
2250		break;
2251	case ID_DER_ASN1_GN:
2252		ND_PRINT(" gn:");
2253		dumphex=1;
2254		break;
2255	case ID_KEY_ID:
2256		ND_PRINT(" keyid:");
2257		dumphex=1;
2258		break;
2259	}
2260
2261	if(dumpascii) {
2262		ND_TCHECK_LEN(typedata, idtype_len);
2263		for(i=0; i<idtype_len; i++) {
2264			if(ND_ASCII_ISPRINT(GET_U_1(typedata + i))) {
2265				ND_PRINT("%c", GET_U_1(typedata + i));
2266			} else {
2267				ND_PRINT(".");
2268			}
2269		}
2270	}
2271	if(dumphex) {
2272		if (!rawprint(ndo, (const uint8_t *)typedata, idtype_len))
2273			goto trunc;
2274	}
2275
2276	return (const u_char *)ext + item_len;
2277trunc:
2278	ND_PRINT(" [|%s]", NPSTR(tpay));
2279	return NULL;
2280}
2281
2282static const u_char *
2283ikev2_cert_print(netdissect_options *ndo, u_char tpay,
2284		const struct isakmp_gen *ext,
2285		u_int item_len, const u_char *ep _U_,
2286		uint32_t phase _U_, uint32_t doi _U_,
2287		uint32_t proto _U_, int depth _U_)
2288{
2289	return ikev2_gen_print(ndo, tpay, ext, item_len);
2290}
2291
2292static const u_char *
2293ikev2_cr_print(netdissect_options *ndo, u_char tpay,
2294		const struct isakmp_gen *ext,
2295		u_int item_len, const u_char *ep _U_,
2296		uint32_t phase _U_, uint32_t doi _U_,
2297		uint32_t proto _U_, int depth _U_)
2298{
2299	return ikev2_gen_print(ndo, tpay, ext, item_len);
2300}
2301
2302static const u_char *
2303ikev2_auth_print(netdissect_options *ndo, u_char tpay,
2304		const struct isakmp_gen *ext,
2305		u_int item_len, const u_char *ep,
2306		uint32_t phase _U_, uint32_t doi _U_,
2307		uint32_t proto _U_, int depth _U_)
2308{
2309	const struct ikev2_auth *p;
2310	const char *v2_auth[]={ "invalid", "rsasig",
2311				"shared-secret", "dsssig" };
2312	const u_char *authdata = (const u_char *)ext + sizeof(struct ikev2_auth);
2313
2314	ND_TCHECK_LEN(ext, sizeof(struct ikev2_auth));
2315	p = (const struct ikev2_auth *)ext;
2316	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(p->h.critical));
2317
2318	/*
2319	 * Our caller has ensured that the length is >= 4.
2320	 */
2321	ND_PRINT(" len=%u method=%s", item_len-4,
2322		  STR_OR_ID(GET_U_1(p->auth_method), v2_auth));
2323	if (item_len > 4) {
2324		if (ndo->ndo_vflag > 1) {
2325			ND_PRINT(" authdata=(");
2326			if (!rawprint(ndo, (const uint8_t *)authdata, item_len - sizeof(struct ikev2_auth)))
2327				goto trunc;
2328			ND_PRINT(") ");
2329		} else if (ndo->ndo_vflag) {
2330			if (!ike_show_somedata(ndo, authdata, ep))
2331				goto trunc;
2332		}
2333	}
2334
2335	return (const u_char *)ext + item_len;
2336trunc:
2337	ND_PRINT(" [|%s]", NPSTR(tpay));
2338	return NULL;
2339}
2340
2341static const u_char *
2342ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
2343		const struct isakmp_gen *ext,
2344		u_int item_len, const u_char *ep,
2345		uint32_t phase _U_, uint32_t doi _U_,
2346		uint32_t proto _U_, int depth _U_)
2347{
2348	ND_TCHECK_SIZE(ext);
2349	ikev2_pay_print(ndo, "nonce", GET_U_1(ext->critical));
2350
2351	/*
2352	 * Our caller has ensured that the length is >= 4.
2353	 */
2354	ND_PRINT(" len=%u", item_len - 4);
2355	if (1 < ndo->ndo_vflag && 4 < item_len) {
2356		ND_PRINT(" nonce=(");
2357		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
2358			goto trunc;
2359		ND_PRINT(") ");
2360	} else if(ndo->ndo_vflag && 4 < item_len) {
2361		if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
2362	}
2363
2364	return (const u_char *)ext + item_len;
2365trunc:
2366	ND_PRINT(" [|%s]", NPSTR(tpay));
2367	return NULL;
2368}
2369
2370/* notify payloads */
2371static const u_char *
2372ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
2373		const struct isakmp_gen *ext,
2374		u_int item_len, const u_char *ep,
2375		uint32_t phase _U_, uint32_t doi _U_,
2376		uint32_t proto _U_, int depth _U_)
2377{
2378	const struct ikev2_n *p;
2379	uint16_t type;
2380	uint8_t spi_size;
2381	const u_char *cp;
2382	u_char showspi, showsomedata;
2383	const char *notify_name;
2384
2385	p = (const struct ikev2_n *)ext;
2386	ND_TCHECK_SIZE(p);
2387	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), GET_U_1(p->h.critical));
2388
2389	showspi = 1;
2390	showsomedata=0;
2391	notify_name=NULL;
2392
2393	ND_PRINT(" prot_id=%s", PROTOIDSTR(GET_U_1(p->prot_id)));
2394
2395	type = GET_BE_U_2(p->type);
2396
2397	/* notify space is annoying sparse */
2398	switch(type) {
2399	case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
2400		notify_name = "unsupported_critical_payload";
2401		showspi = 0;
2402		break;
2403
2404	case IV2_NOTIFY_INVALID_IKE_SPI:
2405		notify_name = "invalid_ike_spi";
2406		showspi = 1;
2407		break;
2408
2409	case IV2_NOTIFY_INVALID_MAJOR_VERSION:
2410		notify_name = "invalid_major_version";
2411		showspi = 0;
2412		break;
2413
2414	case IV2_NOTIFY_INVALID_SYNTAX:
2415		notify_name = "invalid_syntax";
2416		showspi = 1;
2417		break;
2418
2419	case IV2_NOTIFY_INVALID_MESSAGE_ID:
2420		notify_name = "invalid_message_id";
2421		showspi = 1;
2422		break;
2423
2424	case IV2_NOTIFY_INVALID_SPI:
2425		notify_name = "invalid_spi";
2426		showspi = 1;
2427		break;
2428
2429	case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
2430		notify_name = "no_protocol_chosen";
2431		showspi = 1;
2432		break;
2433
2434	case IV2_NOTIFY_INVALID_KE_PAYLOAD:
2435		notify_name = "invalid_ke_payload";
2436		showspi = 1;
2437		break;
2438
2439	case IV2_NOTIFY_AUTHENTICATION_FAILED:
2440		notify_name = "authentication_failed";
2441		showspi = 1;
2442		break;
2443
2444	case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
2445		notify_name = "single_pair_required";
2446		showspi = 1;
2447		break;
2448
2449	case IV2_NOTIFY_NO_ADDITIONAL_SAS:
2450		notify_name = "no_additional_sas";
2451		showspi = 0;
2452		break;
2453
2454	case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
2455		notify_name = "internal_address_failure";
2456		showspi = 0;
2457		break;
2458
2459	case IV2_NOTIFY_FAILED_CP_REQUIRED:
2460		notify_name = "failed:cp_required";
2461		showspi = 0;
2462		break;
2463
2464	case IV2_NOTIFY_INVALID_SELECTORS:
2465		notify_name = "invalid_selectors";
2466		showspi = 0;
2467		break;
2468
2469	case IV2_NOTIFY_INITIAL_CONTACT:
2470		notify_name = "initial_contact";
2471		showspi = 0;
2472		break;
2473
2474	case IV2_NOTIFY_SET_WINDOW_SIZE:
2475		notify_name = "set_window_size";
2476		showspi = 0;
2477		break;
2478
2479	case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
2480		notify_name = "additional_ts_possible";
2481		showspi = 0;
2482		break;
2483
2484	case IV2_NOTIFY_IPCOMP_SUPPORTED:
2485		notify_name = "ipcomp_supported";
2486		showspi = 0;
2487		break;
2488
2489	case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
2490		notify_name = "nat_detection_source_ip";
2491		showspi = 1;
2492		break;
2493
2494	case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
2495		notify_name = "nat_detection_destination_ip";
2496		showspi = 1;
2497		break;
2498
2499	case IV2_NOTIFY_COOKIE:
2500		notify_name = "cookie";
2501		showspi = 1;
2502		showsomedata= 1;
2503		break;
2504
2505	case IV2_NOTIFY_USE_TRANSPORT_MODE:
2506		notify_name = "use_transport_mode";
2507		showspi = 0;
2508		break;
2509
2510	case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
2511		notify_name = "http_cert_lookup_supported";
2512		showspi = 0;
2513		break;
2514
2515	case IV2_NOTIFY_REKEY_SA:
2516		notify_name = "rekey_sa";
2517		showspi = 1;
2518		break;
2519
2520	case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
2521		notify_name = "tfc_padding_not_supported";
2522		showspi = 0;
2523		break;
2524
2525	case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
2526		notify_name = "non_first_fragment_also";
2527		showspi = 0;
2528		break;
2529
2530	default:
2531		if (type < 8192) {
2532			notify_name="error";
2533		} else if(type < 16384) {
2534			notify_name="private-error";
2535		} else if(type < 40960) {
2536			notify_name="status";
2537		} else {
2538			notify_name="private-status";
2539		}
2540	}
2541
2542	if(notify_name) {
2543		ND_PRINT(" type=%u(%s)", type, notify_name);
2544	}
2545
2546
2547	spi_size = GET_U_1(p->spi_size);
2548	if (showspi && spi_size) {
2549		ND_PRINT(" spi=");
2550		if (!rawprint(ndo, (const uint8_t *)(p + 1), spi_size))
2551			goto trunc;
2552	}
2553
2554	cp = (const u_char *)(p + 1) + spi_size;
2555
2556	if (cp < ep) {
2557		if (ndo->ndo_vflag > 3 || (showsomedata && ep-cp < 30)) {
2558			ND_PRINT(" data=(");
2559			if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
2560				goto trunc;
2561
2562			ND_PRINT(")");
2563		} else if (showsomedata) {
2564			if (!ike_show_somedata(ndo, cp, ep))
2565				goto trunc;
2566		}
2567	}
2568
2569	return (const u_char *)ext + item_len;
2570trunc:
2571	ND_PRINT(" [|%s]", NPSTR(ISAKMP_NPTYPE_N));
2572	return NULL;
2573}
2574
2575static const u_char *
2576ikev2_d_print(netdissect_options *ndo, u_char tpay,
2577		const struct isakmp_gen *ext,
2578		u_int item_len, const u_char *ep _U_,
2579		uint32_t phase _U_, uint32_t doi _U_,
2580		uint32_t proto _U_, int depth _U_)
2581{
2582	return ikev2_gen_print(ndo, tpay, ext, item_len);
2583}
2584
2585static const u_char *
2586ikev2_vid_print(netdissect_options *ndo, u_char tpay,
2587		const struct isakmp_gen *ext,
2588		u_int item_len, const u_char *ep _U_,
2589		uint32_t phase _U_, uint32_t doi _U_,
2590		uint32_t proto _U_, int depth _U_)
2591{
2592	const u_char *vid;
2593	u_int i, len;
2594
2595	ND_TCHECK_SIZE(ext);
2596	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(ext->critical));
2597
2598	/*
2599	 * Our caller has ensured that the length is >= 4.
2600	 */
2601	ND_PRINT(" len=%u vid=", item_len - 4);
2602
2603	vid = (const u_char *)(ext+1);
2604	len = item_len - 4;
2605	ND_TCHECK_LEN(vid, len);
2606	for(i=0; i<len; i++) {
2607		if(ND_ASCII_ISPRINT(GET_U_1(vid + i)))
2608			ND_PRINT("%c", GET_U_1(vid + i));
2609		else ND_PRINT(".");
2610	}
2611	if (2 < ndo->ndo_vflag && 4 < len) {
2612		/* Print the entire payload in hex */
2613		ND_PRINT(" ");
2614		if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
2615			goto trunc;
2616	}
2617	return (const u_char *)ext + item_len;
2618trunc:
2619	ND_PRINT(" [|%s]", NPSTR(tpay));
2620	return NULL;
2621}
2622
2623static const u_char *
2624ikev2_TS_print(netdissect_options *ndo, u_char tpay,
2625		const struct isakmp_gen *ext,
2626		u_int item_len, const u_char *ep _U_,
2627		uint32_t phase _U_, uint32_t doi _U_,
2628		uint32_t proto _U_, int depth _U_)
2629{
2630	return ikev2_gen_print(ndo, tpay, ext, item_len);
2631}
2632
2633static const u_char *
2634ikev2_e_print(netdissect_options *ndo,
2635#ifndef HAVE_LIBCRYPTO
2636	      _U_
2637#endif
2638	      const struct isakmp *base,
2639	      u_char tpay,
2640	      const struct isakmp_gen *ext,
2641	      u_int item_len, const u_char *ep _U_,
2642#ifndef HAVE_LIBCRYPTO
2643	      _U_
2644#endif
2645	      uint32_t phase,
2646#ifndef HAVE_LIBCRYPTO
2647	      _U_
2648#endif
2649	      uint32_t doi,
2650#ifndef HAVE_LIBCRYPTO
2651	      _U_
2652#endif
2653	      uint32_t proto,
2654#ifndef HAVE_LIBCRYPTO
2655	      _U_
2656#endif
2657	      int depth)
2658{
2659	const u_char *dat;
2660	u_int dlen;
2661#ifdef HAVE_LIBCRYPTO
2662	uint8_t np;
2663#endif
2664
2665	ND_TCHECK_SIZE(ext);
2666	ikev2_pay_print(ndo, NPSTR(tpay), GET_U_1(ext->critical));
2667
2668	dlen = item_len-4;
2669
2670	ND_PRINT(" len=%u", dlen);
2671	if (2 < ndo->ndo_vflag && 4 < dlen) {
2672		ND_PRINT(" ");
2673		if (!rawprint(ndo, (const uint8_t *)(ext + 1), dlen))
2674			goto trunc;
2675	}
2676
2677	dat = (const u_char *)(ext+1);
2678	ND_TCHECK_LEN(dat, dlen);
2679
2680#ifdef HAVE_LIBCRYPTO
2681	np = GET_U_1(ext->np);
2682
2683	/* try to decrypt it! */
2684	if(esp_decrypt_buffer_by_ikev2_print(ndo,
2685					     GET_U_1(base->flags) & ISAKMP_FLAG_I,
2686					     base->i_ck, base->r_ck,
2687					     dat, dat+dlen)) {
2688
2689		ext = (const struct isakmp_gen *)ndo->ndo_packetp;
2690
2691		/* got it decrypted, print stuff inside. */
2692		ikev2_sub_print(ndo, base, np, ext,
2693				ndo->ndo_snapend, phase, doi, proto, depth+1);
2694
2695		/*
2696		 * esp_decrypt_buffer_by_ikev2_print pushed information
2697		 * on the buffer stack; we're done with the buffer, so
2698		 * pop it (which frees the buffer)
2699		 */
2700		nd_pop_packet_info(ndo);
2701	}
2702#endif
2703
2704
2705	/* always return NULL, because E must be at end, and NP refers
2706	 * to what was inside.
2707	 */
2708	return NULL;
2709trunc:
2710	ND_PRINT(" [|%s]", NPSTR(tpay));
2711	return NULL;
2712}
2713
2714static const u_char *
2715ikev2_cp_print(netdissect_options *ndo, u_char tpay,
2716		const struct isakmp_gen *ext,
2717		u_int item_len, const u_char *ep _U_,
2718		uint32_t phase _U_, uint32_t doi _U_,
2719		uint32_t proto _U_, int depth _U_)
2720{
2721	return ikev2_gen_print(ndo, tpay, ext, item_len);
2722}
2723
2724static const u_char *
2725ikev2_eap_print(netdissect_options *ndo, u_char tpay,
2726		const struct isakmp_gen *ext,
2727		u_int item_len, const u_char *ep _U_,
2728		uint32_t phase _U_, uint32_t doi _U_,
2729		uint32_t proto _U_, int depth _U_)
2730{
2731	return ikev2_gen_print(ndo, tpay, ext, item_len);
2732}
2733
2734static const u_char *
2735ike_sub0_print(netdissect_options *ndo,
2736		 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2737
2738	       uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2739{
2740	const u_char *cp;
2741	u_int item_len;
2742
2743	cp = (const u_char *)ext;
2744	ND_TCHECK_SIZE(ext);
2745
2746	/*
2747	 * Since we can't have a payload length of less than 4 bytes,
2748	 * we need to bail out here if the generic header is nonsensical
2749	 * or truncated, otherwise we could loop forever processing
2750	 * zero-length items or otherwise misdissect the packet.
2751	 */
2752	item_len = GET_BE_U_2(ext->len);
2753	if (item_len <= 4)
2754		return NULL;
2755
2756	if (NPFUNC(np)) {
2757		/*
2758		 * XXX - what if item_len is too short, or too long,
2759		 * for this payload type?
2760		 */
2761		cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
2762	} else {
2763		ND_PRINT("%s", NPSTR(np));
2764		cp += item_len;
2765	}
2766
2767	return cp;
2768trunc:
2769	nd_print_trunc(ndo);
2770	return NULL;
2771}
2772
2773static const u_char *
2774ikev1_sub_print(netdissect_options *ndo,
2775		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2776		uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2777{
2778	const u_char *cp;
2779	int i;
2780	u_int item_len;
2781
2782	cp = (const u_char *)ext;
2783
2784	while (np) {
2785		ND_TCHECK_SIZE(ext);
2786
2787		item_len = GET_BE_U_2(ext->len);
2788		ND_TCHECK_LEN(ext, item_len);
2789
2790		depth++;
2791		ND_PRINT("\n");
2792		for (i = 0; i < depth; i++)
2793			ND_PRINT("    ");
2794		ND_PRINT("(");
2795		cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
2796		ND_PRINT(")");
2797		depth--;
2798
2799		if (cp == NULL) {
2800			/* Zero-length subitem */
2801			return NULL;
2802		}
2803
2804		np = GET_U_1(ext->np);
2805		ext = (const struct isakmp_gen *)cp;
2806	}
2807	return cp;
2808trunc:
2809	ND_PRINT(" [|%s]", NPSTR(np));
2810	return NULL;
2811}
2812
2813static char *
2814numstr(u_int x)
2815{
2816	static char buf[20];
2817	snprintf(buf, sizeof(buf), "#%u", x);
2818	return buf;
2819}
2820
2821static void
2822ikev1_print(netdissect_options *ndo,
2823	    const u_char *bp,  u_int length,
2824	    const u_char *bp2, const struct isakmp *base)
2825{
2826	const struct isakmp *p;
2827	const u_char *ep;
2828	u_int flags;
2829	u_char np;
2830	int i;
2831	u_int phase;
2832
2833	p = (const struct isakmp *)bp;
2834	ep = ndo->ndo_snapend;
2835
2836	phase = (GET_BE_U_4(base->msgid) == 0) ? 1 : 2;
2837	if (phase == 1)
2838		ND_PRINT(" phase %u", phase);
2839	else
2840		ND_PRINT(" phase %u/others", phase);
2841
2842	i = cookie_find(&base->i_ck);
2843	if (i < 0) {
2844		if (iszero(ndo, base->r_ck, sizeof(base->r_ck))) {
2845			/* the first packet */
2846			ND_PRINT(" I");
2847			if (bp2)
2848				cookie_record(ndo, &base->i_ck, bp2);
2849		} else
2850			ND_PRINT(" ?");
2851	} else {
2852		if (bp2 && cookie_isinitiator(ndo, i, bp2))
2853			ND_PRINT(" I");
2854		else if (bp2 && cookie_isresponder(ndo, i, bp2))
2855			ND_PRINT(" R");
2856		else
2857			ND_PRINT(" ?");
2858	}
2859
2860	ND_PRINT(" %s", ETYPESTR(GET_U_1(base->etype)));
2861	flags = GET_U_1(base->flags);
2862	if (flags) {
2863		ND_PRINT("[%s%s]", flags & ISAKMP_FLAG_E ? "E" : "",
2864			  flags & ISAKMP_FLAG_C ? "C" : "");
2865	}
2866
2867	if (ndo->ndo_vflag) {
2868		const struct isakmp_gen *ext;
2869
2870		ND_PRINT(":");
2871
2872		np = GET_U_1(base->np);
2873
2874		/* regardless of phase... */
2875		if (flags & ISAKMP_FLAG_E) {
2876			/*
2877			 * encrypted, nothing we can do right now.
2878			 * we hope to decrypt the packet in the future...
2879			 */
2880			ND_PRINT(" [encrypted %s]", NPSTR(np));
2881			goto done;
2882		}
2883
2884		CHECKLEN(p + 1, np);
2885		ext = (const struct isakmp_gen *)(p + 1);
2886		ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
2887	}
2888
2889done:
2890	if (ndo->ndo_vflag) {
2891		if (GET_BE_U_4(base->len) != length) {
2892			ND_PRINT(" (len mismatch: isakmp %u/ip %u)",
2893				  GET_BE_U_4(base->len), length);
2894		}
2895	}
2896}
2897
2898static const u_char *
2899ikev2_sub0_print(netdissect_options *ndo, const struct isakmp *base,
2900		 u_char np,
2901		 const struct isakmp_gen *ext, const u_char *ep,
2902		 uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2903{
2904	const u_char *cp;
2905	u_int item_len;
2906
2907	cp = (const u_char *)ext;
2908	ND_TCHECK_SIZE(ext);
2909
2910	/*
2911	 * Since we can't have a payload length of less than 4 bytes,
2912	 * we need to bail out here if the generic header is nonsensical
2913	 * or truncated, otherwise we could loop forever processing
2914	 * zero-length items or otherwise misdissect the packet.
2915	 */
2916	item_len = GET_BE_U_2(ext->len);
2917	if (item_len <= 4)
2918		return NULL;
2919
2920	if (np == ISAKMP_NPTYPE_v2E) {
2921		cp = ikev2_e_print(ndo, base, np, ext, item_len,
2922				   ep, phase, doi, proto, depth);
2923	} else if (NPFUNC(np)) {
2924		/*
2925		 * XXX - what if item_len is too short, or too long,
2926		 * for this payload type?
2927		 */
2928		cp = (*npfunc[np])(ndo, np, ext, item_len,
2929				   ep, phase, doi, proto, depth);
2930	} else {
2931		ND_PRINT("%s", NPSTR(np));
2932		cp += item_len;
2933	}
2934
2935	return cp;
2936trunc:
2937	nd_print_trunc(ndo);
2938	return NULL;
2939}
2940
2941static const u_char *
2942ikev2_sub_print(netdissect_options *ndo,
2943		const struct isakmp *base,
2944		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2945		uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2946{
2947	const u_char *cp;
2948	int i;
2949
2950	cp = (const u_char *)ext;
2951	while (np) {
2952		ND_TCHECK_SIZE(ext);
2953
2954		ND_TCHECK_LEN(ext, GET_BE_U_2(ext->len));
2955
2956		depth++;
2957		ND_PRINT("\n");
2958		for (i = 0; i < depth; i++)
2959			ND_PRINT("    ");
2960		ND_PRINT("(");
2961		cp = ikev2_sub0_print(ndo, base, np,
2962				      ext, ep, phase, doi, proto, depth);
2963		ND_PRINT(")");
2964		depth--;
2965
2966		if (cp == NULL) {
2967			/* Zero-length subitem */
2968			return NULL;
2969		}
2970
2971		np = GET_U_1(ext->np);
2972		ext = (const struct isakmp_gen *)cp;
2973	}
2974	return cp;
2975trunc:
2976	ND_PRINT(" [|%s]", NPSTR(np));
2977	return NULL;
2978}
2979
2980static void
2981ikev2_print(netdissect_options *ndo,
2982	    const u_char *bp,  u_int length,
2983	    const u_char *bp2 _U_, const struct isakmp *base)
2984{
2985	const struct isakmp *p;
2986	const u_char *ep;
2987	uint8_t flags;
2988	u_char np;
2989	u_int phase;
2990
2991	p = (const struct isakmp *)bp;
2992	ep = ndo->ndo_snapend;
2993
2994	phase = (GET_BE_U_4(base->msgid) == 0) ? 1 : 2;
2995	if (phase == 1)
2996		ND_PRINT(" parent_sa");
2997	else
2998		ND_PRINT(" child_sa ");
2999
3000	ND_PRINT(" %s", ETYPESTR(GET_U_1(base->etype)));
3001	flags = GET_U_1(base->flags);
3002	if (flags) {
3003		ND_PRINT("[%s%s%s]",
3004			  flags & ISAKMP_FLAG_I ? "I" : "",
3005			  flags & ISAKMP_FLAG_V ? "V" : "",
3006			  flags & ISAKMP_FLAG_R ? "R" : "");
3007	}
3008
3009	if (ndo->ndo_vflag) {
3010		const struct isakmp_gen *ext;
3011
3012		ND_PRINT(":");
3013
3014		np = GET_U_1(base->np);
3015
3016		/* regardless of phase... */
3017		if (flags & ISAKMP_FLAG_E) {
3018			/*
3019			 * encrypted, nothing we can do right now.
3020			 * we hope to decrypt the packet in the future...
3021			 */
3022			ND_PRINT(" [encrypted %s]", NPSTR(np));
3023			goto done;
3024		}
3025
3026		CHECKLEN(p + 1, np)
3027		ext = (const struct isakmp_gen *)(p + 1);
3028		ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
3029	}
3030
3031done:
3032	if (ndo->ndo_vflag) {
3033		if (GET_BE_U_4(base->len) != length) {
3034			ND_PRINT(" (len mismatch: isakmp %u/ip %u)",
3035				  GET_BE_U_4(base->len), length);
3036		}
3037	}
3038}
3039
3040void
3041isakmp_print(netdissect_options *ndo,
3042	     const u_char *bp, u_int length,
3043	     const u_char *bp2)
3044{
3045	const struct isakmp *p;
3046	const u_char *ep;
3047	u_int major, minor;
3048
3049	ndo->ndo_protocol = "isakmp";
3050#ifdef HAVE_LIBCRYPTO
3051	/* initialize SAs */
3052	if (ndo->ndo_sa_list_head == NULL) {
3053		if (ndo->ndo_espsecret)
3054			esp_decodesecret_print(ndo);
3055	}
3056#endif
3057
3058	p = (const struct isakmp *)bp;
3059	ep = ndo->ndo_snapend;
3060
3061	if ((const struct isakmp *)ep < p + 1) {
3062		nd_print_trunc(ndo);
3063		return;
3064	}
3065
3066	ND_PRINT("isakmp");
3067	major = (GET_U_1(p->vers) & ISAKMP_VERS_MAJOR)
3068		>> ISAKMP_VERS_MAJOR_SHIFT;
3069	minor = (GET_U_1(p->vers) & ISAKMP_VERS_MINOR)
3070		>> ISAKMP_VERS_MINOR_SHIFT;
3071
3072	if (ndo->ndo_vflag) {
3073		ND_PRINT(" %u.%u", major, minor);
3074	}
3075
3076	if (ndo->ndo_vflag) {
3077		ND_PRINT(" msgid ");
3078		hexprint(ndo, p->msgid, sizeof(p->msgid));
3079	}
3080
3081	if (1 < ndo->ndo_vflag) {
3082		ND_PRINT(" cookie ");
3083		hexprint(ndo, p->i_ck, sizeof(p->i_ck));
3084		ND_PRINT("->");
3085		hexprint(ndo, p->r_ck, sizeof(p->r_ck));
3086	}
3087	ND_PRINT(":");
3088
3089	switch(major) {
3090	case IKEv1_MAJOR_VERSION:
3091		ikev1_print(ndo, bp, length, bp2, p);
3092		break;
3093
3094	case IKEv2_MAJOR_VERSION:
3095		ikev2_print(ndo, bp, length, bp2, p);
3096		break;
3097	}
3098}
3099
3100void
3101isakmp_rfc3948_print(netdissect_options *ndo,
3102		     const u_char *bp, u_int length,
3103		     const u_char *bp2, int ver, int fragmented, u_int ttl_hl)
3104{
3105	ndo->ndo_protocol = "isakmp_rfc3948";
3106	if(length == 1 && GET_U_1(bp)==0xff) {
3107		ND_PRINT("isakmp-nat-keep-alive");
3108		return;
3109	}
3110
3111	if(length < 4) {
3112		goto trunc;
3113	}
3114
3115	/*
3116	 * see if this is an IKE packet
3117	 */
3118	if (GET_BE_U_4(bp) == 0) {
3119		ND_PRINT("NONESP-encap: ");
3120		isakmp_print(ndo, bp+4, length-4, bp2);
3121		return;
3122	}
3123
3124	/* must be an ESP packet */
3125	{
3126		ND_PRINT("UDP-encap: ");
3127
3128		esp_print(ndo, bp, length, bp2, ver, fragmented, ttl_hl);
3129
3130		/*
3131		 * Either this has decrypted the payload and
3132		 * printed it, in which case there's nothing more
3133		 * to do, or it hasn't, in which case there's
3134		 * nothing more to do.
3135		 */
3136		return;
3137	}
3138
3139trunc:
3140	nd_print_trunc(ndo);
3141}
3142