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