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