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