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