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