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