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#define NETDISSECT_REWORKED
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36/* The functions from print-esp.c used in this file are only defined when both
37 * OpenSSL and evp.h are detected. Employ the same preprocessor device here.
38 */
39#ifndef HAVE_OPENSSL_EVP_H
40#undef HAVE_LIBCRYPTO
41#endif
42
43#include <tcpdump-stdinc.h>
44
45#include <string.h>
46
47#include "interface.h"
48#include "addrtoname.h"
49#include "extract.h"                    /* must come after interface.h */
50
51#include "ip.h"
52#ifdef INET6
53#include "ip6.h"
54#endif
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 Notification 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
648int ninitiator = 0;
649union inaddr_u {
650	struct in_addr in4;
651#ifdef INET6
652	struct in6_addr in6;
653#endif
654};
655struct {
656	cookie_t initiator;
657	u_int version;
658	union inaddr_u iaddr;
659	union inaddr_u raddr;
660} cookiecache[MAXINITIATORS];
661
662/* protocol id */
663static const char *protoidstr[] = {
664	NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
665};
666
667/* isakmp->np */
668static const char *npstr[] = {
669	"none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
670	"sig", "nonce", "n", "d", "vid",      /* 9 - 13 */
671	"pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
672	"pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
673	"pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
674	"pay29", "pay30", "pay31", "pay32",          /* 29- 32 */
675	"v2sa",  "v2ke",  "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
676	"v2cr",  "v2auth","v2nonce", "v2n",   "v2d",   /* 38- 42 */
677	"v2vid", "v2TSi", "v2TSr", "v2e",   "v2cp",  /* 43- 47 */
678	"v2eap",                                     /* 48 */
679
680};
681
682/* isakmp->np */
683static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
684				 const struct isakmp_gen *ext,
685				 u_int item_len,
686				 const u_char *end_pointer,
687				 uint32_t phase,
688				 uint32_t doi0,
689				 uint32_t proto0, int depth) = {
690	NULL,
691	ikev1_sa_print,
692	ikev1_p_print,
693	ikev1_t_print,
694	ikev1_ke_print,
695	ikev1_id_print,
696	ikev1_cert_print,
697	ikev1_cr_print,
698	ikev1_hash_print,
699	ikev1_sig_print,
700	ikev1_nonce_print,
701	ikev1_n_print,
702	ikev1_d_print,
703	ikev1_vid_print,                  /* 13 */
704	NULL, NULL, NULL, NULL, NULL,     /* 14- 18 */
705	NULL, NULL, NULL, NULL, NULL,     /* 19- 23 */
706	NULL, NULL, NULL, NULL, NULL,     /* 24- 28 */
707	NULL, NULL, NULL, NULL,           /* 29- 32 */
708	ikev2_sa_print,                 /* 33 */
709	ikev2_ke_print,                 /* 34 */
710	ikev2_ID_print,                 /* 35 */
711	ikev2_ID_print,                 /* 36 */
712	ikev2_cert_print,               /* 37 */
713	ikev2_cr_print,                 /* 38 */
714	ikev2_auth_print,               /* 39 */
715	ikev2_nonce_print,              /* 40 */
716	ikev2_n_print,                  /* 41 */
717	ikev2_d_print,                  /* 42 */
718	ikev2_vid_print,                /* 43 */
719	ikev2_TS_print,                 /* 44 */
720	ikev2_TS_print,                 /* 45 */
721	NULL, /* ikev2_e_print,*/       /* 46 - special */
722	ikev2_cp_print,                 /* 47 */
723	ikev2_eap_print,                /* 48 */
724};
725
726/* isakmp->etype */
727static const char *etypestr[] = {
728/* IKEv1 exchange types */
729	"none", "base", "ident", "auth", "agg", "inf", NULL, NULL,  /* 0-7 */
730	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /*  8-15 */
731	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 16-23 */
732	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 24-31 */
733	"oakley-quick", "oakley-newgroup",               /* 32-33 */
734/* IKEv2 exchange types */
735	"ikev2_init", "ikev2_auth", "child_sa", "inf2"   /* 34-37 */
736};
737
738#define STR_OR_ID(x, tab) \
739	(((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)])	? tab[(x)] : numstr(x))
740#define PROTOIDSTR(x)	STR_OR_ID(x, protoidstr)
741#define NPSTR(x)	STR_OR_ID(x, npstr)
742#define ETYPESTR(x)	STR_OR_ID(x, etypestr)
743
744#define CHECKLEN(p, np)							\
745		if (ep < (u_char *)(p)) {				\
746			ND_PRINT((ndo," [|%s]", NPSTR(np)));		\
747			goto done;					\
748		}
749
750
751#define NPFUNC(x) \
752	(((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
753		? npfunc[(x)] : NULL)
754
755static int
756iszero(u_char *p, size_t l)
757{
758	while (l--) {
759		if (*p++)
760			return 0;
761	}
762	return 1;
763}
764
765/* find cookie from initiator cache */
766static int
767cookie_find(cookie_t *in)
768{
769	int i;
770
771	for (i = 0; i < MAXINITIATORS; i++) {
772		if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
773			return i;
774	}
775
776	return -1;
777}
778
779/* record initiator */
780static void
781cookie_record(cookie_t *in, const u_char *bp2)
782{
783	int i;
784	struct ip *ip;
785#ifdef INET6
786	struct ip6_hdr *ip6;
787#endif
788
789	i = cookie_find(in);
790	if (0 <= i) {
791		ninitiator = (i + 1) % MAXINITIATORS;
792		return;
793	}
794
795	ip = (struct ip *)bp2;
796	switch (IP_V(ip)) {
797	case 4:
798		cookiecache[ninitiator].version = 4;
799		UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in4, &ip->ip_src, sizeof(struct in_addr));
800		UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in4, &ip->ip_dst, sizeof(struct in_addr));
801		break;
802#ifdef INET6
803	case 6:
804		ip6 = (struct ip6_hdr *)bp2;
805		cookiecache[ninitiator].version = 6;
806		UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in6, &ip6->ip6_src, sizeof(struct in6_addr));
807		UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in6, &ip6->ip6_dst, sizeof(struct in6_addr));
808		break;
809#endif
810	default:
811		return;
812	}
813	UNALIGNED_MEMCPY(&cookiecache[ninitiator].initiator, in, sizeof(*in));
814	ninitiator = (ninitiator + 1) % MAXINITIATORS;
815}
816
817#define cookie_isinitiator(x, y)	cookie_sidecheck((x), (y), 1)
818#define cookie_isresponder(x, y)	cookie_sidecheck((x), (y), 0)
819static int
820cookie_sidecheck(int i, const u_char *bp2, int initiator)
821{
822	struct ip *ip;
823#ifdef INET6
824	struct ip6_hdr *ip6;
825#endif
826
827	ip = (struct ip *)bp2;
828	switch (IP_V(ip)) {
829	case 4:
830		if (cookiecache[i].version != 4)
831			return 0;
832		if (initiator) {
833			if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].iaddr.in4, sizeof(struct in_addr)) == 0)
834				return 1;
835		} else {
836			if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].raddr.in4, sizeof(struct in_addr)) == 0)
837				return 1;
838		}
839		break;
840#ifdef INET6
841	case 6:
842		if (cookiecache[i].version != 6)
843			return 0;
844		ip6 = (struct ip6_hdr *)bp2;
845		if (initiator) {
846			if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(struct in6_addr)) == 0)
847				return 1;
848		} else {
849			if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].raddr.in6, sizeof(struct in6_addr)) == 0)
850				return 1;
851		}
852		break;
853#endif /* INET6 */
854	default:
855		break;
856	}
857
858	return 0;
859}
860
861static void
862hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
863{
864	u_char *p;
865	size_t i;
866
867	p = (u_char *)loc;
868	for (i = 0; i < len; i++)
869		ND_PRINT((ndo,"%02x", p[i] & 0xff));
870}
871
872static int
873rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
874{
875	ND_TCHECK2(*loc, len);
876
877	hexprint(ndo, loc, len);
878	return 1;
879trunc:
880	return 0;
881}
882
883
884/*
885 * returns false if we run out of data buffer
886 */
887static int ike_show_somedata(netdissect_options *ndo,
888			     const u_char *cp, const u_char *ep)
889{
890	/* there is too much data, just show some of it */
891	const u_char *end = ep - 20;
892	int  elen = 20;
893	int   len = ep - cp;
894	if(len > 10) {
895		len = 10;
896	}
897
898	/* really shouldn't happen because of above */
899	if(end < cp + len) {
900		end = cp+len;
901		elen = ep - end;
902	}
903
904	ND_PRINT((ndo," data=("));
905	if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc;
906	ND_PRINT((ndo, "..."));
907	if(elen) {
908		if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc;
909	}
910	ND_PRINT((ndo,")"));
911	return 1;
912
913trunc:
914	return 0;
915}
916
917struct attrmap {
918	const char *type;
919	u_int nvalue;
920	const char *value[30];	/*XXX*/
921};
922
923static const u_char *
924ikev1_attrmap_print(netdissect_options *ndo,
925		    const u_char *p, const u_char *ep,
926		    const struct attrmap *map, size_t nmap)
927{
928	int totlen;
929	uint32_t t, v;
930
931	if (p[0] & 0x80)
932		totlen = 4;
933	else
934		totlen = 4 + EXTRACT_16BITS(&p[2]);
935	if (ep < p + totlen) {
936		ND_PRINT((ndo,"[|attr]"));
937		return ep + 1;
938	}
939
940	ND_PRINT((ndo,"("));
941	t = EXTRACT_16BITS(&p[0]) & 0x7fff;
942	if (map && t < nmap && map[t].type)
943		ND_PRINT((ndo,"type=%s ", map[t].type));
944	else
945		ND_PRINT((ndo,"type=#%d ", t));
946	if (p[0] & 0x80) {
947		ND_PRINT((ndo,"value="));
948		v = EXTRACT_16BITS(&p[2]);
949		if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
950			ND_PRINT((ndo,"%s", map[t].value[v]));
951		else
952			rawprint(ndo, (caddr_t)&p[2], 2);
953	} else {
954		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
955		rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2]));
956	}
957	ND_PRINT((ndo,")"));
958	return p + totlen;
959}
960
961static const u_char *
962ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
963{
964	int totlen;
965	uint32_t t;
966
967	if (p[0] & 0x80)
968		totlen = 4;
969	else
970		totlen = 4 + EXTRACT_16BITS(&p[2]);
971	if (ep < p + totlen) {
972		ND_PRINT((ndo,"[|attr]"));
973		return ep + 1;
974	}
975
976	ND_PRINT((ndo,"("));
977	t = EXTRACT_16BITS(&p[0]) & 0x7fff;
978	ND_PRINT((ndo,"type=#%d ", t));
979	if (p[0] & 0x80) {
980		ND_PRINT((ndo,"value="));
981		t = p[2];
982		rawprint(ndo, (caddr_t)&p[2], 2);
983	} else {
984		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
985		rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2]));
986	}
987	ND_PRINT((ndo,")"));
988	return p + totlen;
989}
990
991static const u_char *
992ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
993	       const struct isakmp_gen *ext,
994		u_int item_len _U_,
995		const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
996		uint32_t proto0, int depth)
997{
998	const struct ikev1_pl_sa *p;
999	struct ikev1_pl_sa sa;
1000	uint32_t doi, sit, ident;
1001	const u_char *cp, *np;
1002	int t;
1003
1004	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
1005
1006	p = (struct ikev1_pl_sa *)ext;
1007	ND_TCHECK(*p);
1008	UNALIGNED_MEMCPY(&sa, ext, sizeof(sa));
1009	doi = ntohl(sa.doi);
1010	sit = ntohl(sa.sit);
1011	if (doi != 1) {
1012		ND_PRINT((ndo," doi=%d", doi));
1013		ND_PRINT((ndo," situation=%u", (uint32_t)ntohl(sa.sit)));
1014		return (u_char *)(p + 1);
1015	}
1016
1017	ND_PRINT((ndo," doi=ipsec"));
1018	ND_PRINT((ndo," situation="));
1019	t = 0;
1020	if (sit & 0x01) {
1021		ND_PRINT((ndo,"identity"));
1022		t++;
1023	}
1024	if (sit & 0x02) {
1025		ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));
1026		t++;
1027	}
1028	if (sit & 0x04)
1029		ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));
1030
1031	np = (u_char *)ext + sizeof(sa);
1032	if (sit != 0x01) {
1033		ND_TCHECK2(*(ext + 1), sizeof(ident));
1034		UNALIGNED_MEMCPY(&ident, ext + 1, sizeof(ident));
1035		ND_PRINT((ndo," ident=%u", (uint32_t)ntohl(ident)));
1036		np += sizeof(ident);
1037	}
1038
1039	ext = (struct isakmp_gen *)np;
1040	ND_TCHECK(*ext);
1041
1042	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
1043		depth);
1044
1045	return cp;
1046trunc:
1047	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));
1048	return NULL;
1049}
1050
1051static const u_char *
1052ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
1053	      const struct isakmp_gen *ext, u_int item_len _U_,
1054	       const u_char *ep, uint32_t phase, uint32_t doi0,
1055	       uint32_t proto0 _U_, int depth)
1056{
1057	const struct ikev1_pl_p *p;
1058	struct ikev1_pl_p prop;
1059	const u_char *cp;
1060
1061	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
1062
1063	p = (struct ikev1_pl_p *)ext;
1064	ND_TCHECK(*p);
1065	UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
1066	ND_PRINT((ndo," #%d protoid=%s transform=%d",
1067		  prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
1068	if (prop.spi_size) {
1069		ND_PRINT((ndo," spi="));
1070		if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
1071			goto trunc;
1072	}
1073
1074	ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
1075	ND_TCHECK(*ext);
1076
1077	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1078			     prop.prot_id, depth);
1079
1080	return cp;
1081trunc:
1082	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1083	return NULL;
1084}
1085
1086static const char *ikev1_p_map[] = {
1087	NULL, "ike",
1088};
1089
1090static const char *ikev2_t_type_map[]={
1091	NULL, "encr", "prf", "integ", "dh", "esn"
1092};
1093
1094static const char *ah_p_map[] = {
1095	NULL, "(reserved)", "md5", "sha", "1des",
1096	"sha2-256", "sha2-384", "sha2-512",
1097};
1098
1099static const char *prf_p_map[] = {
1100	NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
1101	"aes128_xcbc"
1102};
1103
1104static const char *integ_p_map[] = {
1105	NULL, "hmac-md5", "hmac-sha", "dec-mac",
1106	"kpdk-md5", "aes-xcbc"
1107};
1108
1109static const char *esn_p_map[] = {
1110	"no-esn", "esn"
1111};
1112
1113static const char *dh_p_map[] = {
1114	NULL, "modp768",
1115	"modp1024",    /* group 2 */
1116	"EC2N 2^155",  /* group 3 */
1117	"EC2N 2^185",  /* group 4 */
1118	"modp1536",    /* group 5 */
1119	"iana-grp06", "iana-grp07", /* reserved */
1120	"iana-grp08", "iana-grp09",
1121	"iana-grp10", "iana-grp11",
1122	"iana-grp12", "iana-grp13",
1123	"modp2048",    /* group 14 */
1124	"modp3072",    /* group 15 */
1125	"modp4096",    /* group 16 */
1126	"modp6144",    /* group 17 */
1127	"modp8192",    /* group 18 */
1128};
1129
1130static const char *esp_p_map[] = {
1131	NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
1132	"blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
1133};
1134
1135static const char *ipcomp_p_map[] = {
1136	NULL, "oui", "deflate", "lzs",
1137};
1138
1139static const struct attrmap ipsec_t_map[] = {
1140	{ NULL,	0, { NULL } },
1141	{ "lifetype", 3, { NULL, "sec", "kb", }, },
1142	{ "life", 0, { NULL } },
1143	{ "group desc", 18,	{ NULL, "modp768",
1144				  "modp1024",    /* group 2 */
1145				  "EC2N 2^155",  /* group 3 */
1146				  "EC2N 2^185",  /* group 4 */
1147				  "modp1536",    /* group 5 */
1148				  "iana-grp06", "iana-grp07", /* reserved */
1149				  "iana-grp08", "iana-grp09",
1150				  "iana-grp10", "iana-grp11",
1151				  "iana-grp12", "iana-grp13",
1152				  "modp2048",    /* group 14 */
1153				  "modp3072",    /* group 15 */
1154				  "modp4096",    /* group 16 */
1155				  "modp6144",    /* group 17 */
1156				  "modp8192",    /* group 18 */
1157		}, },
1158	{ "enc mode", 3, { NULL, "tunnel", "transport", }, },
1159	{ "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
1160	{ "keylen", 0, { NULL } },
1161	{ "rounds", 0, { NULL } },
1162	{ "dictsize", 0, { NULL } },
1163	{ "privalg", 0, { NULL } },
1164};
1165
1166static const struct attrmap encr_t_map[] = {
1167	{ NULL,	0, { NULL } }, 	{ NULL,	0, { NULL } },  /* 0, 1 */
1168	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 2, 3 */
1169	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 4, 5 */
1170	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 6, 7 */
1171	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 8, 9 */
1172	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 10,11*/
1173	{ NULL,	0, { NULL } },	{ NULL,	0, { NULL } },  /* 12,13*/
1174	{ "keylen", 14, { NULL }},
1175};
1176
1177static const struct attrmap oakley_t_map[] = {
1178	{ NULL,	0, { NULL } },
1179	{ "enc", 8,	{ NULL, "1des", "idea", "blowfish", "rc5",
1180		 	  "3des", "cast", "aes", }, },
1181	{ "hash", 7,	{ NULL, "md5", "sha1", "tiger",
1182			  "sha2-256", "sha2-384", "sha2-512", }, },
1183	{ "auth", 6,	{ NULL, "preshared", "dss", "rsa sig", "rsa enc",
1184			  "rsa enc revised", }, },
1185	{ "group desc", 18,	{ NULL, "modp768",
1186				  "modp1024",    /* group 2 */
1187				  "EC2N 2^155",  /* group 3 */
1188				  "EC2N 2^185",  /* group 4 */
1189				  "modp1536",    /* group 5 */
1190				  "iana-grp06", "iana-grp07", /* reserved */
1191				  "iana-grp08", "iana-grp09",
1192				  "iana-grp10", "iana-grp11",
1193				  "iana-grp12", "iana-grp13",
1194				  "modp2048",    /* group 14 */
1195				  "modp3072",    /* group 15 */
1196				  "modp4096",    /* group 16 */
1197				  "modp6144",    /* group 17 */
1198				  "modp8192",    /* group 18 */
1199		}, },
1200	{ "group type", 4,	{ NULL, "MODP", "ECP", "EC2N", }, },
1201	{ "group prime", 0, { NULL } },
1202	{ "group gen1", 0, { NULL } },
1203	{ "group gen2", 0, { NULL } },
1204	{ "group curve A", 0, { NULL } },
1205	{ "group curve B", 0, { NULL } },
1206	{ "lifetype", 3,	{ NULL, "sec", "kb", }, },
1207	{ "lifeduration", 0, { NULL } },
1208	{ "prf", 0, { NULL } },
1209	{ "keylen", 0, { NULL } },
1210	{ "field", 0, { NULL } },
1211	{ "order", 0, { NULL } },
1212};
1213
1214static const u_char *
1215ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
1216	      const struct isakmp_gen *ext, u_int item_len,
1217	      const u_char *ep, uint32_t phase _U_, uint32_t doi _U_,
1218	      uint32_t proto, int depth _U_)
1219{
1220	const struct ikev1_pl_t *p;
1221	struct ikev1_pl_t t;
1222	const u_char *cp;
1223	const char *idstr;
1224	const struct attrmap *map;
1225	size_t nmap;
1226	const u_char *ep2;
1227
1228	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
1229
1230	p = (struct ikev1_pl_t *)ext;
1231	ND_TCHECK(*p);
1232	UNALIGNED_MEMCPY(&t, ext, sizeof(t));
1233
1234	switch (proto) {
1235	case 1:
1236		idstr = STR_OR_ID(t.t_id, ikev1_p_map);
1237		map = oakley_t_map;
1238		nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1239		break;
1240	case 2:
1241		idstr = STR_OR_ID(t.t_id, ah_p_map);
1242		map = ipsec_t_map;
1243		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1244		break;
1245	case 3:
1246		idstr = STR_OR_ID(t.t_id, esp_p_map);
1247		map = ipsec_t_map;
1248		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1249		break;
1250	case 4:
1251		idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
1252		map = ipsec_t_map;
1253		nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1254		break;
1255	default:
1256		idstr = NULL;
1257		map = NULL;
1258		nmap = 0;
1259		break;
1260	}
1261
1262	if (idstr)
1263		ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr));
1264	else
1265		ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id));
1266	cp = (u_char *)(p + 1);
1267	ep2 = (u_char *)p + item_len;
1268	while (cp < ep && cp < ep2) {
1269		if (map && nmap) {
1270			cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1271				map, nmap);
1272		} else
1273			cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1274	}
1275	if (ep < ep2)
1276		ND_PRINT((ndo,"..."));
1277	return cp;
1278trunc:
1279	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1280	return NULL;
1281}
1282
1283static const u_char *
1284ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
1285	       const struct isakmp_gen *ext, u_int item_len _U_,
1286	       const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1287	       uint32_t proto _U_, int depth _U_)
1288{
1289	struct isakmp_gen e;
1290
1291	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
1292
1293	ND_TCHECK(*ext);
1294	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1295	ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
1296	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1297		ND_PRINT((ndo," "));
1298		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1299			goto trunc;
1300	}
1301	return (u_char *)ext + ntohs(e.len);
1302trunc:
1303	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE)));
1304	return NULL;
1305}
1306
1307static const u_char *
1308ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
1309	       const struct isakmp_gen *ext, u_int item_len,
1310	       const u_char *ep _U_, uint32_t phase, uint32_t doi _U_,
1311	       uint32_t proto _U_, int depth _U_)
1312{
1313#define USE_IPSECDOI_IN_PHASE1	1
1314	const struct ikev1_pl_id *p;
1315	struct ikev1_pl_id id;
1316	static const char *idtypestr[] = {
1317		"IPv4", "IPv4net", "IPv6", "IPv6net",
1318	};
1319	static const char *ipsecidtypestr[] = {
1320		NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
1321		"IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
1322		"keyid",
1323	};
1324	int len;
1325	const u_char *data;
1326
1327	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
1328
1329	p = (struct ikev1_pl_id *)ext;
1330	ND_TCHECK(*p);
1331	UNALIGNED_MEMCPY(&id, ext, sizeof(id));
1332	if (sizeof(*p) < item_len) {
1333		data = (u_char *)(p + 1);
1334		len = item_len - sizeof(*p);
1335	} else {
1336		data = NULL;
1337		len = 0;
1338	}
1339
1340#if 0 /*debug*/
1341	ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto));
1342#endif
1343	switch (phase) {
1344#ifndef USE_IPSECDOI_IN_PHASE1
1345	case 1:
1346#endif
1347	default:
1348		ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)));
1349		ND_PRINT((ndo," doi_data=%u",
1350			  (uint32_t)(ntohl(id.d.doi_data) & 0xffffff)));
1351		break;
1352
1353#ifdef USE_IPSECDOI_IN_PHASE1
1354	case 1:
1355#endif
1356	case 2:
1357	    {
1358		const struct ipsecdoi_id *p;
1359		struct ipsecdoi_id id;
1360		struct protoent *pe;
1361
1362		p = (struct ipsecdoi_id *)ext;
1363		ND_TCHECK(*p);
1364		UNALIGNED_MEMCPY(&id, ext, sizeof(id));
1365		ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
1366		/* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
1367		pe = id.proto_id ? getprotobynumber(id.proto_id) : NULL;
1368		if (pe)
1369			ND_PRINT((ndo," protoid=%s", pe->p_name));
1370		else
1371			ND_PRINT((ndo," protoid=%u", id.proto_id));
1372		ND_PRINT((ndo," port=%d", ntohs(id.port)));
1373		if (!len)
1374			break;
1375		if (data == NULL)
1376			goto trunc;
1377		ND_TCHECK2(*data, len);
1378		switch (id.type) {
1379		case IPSECDOI_ID_IPV4_ADDR:
1380			if (len < 4)
1381				ND_PRINT((ndo," len=%d [bad: < 4]", len));
1382			else
1383				ND_PRINT((ndo," len=%d %s", len, ipaddr_string(ndo, data)));
1384			len = 0;
1385			break;
1386		case IPSECDOI_ID_FQDN:
1387		case IPSECDOI_ID_USER_FQDN:
1388		    {
1389			int i;
1390			ND_PRINT((ndo," len=%d ", len));
1391			for (i = 0; i < len; i++)
1392				safeputchar(ndo, data[i]);
1393			len = 0;
1394			break;
1395		    }
1396		case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1397		    {
1398			const u_char *mask;
1399			if (len < 8)
1400				ND_PRINT((ndo," len=%d [bad: < 8]", len));
1401			else {
1402				mask = data + sizeof(struct in_addr);
1403				ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len,
1404					  ipaddr_string(ndo, data),
1405					  mask[0], mask[1], mask[2], mask[3]));
1406			}
1407			len = 0;
1408			break;
1409		    }
1410#ifdef INET6
1411		case IPSECDOI_ID_IPV6_ADDR:
1412			if (len < 16)
1413				ND_PRINT((ndo," len=%d [bad: < 16]", len));
1414			else
1415				ND_PRINT((ndo," len=%d %s", len, ip6addr_string(ndo, data)));
1416			len = 0;
1417			break;
1418		case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1419		    {
1420			const u_char *mask;
1421			if (len < 20)
1422				ND_PRINT((ndo," len=%d [bad: < 20]", len));
1423			else {
1424				mask = (u_char *)(data + sizeof(struct in6_addr));
1425				/*XXX*/
1426				ND_PRINT((ndo," len=%d %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len,
1427					  ip6addr_string(ndo, data),
1428					  mask[0], mask[1], mask[2], mask[3],
1429					  mask[4], mask[5], mask[6], mask[7],
1430					  mask[8], mask[9], mask[10], mask[11],
1431					  mask[12], mask[13], mask[14], mask[15]));
1432			}
1433			len = 0;
1434			break;
1435		    }
1436#endif /*INET6*/
1437		case IPSECDOI_ID_IPV4_ADDR_RANGE:
1438			if (len < 8)
1439				ND_PRINT((ndo," len=%d [bad: < 8]", len));
1440			else {
1441				ND_PRINT((ndo," len=%d %s-%s", len,
1442					  ipaddr_string(ndo, data),
1443					  ipaddr_string(ndo, data + sizeof(struct in_addr))));
1444			}
1445			len = 0;
1446			break;
1447#ifdef INET6
1448		case IPSECDOI_ID_IPV6_ADDR_RANGE:
1449			if (len < 32)
1450				ND_PRINT((ndo," len=%d [bad: < 32]", len));
1451			else {
1452				ND_PRINT((ndo," len=%d %s-%s", len,
1453					  ip6addr_string(ndo, data),
1454					  ip6addr_string(ndo, data + sizeof(struct in6_addr))));
1455			}
1456			len = 0;
1457			break;
1458#endif /*INET6*/
1459		case IPSECDOI_ID_DER_ASN1_DN:
1460		case IPSECDOI_ID_DER_ASN1_GN:
1461		case IPSECDOI_ID_KEY_ID:
1462			break;
1463		}
1464		break;
1465	    }
1466	}
1467	if (data && len) {
1468		ND_PRINT((ndo," len=%d", len));
1469		if (2 < ndo->ndo_vflag) {
1470			ND_PRINT((ndo," "));
1471			if (!rawprint(ndo, (caddr_t)data, len))
1472				goto trunc;
1473		}
1474	}
1475	return (u_char *)ext + item_len;
1476trunc:
1477	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID)));
1478	return NULL;
1479}
1480
1481static const u_char *
1482ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
1483		 const struct isakmp_gen *ext, u_int item_len _U_,
1484		 const u_char *ep _U_, uint32_t phase _U_,
1485		 uint32_t doi0 _U_,
1486		 uint32_t proto0 _U_, int depth _U_)
1487{
1488	const struct ikev1_pl_cert *p;
1489	struct ikev1_pl_cert cert;
1490	static const char *certstr[] = {
1491		"none",	"pkcs7", "pgp", "dns",
1492		"x509sign", "x509ke", "kerberos", "crl",
1493		"arl", "spki", "x509attr",
1494	};
1495
1496	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
1497
1498	p = (struct ikev1_pl_cert *)ext;
1499	ND_TCHECK(*p);
1500	UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1501	ND_PRINT((ndo," len=%d", item_len - 4));
1502	ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1503	if (2 < ndo->ndo_vflag && 4 < item_len) {
1504		ND_PRINT((ndo," "));
1505		if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
1506			goto trunc;
1507	}
1508	return (u_char *)ext + item_len;
1509trunc:
1510	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)));
1511	return NULL;
1512}
1513
1514static const u_char *
1515ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
1516	       const struct isakmp_gen *ext, u_int item_len _U_,
1517	       const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1518	       uint32_t proto0 _U_, int depth _U_)
1519{
1520	const struct ikev1_pl_cert *p;
1521	struct ikev1_pl_cert cert;
1522	static const char *certstr[] = {
1523		"none",	"pkcs7", "pgp", "dns",
1524		"x509sign", "x509ke", "kerberos", "crl",
1525		"arl", "spki", "x509attr",
1526	};
1527
1528	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
1529
1530	p = (struct ikev1_pl_cert *)ext;
1531	ND_TCHECK(*p);
1532	UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1533	ND_PRINT((ndo," len=%d", item_len - 4));
1534	ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1535	if (2 < ndo->ndo_vflag && 4 < item_len) {
1536		ND_PRINT((ndo," "));
1537		if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
1538			goto trunc;
1539	}
1540	return (u_char *)ext + item_len;
1541trunc:
1542	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR)));
1543	return NULL;
1544}
1545
1546static const u_char *
1547ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
1548		 const struct isakmp_gen *ext, u_int item_len _U_,
1549		 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1550		 uint32_t proto _U_, int depth _U_)
1551{
1552	struct isakmp_gen e;
1553
1554	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
1555
1556	ND_TCHECK(*ext);
1557	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1558	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1559	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1560		ND_PRINT((ndo," "));
1561		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1562			goto trunc;
1563	}
1564	return (u_char *)ext + ntohs(e.len);
1565trunc:
1566	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)));
1567	return NULL;
1568}
1569
1570static const u_char *
1571ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
1572		const struct isakmp_gen *ext, u_int item_len _U_,
1573		const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1574		uint32_t proto _U_, int depth _U_)
1575{
1576	struct isakmp_gen e;
1577
1578	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
1579
1580	ND_TCHECK(*ext);
1581	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1582	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1583	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1584		ND_PRINT((ndo," "));
1585		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1586			goto trunc;
1587	}
1588	return (u_char *)ext + ntohs(e.len);
1589trunc:
1590	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)));
1591	return NULL;
1592}
1593
1594static const u_char *
1595ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
1596		  const struct isakmp_gen *ext,
1597		  u_int item_len _U_,
1598		  const u_char *ep _U_,
1599		  uint32_t phase _U_, uint32_t doi _U_,
1600		  uint32_t proto _U_, int depth _U_)
1601{
1602	struct isakmp_gen e;
1603
1604	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
1605
1606	ND_TCHECK(*ext);
1607	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1608	ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
1609	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1610		ND_PRINT((ndo," "));
1611		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1612			goto trunc;
1613	} else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1614		ND_PRINT((ndo," "));
1615		if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep))
1616			goto trunc;
1617	}
1618	return (u_char *)ext + ntohs(e.len);
1619trunc:
1620	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)));
1621	return NULL;
1622}
1623
1624static const u_char *
1625ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
1626	      const struct isakmp_gen *ext, u_int item_len,
1627	      const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
1628	      uint32_t proto0 _U_, int depth)
1629{
1630	struct ikev1_pl_n *p, n;
1631	const u_char *cp;
1632	u_char *ep2;
1633	uint32_t doi;
1634	uint32_t proto;
1635	static const char *notify_error_str[] = {
1636		NULL,				"INVALID-PAYLOAD-TYPE",
1637		"DOI-NOT-SUPPORTED",		"SITUATION-NOT-SUPPORTED",
1638		"INVALID-COOKIE",		"INVALID-MAJOR-VERSION",
1639		"INVALID-MINOR-VERSION",	"INVALID-EXCHANGE-TYPE",
1640		"INVALID-FLAGS",		"INVALID-MESSAGE-ID",
1641		"INVALID-PROTOCOL-ID",		"INVALID-SPI",
1642		"INVALID-TRANSFORM-ID",		"ATTRIBUTES-NOT-SUPPORTED",
1643		"NO-PROPOSAL-CHOSEN",		"BAD-PROPOSAL-SYNTAX",
1644		"PAYLOAD-MALFORMED",		"INVALID-KEY-INFORMATION",
1645		"INVALID-ID-INFORMATION",	"INVALID-CERT-ENCODING",
1646		"INVALID-CERTIFICATE",		"CERT-TYPE-UNSUPPORTED",
1647		"INVALID-CERT-AUTHORITY",	"INVALID-HASH-INFORMATION",
1648		"AUTHENTICATION-FAILED",	"INVALID-SIGNATURE",
1649		"ADDRESS-NOTIFICATION",		"NOTIFY-SA-LIFETIME",
1650		"CERTIFICATE-UNAVAILABLE",	"UNSUPPORTED-EXCHANGE-TYPE",
1651		"UNEQUAL-PAYLOAD-LENGTHS",
1652	};
1653	static const char *ipsec_notify_error_str[] = {
1654		"RESERVED",
1655	};
1656	static const char *notify_status_str[] = {
1657		"CONNECTED",
1658	};
1659	static const char *ipsec_notify_status_str[] = {
1660		"RESPONDER-LIFETIME",		"REPLAY-STATUS",
1661		"INITIAL-CONTACT",
1662	};
1663/* NOTE: these macro must be called with x in proper range */
1664
1665/* 0 - 8191 */
1666#define NOTIFY_ERROR_STR(x) \
1667	STR_OR_ID((x), notify_error_str)
1668
1669/* 8192 - 16383 */
1670#define IPSEC_NOTIFY_ERROR_STR(x) \
1671	STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1672
1673/* 16384 - 24575 */
1674#define NOTIFY_STATUS_STR(x) \
1675	STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1676
1677/* 24576 - 32767 */
1678#define IPSEC_NOTIFY_STATUS_STR(x) \
1679	STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1680
1681	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
1682
1683	p = (struct ikev1_pl_n *)ext;
1684	ND_TCHECK(*p);
1685	UNALIGNED_MEMCPY(&n, ext, sizeof(n));
1686	doi = ntohl(n.doi);
1687	proto = n.prot_id;
1688	if (doi != 1) {
1689		ND_PRINT((ndo," doi=%d", doi));
1690		ND_PRINT((ndo," proto=%d", proto));
1691		if (ntohs(n.type) < 8192)
1692			ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1693		else if (ntohs(n.type) < 16384)
1694			ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1695		else if (ntohs(n.type) < 24576)
1696			ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1697		else
1698			ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1699		if (n.spi_size) {
1700			ND_PRINT((ndo," spi="));
1701			if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1702				goto trunc;
1703		}
1704		return (u_char *)(p + 1) + n.spi_size;
1705	}
1706
1707	ND_PRINT((ndo," doi=ipsec"));
1708	ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1709	if (ntohs(n.type) < 8192)
1710		ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1711	else if (ntohs(n.type) < 16384)
1712		ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type))));
1713	else if (ntohs(n.type) < 24576)
1714		ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1715	else if (ntohs(n.type) < 32768)
1716		ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type))));
1717	else
1718		ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1719	if (n.spi_size) {
1720		ND_PRINT((ndo," spi="));
1721		if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1722			goto trunc;
1723	}
1724
1725	cp = (u_char *)(p + 1) + n.spi_size;
1726	ep2 = (u_char *)p + item_len;
1727
1728	if (cp < ep) {
1729		ND_PRINT((ndo," orig=("));
1730		switch (ntohs(n.type)) {
1731		case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1732		    {
1733			const struct attrmap *map = oakley_t_map;
1734			size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1735			while (cp < ep && cp < ep2) {
1736				cp = ikev1_attrmap_print(ndo, cp,
1737					(ep < ep2) ? ep : ep2, map, nmap);
1738			}
1739			break;
1740		    }
1741		case IPSECDOI_NTYPE_REPLAY_STATUS:
1742			ND_PRINT((ndo,"replay detection %sabled",
1743				  EXTRACT_32BITS(cp) ? "en" : "dis"));
1744			break;
1745		case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1746			if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
1747					    (struct isakmp_gen *)cp, ep, phase, doi, proto,
1748					    depth) == NULL)
1749				return NULL;
1750			break;
1751		default:
1752			/* NULL is dummy */
1753			isakmp_print(ndo, cp,
1754				     item_len - sizeof(*p) - n.spi_size,
1755				     NULL);
1756		}
1757		ND_PRINT((ndo,")"));
1758	}
1759	return (u_char *)ext + item_len;
1760trunc:
1761	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
1762	return NULL;
1763}
1764
1765static const u_char *
1766ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
1767	      const struct isakmp_gen *ext, u_int item_len _U_,
1768	      const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1769	      uint32_t proto0 _U_, int depth _U_)
1770{
1771	const struct ikev1_pl_d *p;
1772	struct ikev1_pl_d d;
1773	const uint8_t *q;
1774	uint32_t doi;
1775	uint32_t proto;
1776	int i;
1777
1778	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
1779
1780	p = (struct ikev1_pl_d *)ext;
1781	ND_TCHECK(*p);
1782	UNALIGNED_MEMCPY(&d, ext, sizeof(d));
1783	doi = ntohl(d.doi);
1784	proto = d.prot_id;
1785	if (doi != 1) {
1786		ND_PRINT((ndo," doi=%u", doi));
1787		ND_PRINT((ndo," proto=%u", proto));
1788	} else {
1789		ND_PRINT((ndo," doi=ipsec"));
1790		ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1791	}
1792	ND_PRINT((ndo," spilen=%u", d.spi_size));
1793	ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi)));
1794	ND_PRINT((ndo," spi="));
1795	q = (uint8_t *)(p + 1);
1796	for (i = 0; i < ntohs(d.num_spi); i++) {
1797		if (i != 0)
1798			ND_PRINT((ndo,","));
1799		if (!rawprint(ndo, (caddr_t)q, d.spi_size))
1800			goto trunc;
1801		q += d.spi_size;
1802	}
1803	return q;
1804trunc:
1805	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D)));
1806	return NULL;
1807}
1808
1809static const u_char *
1810ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
1811		const struct isakmp_gen *ext,
1812		u_int item_len _U_, const u_char *ep _U_,
1813		uint32_t phase _U_, uint32_t doi _U_,
1814		uint32_t proto _U_, int depth _U_)
1815{
1816	struct isakmp_gen e;
1817
1818	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
1819
1820	ND_TCHECK(*ext);
1821	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1822	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1823	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1824		ND_PRINT((ndo," "));
1825		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1826			goto trunc;
1827	}
1828	return (u_char *)ext + ntohs(e.len);
1829trunc:
1830	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID)));
1831	return NULL;
1832}
1833
1834/************************************************************/
1835/*                                                          */
1836/*              IKE v2 - rfc4306 - dissector                */
1837/*                                                          */
1838/************************************************************/
1839
1840static void
1841ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical)
1842{
1843	ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : ""));
1844}
1845
1846static const u_char *
1847ikev2_gen_print(netdissect_options *ndo, u_char tpay,
1848		const struct isakmp_gen *ext)
1849{
1850	struct isakmp_gen e;
1851
1852	ND_TCHECK(*ext);
1853	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1854	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
1855
1856	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1857	if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1858		ND_PRINT((ndo," "));
1859		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1860			goto trunc;
1861	}
1862	return (u_char *)ext + ntohs(e.len);
1863trunc:
1864	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1865	return NULL;
1866}
1867
1868static const u_char *
1869ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
1870	      const struct isakmp_gen *ext, u_int item_len,
1871	      const u_char *ep, uint32_t phase _U_, uint32_t doi _U_,
1872	      uint32_t proto _U_, int depth _U_)
1873{
1874	const struct ikev2_t *p;
1875	struct ikev2_t t;
1876	uint16_t  t_id;
1877	const u_char *cp;
1878	const char *idstr;
1879	const struct attrmap *map;
1880	size_t nmap;
1881	const u_char *ep2;
1882
1883	p = (struct ikev2_t *)ext;
1884	ND_TCHECK(*p);
1885	UNALIGNED_MEMCPY(&t, ext, sizeof(t));
1886	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
1887
1888	t_id = ntohs(t.t_id);
1889
1890	map = NULL;
1891	nmap = 0;
1892
1893	switch (t.t_type) {
1894	case IV2_T_ENCR:
1895		idstr = STR_OR_ID(t_id, esp_p_map);
1896		map = encr_t_map;
1897		nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
1898		break;
1899
1900	case IV2_T_PRF:
1901		idstr = STR_OR_ID(t_id, prf_p_map);
1902		break;
1903
1904	case IV2_T_INTEG:
1905		idstr = STR_OR_ID(t_id, integ_p_map);
1906		break;
1907
1908	case IV2_T_DH:
1909		idstr = STR_OR_ID(t_id, dh_p_map);
1910		break;
1911
1912	case IV2_T_ESN:
1913		idstr = STR_OR_ID(t_id, esn_p_map);
1914		break;
1915
1916	default:
1917		idstr = NULL;
1918		break;
1919	}
1920
1921	if (idstr)
1922		ND_PRINT((ndo," #%u type=%s id=%s ", pcount,
1923			  STR_OR_ID(t.t_type, ikev2_t_type_map),
1924			  idstr));
1925	else
1926		ND_PRINT((ndo," #%u type=%s id=%u ", pcount,
1927			  STR_OR_ID(t.t_type, ikev2_t_type_map),
1928			  t.t_id));
1929	cp = (u_char *)(p + 1);
1930	ep2 = (u_char *)p + item_len;
1931	while (cp < ep && cp < ep2) {
1932		if (map && nmap) {
1933			cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1934				map, nmap);
1935		} else
1936			cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1937	}
1938	if (ep < ep2)
1939		ND_PRINT((ndo,"..."));
1940	return cp;
1941trunc:
1942	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1943	return NULL;
1944}
1945
1946static const u_char *
1947ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
1948	      const struct isakmp_gen *ext, u_int item_len _U_,
1949	       const u_char *ep, uint32_t phase, uint32_t doi0,
1950	       uint32_t proto0 _U_, int depth)
1951{
1952	const struct ikev2_p *p;
1953	struct ikev2_p prop;
1954	const u_char *cp;
1955
1956	p = (struct ikev2_p *)ext;
1957	ND_TCHECK(*p);
1958	UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
1959	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
1960
1961	ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
1962		  prop.p_no,  PROTOIDSTR(prop.prot_id),
1963		  prop.num_t, ntohs(prop.h.len)));
1964	if (prop.spi_size) {
1965		ND_PRINT((ndo," spi="));
1966		if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
1967			goto trunc;
1968	}
1969
1970	ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
1971	ND_TCHECK(*ext);
1972
1973	cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1974			     prop.prot_id, depth);
1975
1976	return cp;
1977trunc:
1978	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1979	return NULL;
1980}
1981
1982static const u_char *
1983ikev2_sa_print(netdissect_options *ndo, u_char tpay,
1984		const struct isakmp_gen *ext1,
1985		u_int item_len _U_, const u_char *ep _U_,
1986		uint32_t phase _U_, uint32_t doi _U_,
1987		uint32_t proto _U_, int depth _U_)
1988{
1989	struct isakmp_gen e;
1990	int    osa_length, sa_length;
1991
1992	ND_TCHECK(*ext1);
1993	UNALIGNED_MEMCPY(&e, ext1, sizeof(e));
1994	ikev2_pay_print(ndo, "sa", e.critical);
1995
1996	osa_length= ntohs(e.len);
1997	sa_length = osa_length - 4;
1998	ND_PRINT((ndo," len=%d", sa_length));
1999
2000	ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
2001			ext1+1, ep,
2002			0, 0, 0, depth);
2003
2004	return (u_char *)ext1 + osa_length;
2005trunc:
2006	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2007	return NULL;
2008}
2009
2010static const u_char *
2011ikev2_ke_print(netdissect_options *ndo, u_char tpay,
2012		const struct isakmp_gen *ext,
2013		u_int item_len _U_, const u_char *ep _U_,
2014		uint32_t phase _U_, uint32_t doi _U_,
2015		uint32_t proto _U_, int depth _U_)
2016{
2017	struct ikev2_ke ke;
2018	struct ikev2_ke *k;
2019
2020	k = (struct ikev2_ke *)ext;
2021	ND_TCHECK(*ext);
2022	UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
2023	ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
2024
2025	ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
2026		  STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
2027
2028	if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
2029		ND_PRINT((ndo," "));
2030		if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8))
2031			goto trunc;
2032	}
2033	return (u_char *)ext + ntohs(ke.h.len);
2034trunc:
2035	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2036	return NULL;
2037}
2038
2039static const u_char *
2040ikev2_ID_print(netdissect_options *ndo, u_char tpay,
2041		const struct isakmp_gen *ext,
2042		u_int item_len _U_, const u_char *ep _U_,
2043		uint32_t phase _U_, uint32_t doi _U_,
2044		uint32_t proto _U_, int depth _U_)
2045{
2046	struct ikev2_id id;
2047	int id_len, idtype_len, i;
2048	unsigned int dumpascii, dumphex;
2049	unsigned char *typedata;
2050
2051	ND_TCHECK(*ext);
2052	UNALIGNED_MEMCPY(&id, ext, sizeof(id));
2053	ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
2054
2055	id_len = ntohs(id.h.len);
2056
2057	ND_PRINT((ndo," len=%d", id_len - 4));
2058	if (2 < ndo->ndo_vflag && 4 < id_len) {
2059		ND_PRINT((ndo," "));
2060		if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
2061			goto trunc;
2062	}
2063
2064	idtype_len =id_len - sizeof(struct ikev2_id);
2065	dumpascii = 0;
2066	dumphex   = 0;
2067	typedata  = (unsigned char *)(ext)+sizeof(struct ikev2_id);
2068
2069	switch(id.type) {
2070	case ID_IPV4_ADDR:
2071		ND_PRINT((ndo, " ipv4:"));
2072		dumphex=1;
2073		break;
2074	case ID_FQDN:
2075		ND_PRINT((ndo, " fqdn:"));
2076		dumpascii=1;
2077		break;
2078	case ID_RFC822_ADDR:
2079		ND_PRINT((ndo, " rfc822:"));
2080		dumpascii=1;
2081		break;
2082	case ID_IPV6_ADDR:
2083		ND_PRINT((ndo, " ipv6:"));
2084		dumphex=1;
2085		break;
2086	case ID_DER_ASN1_DN:
2087		ND_PRINT((ndo, " dn:"));
2088		dumphex=1;
2089		break;
2090	case ID_DER_ASN1_GN:
2091		ND_PRINT((ndo, " gn:"));
2092		dumphex=1;
2093		break;
2094	case ID_KEY_ID:
2095		ND_PRINT((ndo, " keyid:"));
2096		dumphex=1;
2097		break;
2098	}
2099
2100	if(dumpascii) {
2101		ND_TCHECK2(*typedata, idtype_len);
2102		for(i=0; i<idtype_len; i++) {
2103			if(ND_ISPRINT(typedata[i])) {
2104				ND_PRINT((ndo, "%c", typedata[i]));
2105			} else {
2106				ND_PRINT((ndo, "."));
2107			}
2108		}
2109	}
2110	if(dumphex) {
2111		if (!rawprint(ndo, (caddr_t)typedata, idtype_len))
2112			goto trunc;
2113	}
2114
2115	return (u_char *)ext + id_len;
2116trunc:
2117	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2118	return NULL;
2119}
2120
2121static const u_char *
2122ikev2_cert_print(netdissect_options *ndo, u_char tpay,
2123		const struct isakmp_gen *ext,
2124		u_int item_len _U_, const u_char *ep _U_,
2125		uint32_t phase _U_, uint32_t doi _U_,
2126		uint32_t proto _U_, int depth _U_)
2127{
2128	return ikev2_gen_print(ndo, tpay, ext);
2129}
2130
2131static const u_char *
2132ikev2_cr_print(netdissect_options *ndo, u_char tpay,
2133		const struct isakmp_gen *ext,
2134		u_int item_len _U_, const u_char *ep _U_,
2135		uint32_t phase _U_, uint32_t doi _U_,
2136		uint32_t proto _U_, int depth _U_)
2137{
2138	return ikev2_gen_print(ndo, tpay, ext);
2139}
2140
2141static const u_char *
2142ikev2_auth_print(netdissect_options *ndo, u_char tpay,
2143		const struct isakmp_gen *ext,
2144		u_int item_len _U_, const u_char *ep _U_,
2145		uint32_t phase _U_, uint32_t doi _U_,
2146		uint32_t proto _U_, int depth _U_)
2147{
2148	struct ikev2_auth a;
2149	const char *v2_auth[]={ "invalid", "rsasig",
2150				"shared-secret", "dsssig" };
2151	u_char *authdata = (u_char*)ext + sizeof(a);
2152	unsigned int len;
2153
2154	ND_TCHECK(*ext);
2155	UNALIGNED_MEMCPY(&a, ext, sizeof(a));
2156	ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
2157	len = ntohs(a.h.len);
2158
2159	ND_PRINT((ndo," len=%d method=%s", len-4,
2160		  STR_OR_ID(a.auth_method, v2_auth)));
2161
2162	if (1 < ndo->ndo_vflag && 4 < len) {
2163		ND_PRINT((ndo," authdata=("));
2164		if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a)))
2165			goto trunc;
2166		ND_PRINT((ndo,") "));
2167	} else if(ndo->ndo_vflag && 4 < len) {
2168		if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
2169	}
2170
2171	return (u_char *)ext + len;
2172trunc:
2173	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2174	return NULL;
2175}
2176
2177static const u_char *
2178ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
2179		const struct isakmp_gen *ext,
2180		u_int item_len _U_, const u_char *ep _U_,
2181		uint32_t phase _U_, uint32_t doi _U_,
2182		uint32_t proto _U_, int depth _U_)
2183{
2184	struct isakmp_gen e;
2185
2186	ND_TCHECK(*ext);
2187	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2188	ikev2_pay_print(ndo, "nonce", e.critical);
2189
2190	ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
2191	if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
2192		ND_PRINT((ndo," nonce=("));
2193		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
2194			goto trunc;
2195		ND_PRINT((ndo,") "));
2196	} else if(ndo->ndo_vflag && 4 < ntohs(e.len)) {
2197		if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
2198	}
2199
2200	return (u_char *)ext + ntohs(e.len);
2201trunc:
2202	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2203	return NULL;
2204}
2205
2206/* notify payloads */
2207static const u_char *
2208ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
2209		const struct isakmp_gen *ext,
2210		u_int item_len _U_, const u_char *ep _U_,
2211		uint32_t phase _U_, uint32_t doi _U_,
2212		uint32_t proto _U_, int depth _U_)
2213{
2214	struct ikev2_n *p, n;
2215	const u_char *cp;
2216	u_char showspi, showdata, showsomedata;
2217	const char *notify_name;
2218	uint32_t type;
2219
2220	p = (struct ikev2_n *)ext;
2221	ND_TCHECK(*p);
2222	UNALIGNED_MEMCPY(&n, ext, sizeof(n));
2223	ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
2224
2225	showspi = 1;
2226	showdata = 0;
2227	showsomedata=0;
2228	notify_name=NULL;
2229
2230	ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id)));
2231
2232	type = ntohs(n.type);
2233
2234	/* notify space is annoying sparse */
2235	switch(type) {
2236	case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
2237		notify_name = "unsupported_critical_payload";
2238		showspi = 0;
2239		break;
2240
2241	case IV2_NOTIFY_INVALID_IKE_SPI:
2242		notify_name = "invalid_ike_spi";
2243		showspi = 1;
2244		break;
2245
2246	case IV2_NOTIFY_INVALID_MAJOR_VERSION:
2247		notify_name = "invalid_major_version";
2248		showspi = 0;
2249		break;
2250
2251	case IV2_NOTIFY_INVALID_SYNTAX:
2252		notify_name = "invalid_syntax";
2253		showspi = 1;
2254		break;
2255
2256	case IV2_NOTIFY_INVALID_MESSAGE_ID:
2257		notify_name = "invalid_message_id";
2258		showspi = 1;
2259		break;
2260
2261	case IV2_NOTIFY_INVALID_SPI:
2262		notify_name = "invalid_spi";
2263		showspi = 1;
2264		break;
2265
2266	case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
2267		notify_name = "no_protocol_chosen";
2268		showspi = 1;
2269		break;
2270
2271	case IV2_NOTIFY_INVALID_KE_PAYLOAD:
2272		notify_name = "invalid_ke_payload";
2273		showspi = 1;
2274		break;
2275
2276	case IV2_NOTIFY_AUTHENTICATION_FAILED:
2277		notify_name = "authentication_failed";
2278		showspi = 1;
2279		break;
2280
2281	case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
2282		notify_name = "single_pair_required";
2283		showspi = 1;
2284		break;
2285
2286	case IV2_NOTIFY_NO_ADDITIONAL_SAS:
2287		notify_name = "no_additional_sas";
2288		showspi = 0;
2289		break;
2290
2291	case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
2292		notify_name = "internal_address_failure";
2293		showspi = 0;
2294		break;
2295
2296	case IV2_NOTIFY_FAILED_CP_REQUIRED:
2297		notify_name = "failed:cp_required";
2298		showspi = 0;
2299		break;
2300
2301	case IV2_NOTIFY_INVALID_SELECTORS:
2302		notify_name = "invalid_selectors";
2303		showspi = 0;
2304		break;
2305
2306	case IV2_NOTIFY_INITIAL_CONTACT:
2307		notify_name = "initial_contact";
2308		showspi = 0;
2309		break;
2310
2311	case IV2_NOTIFY_SET_WINDOW_SIZE:
2312		notify_name = "set_window_size";
2313		showspi = 0;
2314		break;
2315
2316	case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
2317		notify_name = "additional_ts_possible";
2318		showspi = 0;
2319		break;
2320
2321	case IV2_NOTIFY_IPCOMP_SUPPORTED:
2322		notify_name = "ipcomp_supported";
2323		showspi = 0;
2324		break;
2325
2326	case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
2327		notify_name = "nat_detection_source_ip";
2328		showspi = 1;
2329		break;
2330
2331	case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
2332		notify_name = "nat_detection_destination_ip";
2333		showspi = 1;
2334		break;
2335
2336	case IV2_NOTIFY_COOKIE:
2337		notify_name = "cookie";
2338		showspi = 1;
2339		showsomedata= 1;
2340		showdata= 0;
2341		break;
2342
2343	case IV2_NOTIFY_USE_TRANSPORT_MODE:
2344		notify_name = "use_transport_mode";
2345		showspi = 0;
2346		break;
2347
2348	case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
2349		notify_name = "http_cert_lookup_supported";
2350		showspi = 0;
2351		break;
2352
2353	case IV2_NOTIFY_REKEY_SA:
2354		notify_name = "rekey_sa";
2355		showspi = 1;
2356		break;
2357
2358	case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
2359		notify_name = "tfc_padding_not_supported";
2360		showspi = 0;
2361		break;
2362
2363	case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
2364		notify_name = "non_first_fragment_also";
2365		showspi = 0;
2366		break;
2367
2368	default:
2369		if (type < 8192) {
2370			notify_name="error";
2371		} else if(type < 16384) {
2372			notify_name="private-error";
2373		} else if(type < 40960) {
2374			notify_name="status";
2375		} else {
2376			notify_name="private-status";
2377		}
2378	}
2379
2380	if(notify_name) {
2381		ND_PRINT((ndo," type=%u(%s)", type, notify_name));
2382	}
2383
2384
2385	if (showspi && n.spi_size) {
2386		ND_PRINT((ndo," spi="));
2387		if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
2388			goto trunc;
2389	}
2390
2391	cp = (u_char *)(p + 1) + n.spi_size;
2392
2393	if(3 < ndo->ndo_vflag) {
2394		showdata = 1;
2395	}
2396
2397	if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
2398		ND_PRINT((ndo," data=("));
2399		if (!rawprint(ndo, (caddr_t)(cp), ep - cp))
2400			goto trunc;
2401
2402		ND_PRINT((ndo,")"));
2403
2404	} else if(showsomedata && cp < ep) {
2405		if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
2406	}
2407
2408	return (u_char *)ext + item_len;
2409trunc:
2410	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
2411	return NULL;
2412}
2413
2414static const u_char *
2415ikev2_d_print(netdissect_options *ndo, u_char tpay,
2416		const struct isakmp_gen *ext,
2417		u_int item_len _U_, const u_char *ep _U_,
2418		uint32_t phase _U_, uint32_t doi _U_,
2419		uint32_t proto _U_, int depth _U_)
2420{
2421	return ikev2_gen_print(ndo, tpay, ext);
2422}
2423
2424static const u_char *
2425ikev2_vid_print(netdissect_options *ndo, u_char tpay,
2426		const struct isakmp_gen *ext,
2427		u_int item_len _U_, const u_char *ep _U_,
2428		uint32_t phase _U_, uint32_t doi _U_,
2429		uint32_t proto _U_, int depth _U_)
2430{
2431	struct isakmp_gen e;
2432	const u_char *vid;
2433	int i, len;
2434
2435	ND_TCHECK(*ext);
2436	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2437	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2438	ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
2439
2440	vid = (const u_char *)(ext+1);
2441	len = ntohs(e.len) - 4;
2442	ND_TCHECK2(*vid, len);
2443	for(i=0; i<len; i++) {
2444		if(ND_ISPRINT(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
2445		else ND_PRINT((ndo, "."));
2446	}
2447	if (2 < ndo->ndo_vflag && 4 < len) {
2448		ND_PRINT((ndo," "));
2449		if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
2450			goto trunc;
2451	}
2452	return (u_char *)ext + ntohs(e.len);
2453trunc:
2454	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2455	return NULL;
2456}
2457
2458static const u_char *
2459ikev2_TS_print(netdissect_options *ndo, u_char tpay,
2460		const struct isakmp_gen *ext,
2461		u_int item_len _U_, const u_char *ep _U_,
2462		uint32_t phase _U_, uint32_t doi _U_,
2463		uint32_t proto _U_, int depth _U_)
2464{
2465	return ikev2_gen_print(ndo, tpay, ext);
2466}
2467
2468static const u_char *
2469ikev2_e_print(netdissect_options *ndo,
2470#ifndef HAVE_LIBCRYPTO
2471	      _U_
2472#endif
2473	      struct isakmp *base,
2474	      u_char tpay,
2475	      const struct isakmp_gen *ext,
2476	      u_int item_len _U_, const u_char *ep _U_,
2477#ifndef HAVE_LIBCRYPTO
2478	      _U_
2479#endif
2480	      uint32_t phase,
2481#ifndef HAVE_LIBCRYPTO
2482	      _U_
2483#endif
2484	      uint32_t doi,
2485#ifndef HAVE_LIBCRYPTO
2486	      _U_
2487#endif
2488	      uint32_t proto,
2489#ifndef HAVE_LIBCRYPTO
2490	      _U_
2491#endif
2492	      int depth)
2493{
2494	struct isakmp_gen e;
2495	u_char *dat;
2496	volatile int dlen;
2497
2498	ND_TCHECK(*ext);
2499	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2500	ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2501
2502	dlen = ntohs(e.len)-4;
2503
2504	ND_PRINT((ndo," len=%d", dlen));
2505	if (2 < ndo->ndo_vflag && 4 < dlen) {
2506		ND_PRINT((ndo," "));
2507		if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
2508			goto trunc;
2509	}
2510
2511	dat = (u_char *)(ext+1);
2512	ND_TCHECK2(*dat, dlen);
2513
2514#ifdef HAVE_LIBCRYPTO
2515	/* try to decypt it! */
2516	if(esp_print_decrypt_buffer_by_ikev2(ndo,
2517					     base->flags & ISAKMP_FLAG_I,
2518					     base->i_ck, base->r_ck,
2519					     dat, dat+dlen)) {
2520
2521		ext = (const struct isakmp_gen *)ndo->ndo_packetp;
2522
2523		/* got it decrypted, print stuff inside. */
2524		ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
2525				phase, doi, proto, depth+1);
2526	}
2527#endif
2528
2529
2530	/* always return NULL, because E must be at end, and NP refers
2531	 * to what was inside.
2532	 */
2533	return NULL;
2534trunc:
2535	ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2536	return NULL;
2537}
2538
2539static const u_char *
2540ikev2_cp_print(netdissect_options *ndo, u_char tpay,
2541		const struct isakmp_gen *ext,
2542		u_int item_len _U_, const u_char *ep _U_,
2543		uint32_t phase _U_, uint32_t doi _U_,
2544		uint32_t proto _U_, int depth _U_)
2545{
2546	return ikev2_gen_print(ndo, tpay, ext);
2547}
2548
2549static const u_char *
2550ikev2_eap_print(netdissect_options *ndo, u_char tpay,
2551		const struct isakmp_gen *ext,
2552		u_int item_len _U_, const u_char *ep _U_,
2553		uint32_t phase _U_, uint32_t doi _U_,
2554		uint32_t proto _U_, int depth _U_)
2555{
2556	return ikev2_gen_print(ndo, tpay, ext);
2557}
2558
2559static const u_char *
2560ike_sub0_print(netdissect_options *ndo,
2561		 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2562
2563	       uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2564{
2565	const u_char *cp;
2566	struct isakmp_gen e;
2567	u_int item_len;
2568
2569	cp = (u_char *)ext;
2570	ND_TCHECK(*ext);
2571	UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2572
2573	/*
2574	 * Since we can't have a payload length of less than 4 bytes,
2575	 * we need to bail out here if the generic header is nonsensical
2576	 * or truncated, otherwise we could loop forever processing
2577	 * zero-length items or otherwise misdissect the packet.
2578	 */
2579	item_len = ntohs(e.len);
2580	if (item_len <= 4)
2581		return NULL;
2582
2583	if (NPFUNC(np)) {
2584		/*
2585		 * XXX - what if item_len is too short, or too long,
2586		 * for this payload type?
2587		 */
2588		cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
2589	} else {
2590		ND_PRINT((ndo,"%s", NPSTR(np)));
2591		cp += item_len;
2592	}
2593
2594	return cp;
2595trunc:
2596	ND_PRINT((ndo," [|isakmp]"));
2597	return NULL;
2598}
2599
2600static const u_char *
2601ikev1_sub_print(netdissect_options *ndo,
2602		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2603		uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2604{
2605	const u_char *cp;
2606	int i;
2607	struct isakmp_gen e;
2608
2609	cp = (const u_char *)ext;
2610
2611	while (np) {
2612		ND_TCHECK(*ext);
2613
2614		UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2615
2616		ND_TCHECK2(*ext, ntohs(e.len));
2617
2618		depth++;
2619		ND_PRINT((ndo,"\n"));
2620		for (i = 0; i < depth; i++)
2621			ND_PRINT((ndo,"    "));
2622		ND_PRINT((ndo,"("));
2623		cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
2624		ND_PRINT((ndo,")"));
2625		depth--;
2626
2627		if (cp == NULL) {
2628			/* Zero-length subitem */
2629			return NULL;
2630		}
2631
2632		np = e.np;
2633		ext = (struct isakmp_gen *)cp;
2634	}
2635	return cp;
2636trunc:
2637	ND_PRINT((ndo," [|%s]", NPSTR(np)));
2638	return NULL;
2639}
2640
2641static char *
2642numstr(int x)
2643{
2644	static char buf[20];
2645	snprintf(buf, sizeof(buf), "#%d", x);
2646	return buf;
2647}
2648
2649static void
2650ikev1_print(netdissect_options *ndo,
2651	    const u_char *bp,  u_int length,
2652	    const u_char *bp2, struct isakmp *base)
2653{
2654	const struct isakmp *p;
2655	const u_char *ep;
2656	u_char np;
2657	int i;
2658	int phase;
2659
2660	p = (const struct isakmp *)bp;
2661	ep = ndo->ndo_snapend;
2662
2663	phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2664	if (phase == 1)
2665		ND_PRINT((ndo," phase %d", phase));
2666	else
2667		ND_PRINT((ndo," phase %d/others", phase));
2668
2669	i = cookie_find(&base->i_ck);
2670	if (i < 0) {
2671		if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) {
2672			/* the first packet */
2673			ND_PRINT((ndo," I"));
2674			if (bp2)
2675				cookie_record(&base->i_ck, bp2);
2676		} else
2677			ND_PRINT((ndo," ?"));
2678	} else {
2679		if (bp2 && cookie_isinitiator(i, bp2))
2680			ND_PRINT((ndo," I"));
2681		else if (bp2 && cookie_isresponder(i, bp2))
2682			ND_PRINT((ndo," R"));
2683		else
2684			ND_PRINT((ndo," ?"));
2685	}
2686
2687	ND_PRINT((ndo," %s", ETYPESTR(base->etype)));
2688	if (base->flags) {
2689		ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
2690			  base->flags & ISAKMP_FLAG_C ? "C" : ""));
2691	}
2692
2693	if (ndo->ndo_vflag) {
2694		const struct isakmp_gen *ext;
2695
2696		ND_PRINT((ndo,":"));
2697
2698		/* regardless of phase... */
2699		if (base->flags & ISAKMP_FLAG_E) {
2700			/*
2701			 * encrypted, nothing we can do right now.
2702			 * we hope to decrypt the packet in the future...
2703			 */
2704			ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np)));
2705			goto done;
2706		}
2707
2708		CHECKLEN(p + 1, base->np);
2709		np = base->np;
2710		ext = (struct isakmp_gen *)(p + 1);
2711		ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
2712	}
2713
2714done:
2715	if (ndo->ndo_vflag) {
2716		if (ntohl(base->len) != length) {
2717			ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
2718				  (uint32_t)ntohl(base->len), length));
2719		}
2720	}
2721}
2722
2723static const u_char *
2724ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
2725		 u_char np, int pcount,
2726		 const struct isakmp_gen *ext, const u_char *ep,
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 = (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(np == ISAKMP_NPTYPE_P) {
2748		cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
2749				   ep, phase, doi, proto, depth);
2750	} else if(np == ISAKMP_NPTYPE_T) {
2751		cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
2752				   ep, phase, doi, proto, depth);
2753	} else if(np == ISAKMP_NPTYPE_v2E) {
2754		cp = ikev2_e_print(ndo, base, np, ext, item_len,
2755				   ep, phase, doi, proto, depth);
2756	} else if (NPFUNC(np)) {
2757		/*
2758		 * XXX - what if item_len is too short, or too long,
2759		 * for this payload type?
2760		 */
2761		cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len,
2762				   ep, phase, doi, proto, depth);
2763	} else {
2764		ND_PRINT((ndo,"%s", NPSTR(np)));
2765		cp += item_len;
2766	}
2767
2768	return cp;
2769trunc:
2770	ND_PRINT((ndo," [|isakmp]"));
2771	return NULL;
2772}
2773
2774static const u_char *
2775ikev2_sub_print(netdissect_options *ndo,
2776		struct isakmp *base,
2777		u_char np, const struct isakmp_gen *ext, const u_char *ep,
2778		uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2779{
2780	const u_char *cp;
2781	int i;
2782	int pcount;
2783	struct isakmp_gen e;
2784
2785	cp = (const u_char *)ext;
2786	pcount = 0;
2787	while (np) {
2788		pcount++;
2789		ND_TCHECK(*ext);
2790
2791		UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2792
2793		ND_TCHECK2(*ext, ntohs(e.len));
2794
2795		depth++;
2796		ND_PRINT((ndo,"\n"));
2797		for (i = 0; i < depth; i++)
2798			ND_PRINT((ndo,"    "));
2799		ND_PRINT((ndo,"("));
2800		cp = ikev2_sub0_print(ndo, base, np, pcount,
2801				      ext, ep, phase, doi, proto, depth);
2802		ND_PRINT((ndo,")"));
2803		depth--;
2804
2805		if (cp == NULL) {
2806			/* Zero-length subitem */
2807			return NULL;
2808		}
2809
2810		np = e.np;
2811		ext = (struct isakmp_gen *)cp;
2812	}
2813	return cp;
2814trunc:
2815	ND_PRINT((ndo," [|%s]", NPSTR(np)));
2816	return NULL;
2817}
2818
2819static void
2820ikev2_print(netdissect_options *ndo,
2821	    const u_char *bp,  u_int length,
2822	    const u_char *bp2 _U_, struct isakmp *base)
2823{
2824	const struct isakmp *p;
2825	const u_char *ep;
2826	u_char np;
2827	int phase;
2828
2829	p = (const struct isakmp *)bp;
2830	ep = ndo->ndo_snapend;
2831
2832	phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2833	if (phase == 1)
2834		ND_PRINT((ndo, " parent_sa"));
2835	else
2836		ND_PRINT((ndo, " child_sa "));
2837
2838	ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
2839	if (base->flags) {
2840		ND_PRINT((ndo, "[%s%s%s]",
2841			  base->flags & ISAKMP_FLAG_I ? "I" : "",
2842			  base->flags & ISAKMP_FLAG_V ? "V" : "",
2843			  base->flags & ISAKMP_FLAG_R ? "R" : ""));
2844	}
2845
2846	if (ndo->ndo_vflag) {
2847		const struct isakmp_gen *ext;
2848
2849		ND_PRINT((ndo, ":"));
2850
2851		/* regardless of phase... */
2852		if (base->flags & ISAKMP_FLAG_E) {
2853			/*
2854			 * encrypted, nothing we can do right now.
2855			 * we hope to decrypt the packet in the future...
2856			 */
2857			ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np)));
2858			goto done;
2859		}
2860
2861		CHECKLEN(p + 1, base->np)
2862
2863		np = base->np;
2864		ext = (struct isakmp_gen *)(p + 1);
2865		ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
2866	}
2867
2868done:
2869	if (ndo->ndo_vflag) {
2870		if (ntohl(base->len) != length) {
2871			ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)",
2872				  (uint32_t)ntohl(base->len), length));
2873		}
2874	}
2875}
2876
2877void
2878isakmp_print(netdissect_options *ndo,
2879	     const u_char *bp, u_int length,
2880	     const u_char *bp2)
2881{
2882	const struct isakmp *p;
2883	struct isakmp base;
2884	const u_char *ep;
2885	int major, minor;
2886
2887#ifdef HAVE_LIBCRYPTO
2888	/* initialize SAs */
2889	if (ndo->ndo_sa_list_head == NULL) {
2890		if (ndo->ndo_espsecret)
2891			esp_print_decodesecret(ndo);
2892	}
2893#endif
2894
2895	p = (const struct isakmp *)bp;
2896	ep = ndo->ndo_snapend;
2897
2898	if ((struct isakmp *)ep < p + 1) {
2899		ND_PRINT((ndo,"[|isakmp]"));
2900		return;
2901	}
2902
2903	UNALIGNED_MEMCPY(&base, p, sizeof(base));
2904
2905	ND_PRINT((ndo,"isakmp"));
2906	major = (base.vers & ISAKMP_VERS_MAJOR)
2907		>> ISAKMP_VERS_MAJOR_SHIFT;
2908	minor = (base.vers & ISAKMP_VERS_MINOR)
2909		>> ISAKMP_VERS_MINOR_SHIFT;
2910
2911	if (ndo->ndo_vflag) {
2912		ND_PRINT((ndo," %d.%d", major, minor));
2913	}
2914
2915	if (ndo->ndo_vflag) {
2916		ND_PRINT((ndo," msgid "));
2917		hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
2918	}
2919
2920	if (1 < ndo->ndo_vflag) {
2921		ND_PRINT((ndo," cookie "));
2922		hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
2923		ND_PRINT((ndo,"->"));
2924		hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
2925	}
2926	ND_PRINT((ndo,":"));
2927
2928	switch(major) {
2929	case IKEv1_MAJOR_VERSION:
2930		ikev1_print(ndo, bp, length, bp2, &base);
2931		break;
2932
2933	case IKEv2_MAJOR_VERSION:
2934		ikev2_print(ndo, bp, length, bp2, &base);
2935		break;
2936	}
2937}
2938
2939void
2940isakmp_rfc3948_print(netdissect_options *ndo,
2941		     const u_char *bp, u_int length,
2942		     const u_char *bp2)
2943{
2944
2945	if(length == 1 && bp[0]==0xff) {
2946		ND_PRINT((ndo, "isakmp-nat-keep-alive"));
2947		return;
2948	}
2949
2950	if(length < 4) {
2951		goto trunc;
2952	}
2953
2954	/*
2955	 * see if this is an IKE packet
2956	 */
2957	if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
2958		ND_PRINT((ndo, "NONESP-encap: "));
2959		isakmp_print(ndo, bp+4, length-4, bp2);
2960		return;
2961	}
2962
2963	/* must be an ESP packet */
2964	{
2965		int nh, enh, padlen;
2966		int advance;
2967
2968		ND_PRINT((ndo, "UDP-encap: "));
2969
2970		advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
2971		if(advance <= 0)
2972			return;
2973
2974		bp += advance;
2975		length -= advance + padlen;
2976		nh = enh & 0xff;
2977
2978		ip_print_inner(ndo, bp, length, nh, bp2);
2979		return;
2980	}
2981
2982trunc:
2983	ND_PRINT((ndo,"[|isakmp]"));
2984	return;
2985}
2986
2987/*
2988 * Local Variables:
2989 * c-style: whitesmith
2990 * c-basic-offset: 8
2991 * End:
2992 */
2993
2994
2995
2996
2997