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