]> The Tcpdump Group git mirrors - tcpdump/blob - print-isakmp.c
Fix used but marked unused parameters
[tcpdump] / print-isakmp.c
1 /*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 */
30
31 /* \summary: Internet Security Association and Key Management Protocol (ISAKMP) printer */
32
33 #ifdef HAVE_CONFIG_H
34 #include "config.h"
35 #endif
36
37 /* The functions from print-esp.c used in this file are only defined when both
38 * OpenSSL and evp.h are detected. Employ the same preprocessor device here.
39 */
40 #ifndef HAVE_OPENSSL_EVP_H
41 #undef HAVE_LIBCRYPTO
42 #endif
43
44 #include <netdissect-stdinc.h>
45
46 #include <string.h>
47
48 #include "netdissect.h"
49 #include "addrtoname.h"
50 #include "extract.h"
51
52 #include "ip.h"
53 #include "ip6.h"
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 struct in6_addr in6;
651 };
652 struct {
653 cookie_t initiator;
654 u_int version;
655 union inaddr_u iaddr;
656 union inaddr_u raddr;
657 } cookiecache[MAXINITIATORS];
658
659 /* protocol id */
660 static const char *protoidstr[] = {
661 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
662 };
663
664 /* isakmp->np */
665 static const char *npstr[] = {
666 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
667 "sig", "nonce", "n", "d", "vid", /* 9 - 13 */
668 "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
669 "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
670 "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
671 "pay29", "pay30", "pay31", "pay32", /* 29- 32 */
672 "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
673 "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */
674 "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */
675 "v2eap", /* 48 */
676
677 };
678
679 /* isakmp->np */
680 static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
681 const struct isakmp_gen *ext,
682 u_int item_len,
683 const u_char *end_pointer,
684 uint32_t phase,
685 uint32_t doi0,
686 uint32_t proto0, int depth) = {
687 NULL,
688 ikev1_sa_print,
689 ikev1_p_print,
690 ikev1_t_print,
691 ikev1_ke_print,
692 ikev1_id_print,
693 ikev1_cert_print,
694 ikev1_cr_print,
695 ikev1_hash_print,
696 ikev1_sig_print,
697 ikev1_nonce_print,
698 ikev1_n_print,
699 ikev1_d_print,
700 ikev1_vid_print, /* 13 */
701 NULL, NULL, NULL, NULL, NULL, /* 14- 18 */
702 NULL, NULL, NULL, NULL, NULL, /* 19- 23 */
703 NULL, NULL, NULL, NULL, NULL, /* 24- 28 */
704 NULL, NULL, NULL, NULL, /* 29- 32 */
705 ikev2_sa_print, /* 33 */
706 ikev2_ke_print, /* 34 */
707 ikev2_ID_print, /* 35 */
708 ikev2_ID_print, /* 36 */
709 ikev2_cert_print, /* 37 */
710 ikev2_cr_print, /* 38 */
711 ikev2_auth_print, /* 39 */
712 ikev2_nonce_print, /* 40 */
713 ikev2_n_print, /* 41 */
714 ikev2_d_print, /* 42 */
715 ikev2_vid_print, /* 43 */
716 ikev2_TS_print, /* 44 */
717 ikev2_TS_print, /* 45 */
718 NULL, /* ikev2_e_print,*/ /* 46 - special */
719 ikev2_cp_print, /* 47 */
720 ikev2_eap_print, /* 48 */
721 };
722
723 /* isakmp->etype */
724 static const char *etypestr[] = {
725 /* IKEv1 exchange types */
726 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */
727 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */
728 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */
729 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */
730 "oakley-quick", "oakley-newgroup", /* 32-33 */
731 /* IKEv2 exchange types */
732 "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */
733 };
734
735 #define STR_OR_ID(x, tab) \
736 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
737 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
738 #define NPSTR(x) STR_OR_ID(x, npstr)
739 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
740
741 #define CHECKLEN(p, np) \
742 if (ep < (const u_char *)(p)) { \
743 ND_PRINT((ndo," [|%s]", NPSTR(np))); \
744 goto done; \
745 }
746
747
748 #define NPFUNC(x) \
749 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
750 ? npfunc[(x)] : NULL)
751
752 static int
753 iszero(const u_char *p, size_t l)
754 {
755 while (l--) {
756 if (*p++)
757 return 0;
758 }
759 return 1;
760 }
761
762 /* find cookie from initiator cache */
763 static int
764 cookie_find(cookie_t *in)
765 {
766 int i;
767
768 for (i = 0; i < MAXINITIATORS; i++) {
769 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
770 return i;
771 }
772
773 return -1;
774 }
775
776 /* record initiator */
777 static void
778 cookie_record(cookie_t *in, const u_char *bp2)
779 {
780 int i;
781 const struct ip *ip;
782 const struct ip6_hdr *ip6;
783
784 i = cookie_find(in);
785 if (0 <= i) {
786 ninitiator = (i + 1) % MAXINITIATORS;
787 return;
788 }
789
790 ip = (const struct ip *)bp2;
791 switch (IP_V(ip)) {
792 case 4:
793 cookiecache[ninitiator].version = 4;
794 UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in4, &ip->ip_src, sizeof(struct in_addr));
795 UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in4, &ip->ip_dst, sizeof(struct in_addr));
796 break;
797 case 6:
798 ip6 = (const struct ip6_hdr *)bp2;
799 cookiecache[ninitiator].version = 6;
800 UNALIGNED_MEMCPY(&cookiecache[ninitiator].iaddr.in6, &ip6->ip6_src, sizeof(struct in6_addr));
801 UNALIGNED_MEMCPY(&cookiecache[ninitiator].raddr.in6, &ip6->ip6_dst, sizeof(struct in6_addr));
802 break;
803 default:
804 return;
805 }
806 UNALIGNED_MEMCPY(&cookiecache[ninitiator].initiator, in, sizeof(*in));
807 ninitiator = (ninitiator + 1) % MAXINITIATORS;
808 }
809
810 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
811 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
812 static int
813 cookie_sidecheck(int i, const u_char *bp2, int initiator)
814 {
815 const struct ip *ip;
816 const struct ip6_hdr *ip6;
817
818 ip = (const struct ip *)bp2;
819 switch (IP_V(ip)) {
820 case 4:
821 if (cookiecache[i].version != 4)
822 return 0;
823 if (initiator) {
824 if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].iaddr.in4, sizeof(struct in_addr)) == 0)
825 return 1;
826 } else {
827 if (UNALIGNED_MEMCMP(&ip->ip_src, &cookiecache[i].raddr.in4, sizeof(struct in_addr)) == 0)
828 return 1;
829 }
830 break;
831 case 6:
832 if (cookiecache[i].version != 6)
833 return 0;
834 ip6 = (const struct ip6_hdr *)bp2;
835 if (initiator) {
836 if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].iaddr.in6, sizeof(struct in6_addr)) == 0)
837 return 1;
838 } else {
839 if (UNALIGNED_MEMCMP(&ip6->ip6_src, &cookiecache[i].raddr.in6, sizeof(struct in6_addr)) == 0)
840 return 1;
841 }
842 break;
843 default:
844 break;
845 }
846
847 return 0;
848 }
849
850 static void
851 hexprint(netdissect_options *ndo, const uint8_t *loc, size_t len)
852 {
853 const uint8_t *p;
854 size_t i;
855
856 p = loc;
857 for (i = 0; i < len; i++)
858 ND_PRINT((ndo,"%02x", p[i] & 0xff));
859 }
860
861 static int
862 rawprint(netdissect_options *ndo, const uint8_t *loc, size_t len)
863 {
864 ND_TCHECK2(*loc, len);
865
866 hexprint(ndo, loc, len);
867 return 1;
868 trunc:
869 return 0;
870 }
871
872
873 /*
874 * returns false if we run out of data buffer
875 */
876 static int ike_show_somedata(netdissect_options *ndo,
877 const u_char *cp, const u_char *ep)
878 {
879 /* there is too much data, just show some of it */
880 const u_char *end = ep - 20;
881 int elen = 20;
882 int len = ep - cp;
883 if(len > 10) {
884 len = 10;
885 }
886
887 /* really shouldn't happen because of above */
888 if(end < cp + len) {
889 end = cp+len;
890 elen = ep - end;
891 }
892
893 ND_PRINT((ndo," data=("));
894 if(!rawprint(ndo, (const uint8_t *)(cp), len)) goto trunc;
895 ND_PRINT((ndo, "..."));
896 if(elen) {
897 if(!rawprint(ndo, (const uint8_t *)(end), elen)) goto trunc;
898 }
899 ND_PRINT((ndo,")"));
900 return 1;
901
902 trunc:
903 return 0;
904 }
905
906 struct attrmap {
907 const char *type;
908 u_int nvalue;
909 const char *value[30]; /*XXX*/
910 };
911
912 static const u_char *
913 ikev1_attrmap_print(netdissect_options *ndo,
914 const u_char *p, const u_char *ep,
915 const struct attrmap *map, size_t nmap)
916 {
917 int totlen;
918 uint32_t t, v;
919
920 if (p[0] & 0x80)
921 totlen = 4;
922 else
923 totlen = 4 + EXTRACT_16BITS(&p[2]);
924 if (ep < p + totlen) {
925 ND_PRINT((ndo,"[|attr]"));
926 return ep + 1;
927 }
928
929 ND_PRINT((ndo,"("));
930 t = EXTRACT_16BITS(&p[0]) & 0x7fff;
931 if (map && t < nmap && map[t].type)
932 ND_PRINT((ndo,"type=%s ", map[t].type));
933 else
934 ND_PRINT((ndo,"type=#%d ", t));
935 if (p[0] & 0x80) {
936 ND_PRINT((ndo,"value="));
937 v = EXTRACT_16BITS(&p[2]);
938 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
939 ND_PRINT((ndo,"%s", map[t].value[v]));
940 else
941 rawprint(ndo, (const uint8_t *)&p[2], 2);
942 } else {
943 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
944 rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
945 }
946 ND_PRINT((ndo,")"));
947 return p + totlen;
948 }
949
950 static const u_char *
951 ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
952 {
953 int totlen;
954 uint32_t t;
955
956 if (p[0] & 0x80)
957 totlen = 4;
958 else
959 totlen = 4 + EXTRACT_16BITS(&p[2]);
960 if (ep < p + totlen) {
961 ND_PRINT((ndo,"[|attr]"));
962 return ep + 1;
963 }
964
965 ND_PRINT((ndo,"("));
966 t = EXTRACT_16BITS(&p[0]) & 0x7fff;
967 ND_PRINT((ndo,"type=#%d ", t));
968 if (p[0] & 0x80) {
969 ND_PRINT((ndo,"value="));
970 t = p[2];
971 rawprint(ndo, (const uint8_t *)&p[2], 2);
972 } else {
973 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
974 rawprint(ndo, (const uint8_t *)&p[4], EXTRACT_16BITS(&p[2]));
975 }
976 ND_PRINT((ndo,")"));
977 return p + totlen;
978 }
979
980 static const u_char *
981 ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
982 const struct isakmp_gen *ext,
983 u_int item_len _U_,
984 const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
985 uint32_t proto0, int depth)
986 {
987 const struct ikev1_pl_sa *p;
988 struct ikev1_pl_sa sa;
989 uint32_t doi, sit, ident;
990 const u_char *cp, *np;
991 int t;
992
993 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
994
995 p = (const struct ikev1_pl_sa *)ext;
996 ND_TCHECK(*p);
997 UNALIGNED_MEMCPY(&sa, ext, sizeof(sa));
998 doi = ntohl(sa.doi);
999 sit = ntohl(sa.sit);
1000 if (doi != 1) {
1001 ND_PRINT((ndo," doi=%d", doi));
1002 ND_PRINT((ndo," situation=%u", (uint32_t)ntohl(sa.sit)));
1003 return (const u_char *)(p + 1);
1004 }
1005
1006 ND_PRINT((ndo," doi=ipsec"));
1007 ND_PRINT((ndo," situation="));
1008 t = 0;
1009 if (sit & 0x01) {
1010 ND_PRINT((ndo,"identity"));
1011 t++;
1012 }
1013 if (sit & 0x02) {
1014 ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));
1015 t++;
1016 }
1017 if (sit & 0x04)
1018 ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));
1019
1020 np = (const u_char *)ext + sizeof(sa);
1021 if (sit != 0x01) {
1022 ND_TCHECK2(*(ext + 1), sizeof(ident));
1023 UNALIGNED_MEMCPY(&ident, ext + 1, sizeof(ident));
1024 ND_PRINT((ndo," ident=%u", (uint32_t)ntohl(ident)));
1025 np += sizeof(ident);
1026 }
1027
1028 ext = (const struct isakmp_gen *)np;
1029 ND_TCHECK(*ext);
1030
1031 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
1032 depth);
1033
1034 return cp;
1035 trunc:
1036 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));
1037 return NULL;
1038 }
1039
1040 static const u_char *
1041 ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
1042 const struct isakmp_gen *ext, u_int item_len _U_,
1043 const u_char *ep, uint32_t phase, uint32_t doi0,
1044 uint32_t proto0 _U_, int depth)
1045 {
1046 const struct ikev1_pl_p *p;
1047 struct ikev1_pl_p prop;
1048 const u_char *cp;
1049
1050 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
1051
1052 p = (const struct ikev1_pl_p *)ext;
1053 ND_TCHECK(*p);
1054 UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
1055 ND_PRINT((ndo," #%d protoid=%s transform=%d",
1056 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
1057 if (prop.spi_size) {
1058 ND_PRINT((ndo," spi="));
1059 if (!rawprint(ndo, (const uint8_t *)(p + 1), prop.spi_size))
1060 goto trunc;
1061 }
1062
1063 ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + prop.spi_size);
1064 ND_TCHECK(*ext);
1065
1066 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1067 prop.prot_id, depth);
1068
1069 return cp;
1070 trunc:
1071 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1072 return NULL;
1073 }
1074
1075 static const char *ikev1_p_map[] = {
1076 NULL, "ike",
1077 };
1078
1079 static const char *ikev2_t_type_map[]={
1080 NULL, "encr", "prf", "integ", "dh", "esn"
1081 };
1082
1083 static const char *ah_p_map[] = {
1084 NULL, "(reserved)", "md5", "sha", "1des",
1085 "sha2-256", "sha2-384", "sha2-512",
1086 };
1087
1088 static const char *prf_p_map[] = {
1089 NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
1090 "aes128_xcbc"
1091 };
1092
1093 static const char *integ_p_map[] = {
1094 NULL, "hmac-md5", "hmac-sha", "dec-mac",
1095 "kpdk-md5", "aes-xcbc"
1096 };
1097
1098 static const char *esn_p_map[] = {
1099 "no-esn", "esn"
1100 };
1101
1102 static const char *dh_p_map[] = {
1103 NULL, "modp768",
1104 "modp1024", /* group 2 */
1105 "EC2N 2^155", /* group 3 */
1106 "EC2N 2^185", /* group 4 */
1107 "modp1536", /* group 5 */
1108 "iana-grp06", "iana-grp07", /* reserved */
1109 "iana-grp08", "iana-grp09",
1110 "iana-grp10", "iana-grp11",
1111 "iana-grp12", "iana-grp13",
1112 "modp2048", /* group 14 */
1113 "modp3072", /* group 15 */
1114 "modp4096", /* group 16 */
1115 "modp6144", /* group 17 */
1116 "modp8192", /* group 18 */
1117 };
1118
1119 static const char *esp_p_map[] = {
1120 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
1121 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
1122 };
1123
1124 static const char *ipcomp_p_map[] = {
1125 NULL, "oui", "deflate", "lzs",
1126 };
1127
1128 static const struct attrmap ipsec_t_map[] = {
1129 { NULL, 0, { NULL } },
1130 { "lifetype", 3, { NULL, "sec", "kb", }, },
1131 { "life", 0, { NULL } },
1132 { "group desc", 18, { NULL, "modp768",
1133 "modp1024", /* group 2 */
1134 "EC2N 2^155", /* group 3 */
1135 "EC2N 2^185", /* group 4 */
1136 "modp1536", /* group 5 */
1137 "iana-grp06", "iana-grp07", /* reserved */
1138 "iana-grp08", "iana-grp09",
1139 "iana-grp10", "iana-grp11",
1140 "iana-grp12", "iana-grp13",
1141 "modp2048", /* group 14 */
1142 "modp3072", /* group 15 */
1143 "modp4096", /* group 16 */
1144 "modp6144", /* group 17 */
1145 "modp8192", /* group 18 */
1146 }, },
1147 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
1148 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
1149 { "keylen", 0, { NULL } },
1150 { "rounds", 0, { NULL } },
1151 { "dictsize", 0, { NULL } },
1152 { "privalg", 0, { NULL } },
1153 };
1154
1155 static const struct attrmap encr_t_map[] = {
1156 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */
1157 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */
1158 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */
1159 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */
1160 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */
1161 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/
1162 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/
1163 { "keylen", 14, { NULL }},
1164 };
1165
1166 static const struct attrmap oakley_t_map[] = {
1167 { NULL, 0, { NULL } },
1168 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
1169 "3des", "cast", "aes", }, },
1170 { "hash", 7, { NULL, "md5", "sha1", "tiger",
1171 "sha2-256", "sha2-384", "sha2-512", }, },
1172 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
1173 "rsa enc revised", }, },
1174 { "group desc", 18, { NULL, "modp768",
1175 "modp1024", /* group 2 */
1176 "EC2N 2^155", /* group 3 */
1177 "EC2N 2^185", /* group 4 */
1178 "modp1536", /* group 5 */
1179 "iana-grp06", "iana-grp07", /* reserved */
1180 "iana-grp08", "iana-grp09",
1181 "iana-grp10", "iana-grp11",
1182 "iana-grp12", "iana-grp13",
1183 "modp2048", /* group 14 */
1184 "modp3072", /* group 15 */
1185 "modp4096", /* group 16 */
1186 "modp6144", /* group 17 */
1187 "modp8192", /* group 18 */
1188 }, },
1189 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
1190 { "group prime", 0, { NULL } },
1191 { "group gen1", 0, { NULL } },
1192 { "group gen2", 0, { NULL } },
1193 { "group curve A", 0, { NULL } },
1194 { "group curve B", 0, { NULL } },
1195 { "lifetype", 3, { NULL, "sec", "kb", }, },
1196 { "lifeduration", 0, { NULL } },
1197 { "prf", 0, { NULL } },
1198 { "keylen", 0, { NULL } },
1199 { "field", 0, { NULL } },
1200 { "order", 0, { NULL } },
1201 };
1202
1203 static const u_char *
1204 ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
1205 const struct isakmp_gen *ext, u_int item_len,
1206 const u_char *ep, uint32_t phase _U_, uint32_t doi _U_,
1207 uint32_t proto, int depth _U_)
1208 {
1209 const struct ikev1_pl_t *p;
1210 struct ikev1_pl_t t;
1211 const u_char *cp;
1212 const char *idstr;
1213 const struct attrmap *map;
1214 size_t nmap;
1215 const u_char *ep2;
1216
1217 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
1218
1219 p = (const struct ikev1_pl_t *)ext;
1220 ND_TCHECK(*p);
1221 UNALIGNED_MEMCPY(&t, ext, sizeof(t));
1222
1223 switch (proto) {
1224 case 1:
1225 idstr = STR_OR_ID(t.t_id, ikev1_p_map);
1226 map = oakley_t_map;
1227 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1228 break;
1229 case 2:
1230 idstr = STR_OR_ID(t.t_id, ah_p_map);
1231 map = ipsec_t_map;
1232 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1233 break;
1234 case 3:
1235 idstr = STR_OR_ID(t.t_id, esp_p_map);
1236 map = ipsec_t_map;
1237 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1238 break;
1239 case 4:
1240 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
1241 map = ipsec_t_map;
1242 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
1243 break;
1244 default:
1245 idstr = NULL;
1246 map = NULL;
1247 nmap = 0;
1248 break;
1249 }
1250
1251 if (idstr)
1252 ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr));
1253 else
1254 ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id));
1255 cp = (const u_char *)(p + 1);
1256 ep2 = (const u_char *)p + item_len;
1257 while (cp < ep && cp < ep2) {
1258 if (map && nmap) {
1259 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1260 map, nmap);
1261 } else
1262 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1263 }
1264 if (ep < ep2)
1265 ND_PRINT((ndo,"..."));
1266 return cp;
1267 trunc:
1268 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1269 return NULL;
1270 }
1271
1272 static const u_char *
1273 ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
1274 const struct isakmp_gen *ext, u_int item_len _U_,
1275 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1276 uint32_t proto _U_, int depth _U_)
1277 {
1278 struct isakmp_gen e;
1279
1280 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
1281
1282 ND_TCHECK(*ext);
1283 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1284 ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
1285 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1286 ND_PRINT((ndo," "));
1287 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1288 goto trunc;
1289 }
1290 return (const u_char *)ext + ntohs(e.len);
1291 trunc:
1292 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE)));
1293 return NULL;
1294 }
1295
1296 static const u_char *
1297 ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
1298 const struct isakmp_gen *ext, u_int item_len,
1299 const u_char *ep _U_, uint32_t phase, uint32_t doi _U_,
1300 uint32_t proto _U_, int depth _U_)
1301 {
1302 #define USE_IPSECDOI_IN_PHASE1 1
1303 const struct ikev1_pl_id *p;
1304 struct ikev1_pl_id id;
1305 static const char *idtypestr[] = {
1306 "IPv4", "IPv4net", "IPv6", "IPv6net",
1307 };
1308 static const char *ipsecidtypestr[] = {
1309 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
1310 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
1311 "keyid",
1312 };
1313 int len;
1314 const u_char *data;
1315
1316 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
1317
1318 p = (const struct ikev1_pl_id *)ext;
1319 ND_TCHECK(*p);
1320 UNALIGNED_MEMCPY(&id, ext, sizeof(id));
1321 if (sizeof(*p) < item_len) {
1322 data = (const u_char *)(p + 1);
1323 len = item_len - sizeof(*p);
1324 } else {
1325 data = NULL;
1326 len = 0;
1327 }
1328
1329 #if 0 /*debug*/
1330 ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto));
1331 #endif
1332 switch (phase) {
1333 #ifndef USE_IPSECDOI_IN_PHASE1
1334 case 1:
1335 #endif
1336 default:
1337 ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)));
1338 ND_PRINT((ndo," doi_data=%u",
1339 (uint32_t)(ntohl(id.d.doi_data) & 0xffffff)));
1340 break;
1341
1342 #ifdef USE_IPSECDOI_IN_PHASE1
1343 case 1:
1344 #endif
1345 case 2:
1346 {
1347 const struct ipsecdoi_id *doi_p;
1348 struct ipsecdoi_id doi_id;
1349 struct protoent *pe;
1350
1351 doi_p = (const struct ipsecdoi_id *)ext;
1352 ND_TCHECK(*doi_p);
1353 UNALIGNED_MEMCPY(&doi_id, ext, sizeof(doi_id));
1354 ND_PRINT((ndo," idtype=%s", STR_OR_ID(doi_id.type, ipsecidtypestr)));
1355 /* A protocol ID of 0 DOES NOT mean IPPROTO_IP! */
1356 pe = doi_id.proto_id ? getprotobynumber(doi_id.proto_id) : NULL;
1357 if (pe)
1358 ND_PRINT((ndo," protoid=%s", pe->p_name));
1359 else
1360 ND_PRINT((ndo," protoid=%u", doi_id.proto_id));
1361 ND_PRINT((ndo," port=%d", ntohs(doi_id.port)));
1362 if (!len)
1363 break;
1364 if (data == NULL)
1365 goto trunc;
1366 ND_TCHECK2(*data, len);
1367 switch (doi_id.type) {
1368 case IPSECDOI_ID_IPV4_ADDR:
1369 if (len < 4)
1370 ND_PRINT((ndo," len=%d [bad: < 4]", len));
1371 else
1372 ND_PRINT((ndo," len=%d %s", len, ipaddr_string(ndo, data)));
1373 len = 0;
1374 break;
1375 case IPSECDOI_ID_FQDN:
1376 case IPSECDOI_ID_USER_FQDN:
1377 {
1378 int i;
1379 ND_PRINT((ndo," len=%d ", len));
1380 for (i = 0; i < len; i++)
1381 safeputchar(ndo, data[i]);
1382 len = 0;
1383 break;
1384 }
1385 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
1386 {
1387 const u_char *mask;
1388 if (len < 8)
1389 ND_PRINT((ndo," len=%d [bad: < 8]", len));
1390 else {
1391 mask = data + sizeof(struct in_addr);
1392 ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len,
1393 ipaddr_string(ndo, data),
1394 mask[0], mask[1], mask[2], mask[3]));
1395 }
1396 len = 0;
1397 break;
1398 }
1399 case IPSECDOI_ID_IPV6_ADDR:
1400 if (len < 16)
1401 ND_PRINT((ndo," len=%d [bad: < 16]", len));
1402 else
1403 ND_PRINT((ndo," len=%d %s", len, ip6addr_string(ndo, data)));
1404 len = 0;
1405 break;
1406 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
1407 {
1408 const u_char *mask;
1409 if (len < 20)
1410 ND_PRINT((ndo," len=%d [bad: < 20]", len));
1411 else {
1412 mask = (const u_char *)(data + sizeof(struct in6_addr));
1413 /*XXX*/
1414 ND_PRINT((ndo," len=%d %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len,
1415 ip6addr_string(ndo, data),
1416 mask[0], mask[1], mask[2], mask[3],
1417 mask[4], mask[5], mask[6], mask[7],
1418 mask[8], mask[9], mask[10], mask[11],
1419 mask[12], mask[13], mask[14], mask[15]));
1420 }
1421 len = 0;
1422 break;
1423 }
1424 case IPSECDOI_ID_IPV4_ADDR_RANGE:
1425 if (len < 8)
1426 ND_PRINT((ndo," len=%d [bad: < 8]", len));
1427 else {
1428 ND_PRINT((ndo," len=%d %s-%s", len,
1429 ipaddr_string(ndo, data),
1430 ipaddr_string(ndo, data + sizeof(struct in_addr))));
1431 }
1432 len = 0;
1433 break;
1434 case IPSECDOI_ID_IPV6_ADDR_RANGE:
1435 if (len < 32)
1436 ND_PRINT((ndo," len=%d [bad: < 32]", len));
1437 else {
1438 ND_PRINT((ndo," len=%d %s-%s", len,
1439 ip6addr_string(ndo, data),
1440 ip6addr_string(ndo, data + sizeof(struct in6_addr))));
1441 }
1442 len = 0;
1443 break;
1444 case IPSECDOI_ID_DER_ASN1_DN:
1445 case IPSECDOI_ID_DER_ASN1_GN:
1446 case IPSECDOI_ID_KEY_ID:
1447 break;
1448 }
1449 break;
1450 }
1451 }
1452 if (data && len) {
1453 ND_PRINT((ndo," len=%d", len));
1454 if (2 < ndo->ndo_vflag) {
1455 ND_PRINT((ndo," "));
1456 if (!rawprint(ndo, (const uint8_t *)data, len))
1457 goto trunc;
1458 }
1459 }
1460 return (const u_char *)ext + item_len;
1461 trunc:
1462 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID)));
1463 return NULL;
1464 }
1465
1466 static const u_char *
1467 ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
1468 const struct isakmp_gen *ext, u_int item_len,
1469 const u_char *ep _U_, uint32_t phase _U_,
1470 uint32_t doi0 _U_,
1471 uint32_t proto0 _U_, int depth _U_)
1472 {
1473 const struct ikev1_pl_cert *p;
1474 struct ikev1_pl_cert cert;
1475 static const char *certstr[] = {
1476 "none", "pkcs7", "pgp", "dns",
1477 "x509sign", "x509ke", "kerberos", "crl",
1478 "arl", "spki", "x509attr",
1479 };
1480
1481 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
1482
1483 p = (const struct ikev1_pl_cert *)ext;
1484 ND_TCHECK(*p);
1485 UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1486 ND_PRINT((ndo," len=%d", item_len - 4));
1487 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1488 if (2 < ndo->ndo_vflag && 4 < item_len) {
1489 ND_PRINT((ndo," "));
1490 if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1491 goto trunc;
1492 }
1493 return (const u_char *)ext + item_len;
1494 trunc:
1495 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)));
1496 return NULL;
1497 }
1498
1499 static const u_char *
1500 ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
1501 const struct isakmp_gen *ext, u_int item_len,
1502 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1503 uint32_t proto0 _U_, int depth _U_)
1504 {
1505 const struct ikev1_pl_cert *p;
1506 struct ikev1_pl_cert cert;
1507 static const char *certstr[] = {
1508 "none", "pkcs7", "pgp", "dns",
1509 "x509sign", "x509ke", "kerberos", "crl",
1510 "arl", "spki", "x509attr",
1511 };
1512
1513 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
1514
1515 p = (const struct ikev1_pl_cert *)ext;
1516 ND_TCHECK(*p);
1517 UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1518 ND_PRINT((ndo," len=%d", item_len - 4));
1519 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1520 if (2 < ndo->ndo_vflag && 4 < item_len) {
1521 ND_PRINT((ndo," "));
1522 if (!rawprint(ndo, (const uint8_t *)(ext + 1), item_len - 4))
1523 goto trunc;
1524 }
1525 return (const u_char *)ext + item_len;
1526 trunc:
1527 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR)));
1528 return NULL;
1529 }
1530
1531 static const u_char *
1532 ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
1533 const struct isakmp_gen *ext, u_int item_len _U_,
1534 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1535 uint32_t proto _U_, int depth _U_)
1536 {
1537 struct isakmp_gen e;
1538
1539 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
1540
1541 ND_TCHECK(*ext);
1542 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1543 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1544 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1545 ND_PRINT((ndo," "));
1546 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1547 goto trunc;
1548 }
1549 return (const u_char *)ext + ntohs(e.len);
1550 trunc:
1551 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)));
1552 return NULL;
1553 }
1554
1555 static const u_char *
1556 ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
1557 const struct isakmp_gen *ext, u_int item_len _U_,
1558 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi _U_,
1559 uint32_t proto _U_, int depth _U_)
1560 {
1561 struct isakmp_gen e;
1562
1563 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
1564
1565 ND_TCHECK(*ext);
1566 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1567 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1568 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1569 ND_PRINT((ndo," "));
1570 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1571 goto trunc;
1572 }
1573 return (const u_char *)ext + ntohs(e.len);
1574 trunc:
1575 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)));
1576 return NULL;
1577 }
1578
1579 static const u_char *
1580 ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
1581 const struct isakmp_gen *ext,
1582 u_int item_len _U_,
1583 const u_char *ep,
1584 uint32_t phase _U_, uint32_t doi _U_,
1585 uint32_t proto _U_, int depth _U_)
1586 {
1587 struct isakmp_gen e;
1588
1589 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
1590
1591 ND_TCHECK(*ext);
1592 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1593 ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
1594 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1595 ND_PRINT((ndo," "));
1596 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1597 goto trunc;
1598 } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1599 ND_PRINT((ndo," "));
1600 if (!ike_show_somedata(ndo, (const u_char *)(const uint8_t *)(ext + 1), ep))
1601 goto trunc;
1602 }
1603 return (const u_char *)ext + ntohs(e.len);
1604 trunc:
1605 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)));
1606 return NULL;
1607 }
1608
1609 static const u_char *
1610 ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
1611 const struct isakmp_gen *ext, u_int item_len,
1612 const u_char *ep, uint32_t phase, uint32_t doi0 _U_,
1613 uint32_t proto0 _U_, int depth)
1614 {
1615 const struct ikev1_pl_n *p;
1616 struct ikev1_pl_n n;
1617 const u_char *cp;
1618 const u_char *ep2;
1619 uint32_t doi;
1620 uint32_t proto;
1621 static const char *notify_error_str[] = {
1622 NULL, "INVALID-PAYLOAD-TYPE",
1623 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
1624 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
1625 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
1626 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
1627 "INVALID-PROTOCOL-ID", "INVALID-SPI",
1628 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
1629 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
1630 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
1631 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
1632 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
1633 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
1634 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
1635 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
1636 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
1637 "UNEQUAL-PAYLOAD-LENGTHS",
1638 };
1639 static const char *ipsec_notify_error_str[] = {
1640 "RESERVED",
1641 };
1642 static const char *notify_status_str[] = {
1643 "CONNECTED",
1644 };
1645 static const char *ipsec_notify_status_str[] = {
1646 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1647 "INITIAL-CONTACT",
1648 };
1649 /* NOTE: these macro must be called with x in proper range */
1650
1651 /* 0 - 8191 */
1652 #define NOTIFY_ERROR_STR(x) \
1653 STR_OR_ID((x), notify_error_str)
1654
1655 /* 8192 - 16383 */
1656 #define IPSEC_NOTIFY_ERROR_STR(x) \
1657 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1658
1659 /* 16384 - 24575 */
1660 #define NOTIFY_STATUS_STR(x) \
1661 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1662
1663 /* 24576 - 32767 */
1664 #define IPSEC_NOTIFY_STATUS_STR(x) \
1665 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1666
1667 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
1668
1669 p = (const struct ikev1_pl_n *)ext;
1670 ND_TCHECK(*p);
1671 UNALIGNED_MEMCPY(&n, ext, sizeof(n));
1672 doi = ntohl(n.doi);
1673 proto = n.prot_id;
1674 if (doi != 1) {
1675 ND_PRINT((ndo," doi=%d", doi));
1676 ND_PRINT((ndo," proto=%d", proto));
1677 if (ntohs(n.type) < 8192)
1678 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1679 else if (ntohs(n.type) < 16384)
1680 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1681 else if (ntohs(n.type) < 24576)
1682 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1683 else
1684 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1685 if (n.spi_size) {
1686 ND_PRINT((ndo," spi="));
1687 if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size))
1688 goto trunc;
1689 }
1690 return (const u_char *)(p + 1) + n.spi_size;
1691 }
1692
1693 ND_PRINT((ndo," doi=ipsec"));
1694 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1695 if (ntohs(n.type) < 8192)
1696 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
1697 else if (ntohs(n.type) < 16384)
1698 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type))));
1699 else if (ntohs(n.type) < 24576)
1700 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
1701 else if (ntohs(n.type) < 32768)
1702 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type))));
1703 else
1704 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
1705 if (n.spi_size) {
1706 ND_PRINT((ndo," spi="));
1707 if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size))
1708 goto trunc;
1709 }
1710
1711 cp = (const u_char *)(p + 1) + n.spi_size;
1712 ep2 = (const u_char *)p + item_len;
1713
1714 if (cp < ep) {
1715 ND_PRINT((ndo," orig=("));
1716 switch (ntohs(n.type)) {
1717 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1718 {
1719 const struct attrmap *map = oakley_t_map;
1720 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1721 while (cp < ep && cp < ep2) {
1722 cp = ikev1_attrmap_print(ndo, cp,
1723 (ep < ep2) ? ep : ep2, map, nmap);
1724 }
1725 break;
1726 }
1727 case IPSECDOI_NTYPE_REPLAY_STATUS:
1728 ND_PRINT((ndo,"replay detection %sabled",
1729 EXTRACT_32BITS(cp) ? "en" : "dis"));
1730 break;
1731 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1732 if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
1733 (const struct isakmp_gen *)cp, ep, phase, doi, proto,
1734 depth) == NULL)
1735 return NULL;
1736 break;
1737 default:
1738 /* NULL is dummy */
1739 isakmp_print(ndo, cp,
1740 item_len - sizeof(*p) - n.spi_size,
1741 NULL);
1742 }
1743 ND_PRINT((ndo,")"));
1744 }
1745 return (const u_char *)ext + item_len;
1746 trunc:
1747 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
1748 return NULL;
1749 }
1750
1751 static const u_char *
1752 ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
1753 const struct isakmp_gen *ext, u_int item_len _U_,
1754 const u_char *ep _U_, uint32_t phase _U_, uint32_t doi0 _U_,
1755 uint32_t proto0 _U_, int depth _U_)
1756 {
1757 const struct ikev1_pl_d *p;
1758 struct ikev1_pl_d d;
1759 const uint8_t *q;
1760 uint32_t doi;
1761 uint32_t proto;
1762 int i;
1763
1764 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
1765
1766 p = (const struct ikev1_pl_d *)ext;
1767 ND_TCHECK(*p);
1768 UNALIGNED_MEMCPY(&d, ext, sizeof(d));
1769 doi = ntohl(d.doi);
1770 proto = d.prot_id;
1771 if (doi != 1) {
1772 ND_PRINT((ndo," doi=%u", doi));
1773 ND_PRINT((ndo," proto=%u", proto));
1774 } else {
1775 ND_PRINT((ndo," doi=ipsec"));
1776 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
1777 }
1778 ND_PRINT((ndo," spilen=%u", d.spi_size));
1779 ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi)));
1780 ND_PRINT((ndo," spi="));
1781 q = (const uint8_t *)(p + 1);
1782 for (i = 0; i < ntohs(d.num_spi); i++) {
1783 if (i != 0)
1784 ND_PRINT((ndo,","));
1785 if (!rawprint(ndo, (const uint8_t *)q, d.spi_size))
1786 goto trunc;
1787 q += d.spi_size;
1788 }
1789 return q;
1790 trunc:
1791 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D)));
1792 return NULL;
1793 }
1794
1795 static const u_char *
1796 ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
1797 const struct isakmp_gen *ext,
1798 u_int item_len _U_, const u_char *ep _U_,
1799 uint32_t phase _U_, uint32_t doi _U_,
1800 uint32_t proto _U_, int depth _U_)
1801 {
1802 struct isakmp_gen e;
1803
1804 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
1805
1806 ND_TCHECK(*ext);
1807 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1808 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1809 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1810 ND_PRINT((ndo," "));
1811 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1812 goto trunc;
1813 }
1814 return (const u_char *)ext + ntohs(e.len);
1815 trunc:
1816 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID)));
1817 return NULL;
1818 }
1819
1820 /************************************************************/
1821 /* */
1822 /* IKE v2 - rfc4306 - dissector */
1823 /* */
1824 /************************************************************/
1825
1826 static void
1827 ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical)
1828 {
1829 ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : ""));
1830 }
1831
1832 static const u_char *
1833 ikev2_gen_print(netdissect_options *ndo, u_char tpay,
1834 const struct isakmp_gen *ext)
1835 {
1836 struct isakmp_gen e;
1837
1838 ND_TCHECK(*ext);
1839 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1840 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
1841
1842 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1843 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1844 ND_PRINT((ndo," "));
1845 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
1846 goto trunc;
1847 }
1848 return (const u_char *)ext + ntohs(e.len);
1849 trunc:
1850 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1851 return NULL;
1852 }
1853
1854 static const u_char *
1855 ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
1856 const struct isakmp_gen *ext, u_int item_len,
1857 const u_char *ep, uint32_t phase _U_, uint32_t doi _U_,
1858 uint32_t proto _U_, int depth _U_)
1859 {
1860 const struct ikev2_t *p;
1861 struct ikev2_t t;
1862 uint16_t t_id;
1863 const u_char *cp;
1864 const char *idstr;
1865 const struct attrmap *map;
1866 size_t nmap;
1867 const u_char *ep2;
1868
1869 p = (const struct ikev2_t *)ext;
1870 ND_TCHECK(*p);
1871 UNALIGNED_MEMCPY(&t, ext, sizeof(t));
1872 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
1873
1874 t_id = ntohs(t.t_id);
1875
1876 map = NULL;
1877 nmap = 0;
1878
1879 switch (t.t_type) {
1880 case IV2_T_ENCR:
1881 idstr = STR_OR_ID(t_id, esp_p_map);
1882 map = encr_t_map;
1883 nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
1884 break;
1885
1886 case IV2_T_PRF:
1887 idstr = STR_OR_ID(t_id, prf_p_map);
1888 break;
1889
1890 case IV2_T_INTEG:
1891 idstr = STR_OR_ID(t_id, integ_p_map);
1892 break;
1893
1894 case IV2_T_DH:
1895 idstr = STR_OR_ID(t_id, dh_p_map);
1896 break;
1897
1898 case IV2_T_ESN:
1899 idstr = STR_OR_ID(t_id, esn_p_map);
1900 break;
1901
1902 default:
1903 idstr = NULL;
1904 break;
1905 }
1906
1907 if (idstr)
1908 ND_PRINT((ndo," #%u type=%s id=%s ", pcount,
1909 STR_OR_ID(t.t_type, ikev2_t_type_map),
1910 idstr));
1911 else
1912 ND_PRINT((ndo," #%u type=%s id=%u ", pcount,
1913 STR_OR_ID(t.t_type, ikev2_t_type_map),
1914 t.t_id));
1915 cp = (const u_char *)(p + 1);
1916 ep2 = (const u_char *)p + item_len;
1917 while (cp < ep && cp < ep2) {
1918 if (map && nmap) {
1919 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1920 map, nmap);
1921 } else
1922 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1923 }
1924 if (ep < ep2)
1925 ND_PRINT((ndo,"..."));
1926 return cp;
1927 trunc:
1928 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1929 return NULL;
1930 }
1931
1932 static const u_char *
1933 ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
1934 const struct isakmp_gen *ext, u_int item_len _U_,
1935 const u_char *ep, uint32_t phase, uint32_t doi0,
1936 uint32_t proto0 _U_, int depth)
1937 {
1938 const struct ikev2_p *p;
1939 struct ikev2_p prop;
1940 const u_char *cp;
1941
1942 p = (const struct ikev2_p *)ext;
1943 ND_TCHECK(*p);
1944 UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
1945 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
1946
1947 ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
1948 prop.p_no, PROTOIDSTR(prop.prot_id),
1949 prop.num_t, ntohs(prop.h.len)));
1950 if (prop.spi_size) {
1951 ND_PRINT((ndo," spi="));
1952 if (!rawprint(ndo, (const uint8_t *)(p + 1), prop.spi_size))
1953 goto trunc;
1954 }
1955
1956 ext = (const struct isakmp_gen *)((const u_char *)(p + 1) + prop.spi_size);
1957 ND_TCHECK(*ext);
1958
1959 cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1960 prop.prot_id, depth);
1961
1962 return cp;
1963 trunc:
1964 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1965 return NULL;
1966 }
1967
1968 static const u_char *
1969 ikev2_sa_print(netdissect_options *ndo, u_char tpay,
1970 const struct isakmp_gen *ext1,
1971 u_int item_len _U_, const u_char *ep,
1972 uint32_t phase _U_, uint32_t doi _U_,
1973 uint32_t proto _U_, int depth)
1974 {
1975 struct isakmp_gen e;
1976 int osa_length, sa_length;
1977
1978 ND_TCHECK(*ext1);
1979 UNALIGNED_MEMCPY(&e, ext1, sizeof(e));
1980 ikev2_pay_print(ndo, "sa", e.critical);
1981
1982 osa_length= ntohs(e.len);
1983 sa_length = osa_length - 4;
1984 ND_PRINT((ndo," len=%d", sa_length));
1985
1986 ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
1987 ext1+1, ep,
1988 0, 0, 0, depth);
1989
1990 return (const u_char *)ext1 + osa_length;
1991 trunc:
1992 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1993 return NULL;
1994 }
1995
1996 static const u_char *
1997 ikev2_ke_print(netdissect_options *ndo, u_char tpay,
1998 const struct isakmp_gen *ext,
1999 u_int item_len _U_, const u_char *ep _U_,
2000 uint32_t phase _U_, uint32_t doi _U_,
2001 uint32_t proto _U_, int depth _U_)
2002 {
2003 struct ikev2_ke ke;
2004 const struct ikev2_ke *k;
2005
2006 k = (const struct ikev2_ke *)ext;
2007 ND_TCHECK(*ext);
2008 UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
2009 ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
2010
2011 ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
2012 STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
2013
2014 if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
2015 ND_PRINT((ndo," "));
2016 if (!rawprint(ndo, (const uint8_t *)(k + 1), ntohs(ke.h.len) - 8))
2017 goto trunc;
2018 }
2019 return (const u_char *)ext + ntohs(ke.h.len);
2020 trunc:
2021 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2022 return NULL;
2023 }
2024
2025 static const u_char *
2026 ikev2_ID_print(netdissect_options *ndo, u_char tpay,
2027 const struct isakmp_gen *ext,
2028 u_int item_len _U_, const u_char *ep _U_,
2029 uint32_t phase _U_, uint32_t doi _U_,
2030 uint32_t proto _U_, int depth _U_)
2031 {
2032 struct ikev2_id id;
2033 int id_len, idtype_len, i;
2034 unsigned int dumpascii, dumphex;
2035 const unsigned char *typedata;
2036
2037 ND_TCHECK(*ext);
2038 UNALIGNED_MEMCPY(&id, ext, sizeof(id));
2039 ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
2040
2041 id_len = ntohs(id.h.len);
2042
2043 ND_PRINT((ndo," len=%d", id_len - 4));
2044 if (2 < ndo->ndo_vflag && 4 < id_len) {
2045 ND_PRINT((ndo," "));
2046 if (!rawprint(ndo, (const uint8_t *)(ext + 1), id_len - 4))
2047 goto trunc;
2048 }
2049
2050 idtype_len =id_len - sizeof(struct ikev2_id);
2051 dumpascii = 0;
2052 dumphex = 0;
2053 typedata = (const unsigned char *)(ext)+sizeof(struct ikev2_id);
2054
2055 switch(id.type) {
2056 case ID_IPV4_ADDR:
2057 ND_PRINT((ndo, " ipv4:"));
2058 dumphex=1;
2059 break;
2060 case ID_FQDN:
2061 ND_PRINT((ndo, " fqdn:"));
2062 dumpascii=1;
2063 break;
2064 case ID_RFC822_ADDR:
2065 ND_PRINT((ndo, " rfc822:"));
2066 dumpascii=1;
2067 break;
2068 case ID_IPV6_ADDR:
2069 ND_PRINT((ndo, " ipv6:"));
2070 dumphex=1;
2071 break;
2072 case ID_DER_ASN1_DN:
2073 ND_PRINT((ndo, " dn:"));
2074 dumphex=1;
2075 break;
2076 case ID_DER_ASN1_GN:
2077 ND_PRINT((ndo, " gn:"));
2078 dumphex=1;
2079 break;
2080 case ID_KEY_ID:
2081 ND_PRINT((ndo, " keyid:"));
2082 dumphex=1;
2083 break;
2084 }
2085
2086 if(dumpascii) {
2087 ND_TCHECK2(*typedata, idtype_len);
2088 for(i=0; i<idtype_len; i++) {
2089 if(ND_ISPRINT(typedata[i])) {
2090 ND_PRINT((ndo, "%c", typedata[i]));
2091 } else {
2092 ND_PRINT((ndo, "."));
2093 }
2094 }
2095 }
2096 if(dumphex) {
2097 if (!rawprint(ndo, (const uint8_t *)typedata, idtype_len))
2098 goto trunc;
2099 }
2100
2101 return (const u_char *)ext + id_len;
2102 trunc:
2103 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2104 return NULL;
2105 }
2106
2107 static const u_char *
2108 ikev2_cert_print(netdissect_options *ndo, u_char tpay,
2109 const struct isakmp_gen *ext,
2110 u_int item_len _U_, const u_char *ep _U_,
2111 uint32_t phase _U_, uint32_t doi _U_,
2112 uint32_t proto _U_, int depth _U_)
2113 {
2114 return ikev2_gen_print(ndo, tpay, ext);
2115 }
2116
2117 static const u_char *
2118 ikev2_cr_print(netdissect_options *ndo, u_char tpay,
2119 const struct isakmp_gen *ext,
2120 u_int item_len _U_, const u_char *ep _U_,
2121 uint32_t phase _U_, uint32_t doi _U_,
2122 uint32_t proto _U_, int depth _U_)
2123 {
2124 return ikev2_gen_print(ndo, tpay, ext);
2125 }
2126
2127 static const u_char *
2128 ikev2_auth_print(netdissect_options *ndo, u_char tpay,
2129 const struct isakmp_gen *ext,
2130 u_int item_len _U_, const u_char *ep,
2131 uint32_t phase _U_, uint32_t doi _U_,
2132 uint32_t proto _U_, int depth _U_)
2133 {
2134 struct ikev2_auth a;
2135 const char *v2_auth[]={ "invalid", "rsasig",
2136 "shared-secret", "dsssig" };
2137 const u_char *authdata = (const u_char*)ext + sizeof(a);
2138 unsigned int len;
2139
2140 ND_TCHECK(*ext);
2141 UNALIGNED_MEMCPY(&a, ext, sizeof(a));
2142 ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
2143 len = ntohs(a.h.len);
2144
2145 ND_PRINT((ndo," len=%d method=%s", len-4,
2146 STR_OR_ID(a.auth_method, v2_auth)));
2147
2148 if (1 < ndo->ndo_vflag && 4 < len) {
2149 ND_PRINT((ndo," authdata=("));
2150 if (!rawprint(ndo, (const uint8_t *)authdata, len - sizeof(a)))
2151 goto trunc;
2152 ND_PRINT((ndo,") "));
2153 } else if(ndo->ndo_vflag && 4 < len) {
2154 if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
2155 }
2156
2157 return (const u_char *)ext + len;
2158 trunc:
2159 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2160 return NULL;
2161 }
2162
2163 static const u_char *
2164 ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
2165 const struct isakmp_gen *ext,
2166 u_int item_len _U_, const u_char *ep,
2167 uint32_t phase _U_, uint32_t doi _U_,
2168 uint32_t proto _U_, int depth _U_)
2169 {
2170 struct isakmp_gen e;
2171
2172 ND_TCHECK(*ext);
2173 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2174 ikev2_pay_print(ndo, "nonce", e.critical);
2175
2176 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
2177 if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
2178 ND_PRINT((ndo," nonce=("));
2179 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
2180 goto trunc;
2181 ND_PRINT((ndo,") "));
2182 } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) {
2183 if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
2184 }
2185
2186 return (const u_char *)ext + ntohs(e.len);
2187 trunc:
2188 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2189 return NULL;
2190 }
2191
2192 /* notify payloads */
2193 static const u_char *
2194 ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
2195 const struct isakmp_gen *ext,
2196 u_int item_len, const u_char *ep,
2197 uint32_t phase _U_, uint32_t doi _U_,
2198 uint32_t proto _U_, int depth _U_)
2199 {
2200 const struct ikev2_n *p;
2201 struct ikev2_n n;
2202 const u_char *cp;
2203 u_char showspi, showdata, showsomedata;
2204 const char *notify_name;
2205 uint32_t type;
2206
2207 p = (const struct ikev2_n *)ext;
2208 ND_TCHECK(*p);
2209 UNALIGNED_MEMCPY(&n, ext, sizeof(n));
2210 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
2211
2212 showspi = 1;
2213 showdata = 0;
2214 showsomedata=0;
2215 notify_name=NULL;
2216
2217 ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id)));
2218
2219 type = ntohs(n.type);
2220
2221 /* notify space is annoying sparse */
2222 switch(type) {
2223 case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
2224 notify_name = "unsupported_critical_payload";
2225 showspi = 0;
2226 break;
2227
2228 case IV2_NOTIFY_INVALID_IKE_SPI:
2229 notify_name = "invalid_ike_spi";
2230 showspi = 1;
2231 break;
2232
2233 case IV2_NOTIFY_INVALID_MAJOR_VERSION:
2234 notify_name = "invalid_major_version";
2235 showspi = 0;
2236 break;
2237
2238 case IV2_NOTIFY_INVALID_SYNTAX:
2239 notify_name = "invalid_syntax";
2240 showspi = 1;
2241 break;
2242
2243 case IV2_NOTIFY_INVALID_MESSAGE_ID:
2244 notify_name = "invalid_message_id";
2245 showspi = 1;
2246 break;
2247
2248 case IV2_NOTIFY_INVALID_SPI:
2249 notify_name = "invalid_spi";
2250 showspi = 1;
2251 break;
2252
2253 case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
2254 notify_name = "no_protocol_chosen";
2255 showspi = 1;
2256 break;
2257
2258 case IV2_NOTIFY_INVALID_KE_PAYLOAD:
2259 notify_name = "invalid_ke_payload";
2260 showspi = 1;
2261 break;
2262
2263 case IV2_NOTIFY_AUTHENTICATION_FAILED:
2264 notify_name = "authentication_failed";
2265 showspi = 1;
2266 break;
2267
2268 case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
2269 notify_name = "single_pair_required";
2270 showspi = 1;
2271 break;
2272
2273 case IV2_NOTIFY_NO_ADDITIONAL_SAS:
2274 notify_name = "no_additional_sas";
2275 showspi = 0;
2276 break;
2277
2278 case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
2279 notify_name = "internal_address_failure";
2280 showspi = 0;
2281 break;
2282
2283 case IV2_NOTIFY_FAILED_CP_REQUIRED:
2284 notify_name = "failed:cp_required";
2285 showspi = 0;
2286 break;
2287
2288 case IV2_NOTIFY_INVALID_SELECTORS:
2289 notify_name = "invalid_selectors";
2290 showspi = 0;
2291 break;
2292
2293 case IV2_NOTIFY_INITIAL_CONTACT:
2294 notify_name = "initial_contact";
2295 showspi = 0;
2296 break;
2297
2298 case IV2_NOTIFY_SET_WINDOW_SIZE:
2299 notify_name = "set_window_size";
2300 showspi = 0;
2301 break;
2302
2303 case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
2304 notify_name = "additional_ts_possible";
2305 showspi = 0;
2306 break;
2307
2308 case IV2_NOTIFY_IPCOMP_SUPPORTED:
2309 notify_name = "ipcomp_supported";
2310 showspi = 0;
2311 break;
2312
2313 case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
2314 notify_name = "nat_detection_source_ip";
2315 showspi = 1;
2316 break;
2317
2318 case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
2319 notify_name = "nat_detection_destination_ip";
2320 showspi = 1;
2321 break;
2322
2323 case IV2_NOTIFY_COOKIE:
2324 notify_name = "cookie";
2325 showspi = 1;
2326 showsomedata= 1;
2327 showdata= 0;
2328 break;
2329
2330 case IV2_NOTIFY_USE_TRANSPORT_MODE:
2331 notify_name = "use_transport_mode";
2332 showspi = 0;
2333 break;
2334
2335 case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
2336 notify_name = "http_cert_lookup_supported";
2337 showspi = 0;
2338 break;
2339
2340 case IV2_NOTIFY_REKEY_SA:
2341 notify_name = "rekey_sa";
2342 showspi = 1;
2343 break;
2344
2345 case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
2346 notify_name = "tfc_padding_not_supported";
2347 showspi = 0;
2348 break;
2349
2350 case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
2351 notify_name = "non_first_fragment_also";
2352 showspi = 0;
2353 break;
2354
2355 default:
2356 if (type < 8192) {
2357 notify_name="error";
2358 } else if(type < 16384) {
2359 notify_name="private-error";
2360 } else if(type < 40960) {
2361 notify_name="status";
2362 } else {
2363 notify_name="private-status";
2364 }
2365 }
2366
2367 if(notify_name) {
2368 ND_PRINT((ndo," type=%u(%s)", type, notify_name));
2369 }
2370
2371
2372 if (showspi && n.spi_size) {
2373 ND_PRINT((ndo," spi="));
2374 if (!rawprint(ndo, (const uint8_t *)(p + 1), n.spi_size))
2375 goto trunc;
2376 }
2377
2378 cp = (const u_char *)(p + 1) + n.spi_size;
2379
2380 if(3 < ndo->ndo_vflag) {
2381 showdata = 1;
2382 }
2383
2384 if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
2385 ND_PRINT((ndo," data=("));
2386 if (!rawprint(ndo, (const uint8_t *)(cp), ep - cp))
2387 goto trunc;
2388
2389 ND_PRINT((ndo,")"));
2390
2391 } else if(showsomedata && cp < ep) {
2392 if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
2393 }
2394
2395 return (const u_char *)ext + item_len;
2396 trunc:
2397 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
2398 return NULL;
2399 }
2400
2401 static const u_char *
2402 ikev2_d_print(netdissect_options *ndo, u_char tpay,
2403 const struct isakmp_gen *ext,
2404 u_int item_len _U_, const u_char *ep _U_,
2405 uint32_t phase _U_, uint32_t doi _U_,
2406 uint32_t proto _U_, int depth _U_)
2407 {
2408 return ikev2_gen_print(ndo, tpay, ext);
2409 }
2410
2411 static const u_char *
2412 ikev2_vid_print(netdissect_options *ndo, u_char tpay,
2413 const struct isakmp_gen *ext,
2414 u_int item_len _U_, const u_char *ep _U_,
2415 uint32_t phase _U_, uint32_t doi _U_,
2416 uint32_t proto _U_, int depth _U_)
2417 {
2418 struct isakmp_gen e;
2419 const u_char *vid;
2420 int i, len;
2421
2422 ND_TCHECK(*ext);
2423 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2424 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2425 ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
2426
2427 vid = (const u_char *)(ext+1);
2428 len = ntohs(e.len) - 4;
2429 ND_TCHECK2(*vid, len);
2430 for(i=0; i<len; i++) {
2431 if(ND_ISPRINT(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
2432 else ND_PRINT((ndo, "."));
2433 }
2434 if (2 < ndo->ndo_vflag && 4 < len) {
2435 ND_PRINT((ndo," "));
2436 if (!rawprint(ndo, (const uint8_t *)(ext + 1), ntohs(e.len) - 4))
2437 goto trunc;
2438 }
2439 return (const u_char *)ext + ntohs(e.len);
2440 trunc:
2441 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2442 return NULL;
2443 }
2444
2445 static const u_char *
2446 ikev2_TS_print(netdissect_options *ndo, u_char tpay,
2447 const struct isakmp_gen *ext,
2448 u_int item_len _U_, const u_char *ep _U_,
2449 uint32_t phase _U_, uint32_t doi _U_,
2450 uint32_t proto _U_, int depth _U_)
2451 {
2452 return ikev2_gen_print(ndo, tpay, ext);
2453 }
2454
2455 static const u_char *
2456 ikev2_e_print(netdissect_options *ndo,
2457 #ifndef HAVE_LIBCRYPTO
2458 _U_
2459 #endif
2460 struct isakmp *base,
2461 u_char tpay,
2462 const struct isakmp_gen *ext,
2463 u_int item_len _U_, const u_char *ep _U_,
2464 #ifndef HAVE_LIBCRYPTO
2465 _U_
2466 #endif
2467 uint32_t phase,
2468 #ifndef HAVE_LIBCRYPTO
2469 _U_
2470 #endif
2471 uint32_t doi,
2472 #ifndef HAVE_LIBCRYPTO
2473 _U_
2474 #endif
2475 uint32_t proto,
2476 #ifndef HAVE_LIBCRYPTO
2477 _U_
2478 #endif
2479 int depth)
2480 {
2481 struct isakmp_gen e;
2482 const u_char *dat;
2483 volatile int dlen;
2484
2485 ND_TCHECK(*ext);
2486 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2487 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2488
2489 dlen = ntohs(e.len)-4;
2490
2491 ND_PRINT((ndo," len=%d", dlen));
2492 if (2 < ndo->ndo_vflag && 4 < dlen) {
2493 ND_PRINT((ndo," "));
2494 if (!rawprint(ndo, (const uint8_t *)(ext + 1), dlen))
2495 goto trunc;
2496 }
2497
2498 dat = (const u_char *)(ext+1);
2499 ND_TCHECK2(*dat, dlen);
2500
2501 #ifdef HAVE_LIBCRYPTO
2502 /* try to decypt it! */
2503 if(esp_print_decrypt_buffer_by_ikev2(ndo,
2504 base->flags & ISAKMP_FLAG_I,
2505 base->i_ck, base->r_ck,
2506 dat, dat+dlen)) {
2507
2508 ext = (const struct isakmp_gen *)ndo->ndo_packetp;
2509
2510 /* got it decrypted, print stuff inside. */
2511 ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
2512 phase, doi, proto, depth+1);
2513 }
2514 #endif
2515
2516
2517 /* always return NULL, because E must be at end, and NP refers
2518 * to what was inside.
2519 */
2520 return NULL;
2521 trunc:
2522 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2523 return NULL;
2524 }
2525
2526 static const u_char *
2527 ikev2_cp_print(netdissect_options *ndo, u_char tpay,
2528 const struct isakmp_gen *ext,
2529 u_int item_len _U_, const u_char *ep _U_,
2530 uint32_t phase _U_, uint32_t doi _U_,
2531 uint32_t proto _U_, int depth _U_)
2532 {
2533 return ikev2_gen_print(ndo, tpay, ext);
2534 }
2535
2536 static const u_char *
2537 ikev2_eap_print(netdissect_options *ndo, u_char tpay,
2538 const struct isakmp_gen *ext,
2539 u_int item_len _U_, const u_char *ep _U_,
2540 uint32_t phase _U_, uint32_t doi _U_,
2541 uint32_t proto _U_, int depth _U_)
2542 {
2543 return ikev2_gen_print(ndo, tpay, ext);
2544 }
2545
2546 static const u_char *
2547 ike_sub0_print(netdissect_options *ndo,
2548 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2549
2550 uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2551 {
2552 const u_char *cp;
2553 struct isakmp_gen e;
2554 u_int item_len;
2555
2556 cp = (const u_char *)ext;
2557 ND_TCHECK(*ext);
2558 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2559
2560 /*
2561 * Since we can't have a payload length of less than 4 bytes,
2562 * we need to bail out here if the generic header is nonsensical
2563 * or truncated, otherwise we could loop forever processing
2564 * zero-length items or otherwise misdissect the packet.
2565 */
2566 item_len = ntohs(e.len);
2567 if (item_len <= 4)
2568 return NULL;
2569
2570 if (NPFUNC(np)) {
2571 /*
2572 * XXX - what if item_len is too short, or too long,
2573 * for this payload type?
2574 */
2575 cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
2576 } else {
2577 ND_PRINT((ndo,"%s", NPSTR(np)));
2578 cp += item_len;
2579 }
2580
2581 return cp;
2582 trunc:
2583 ND_PRINT((ndo," [|isakmp]"));
2584 return NULL;
2585 }
2586
2587 static const u_char *
2588 ikev1_sub_print(netdissect_options *ndo,
2589 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2590 uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2591 {
2592 const u_char *cp;
2593 int i;
2594 struct isakmp_gen e;
2595
2596 cp = (const u_char *)ext;
2597
2598 while (np) {
2599 ND_TCHECK(*ext);
2600
2601 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2602
2603 ND_TCHECK2(*ext, ntohs(e.len));
2604
2605 depth++;
2606 ND_PRINT((ndo,"\n"));
2607 for (i = 0; i < depth; i++)
2608 ND_PRINT((ndo," "));
2609 ND_PRINT((ndo,"("));
2610 cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
2611 ND_PRINT((ndo,")"));
2612 depth--;
2613
2614 if (cp == NULL) {
2615 /* Zero-length subitem */
2616 return NULL;
2617 }
2618
2619 np = e.np;
2620 ext = (const struct isakmp_gen *)cp;
2621 }
2622 return cp;
2623 trunc:
2624 ND_PRINT((ndo," [|%s]", NPSTR(np)));
2625 return NULL;
2626 }
2627
2628 static char *
2629 numstr(int x)
2630 {
2631 static char buf[20];
2632 snprintf(buf, sizeof(buf), "#%d", x);
2633 return buf;
2634 }
2635
2636 static void
2637 ikev1_print(netdissect_options *ndo,
2638 const u_char *bp, u_int length,
2639 const u_char *bp2, struct isakmp *base)
2640 {
2641 const struct isakmp *p;
2642 const u_char *ep;
2643 u_char np;
2644 int i;
2645 int phase;
2646
2647 p = (const struct isakmp *)bp;
2648 ep = ndo->ndo_snapend;
2649
2650 phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2651 if (phase == 1)
2652 ND_PRINT((ndo," phase %d", phase));
2653 else
2654 ND_PRINT((ndo," phase %d/others", phase));
2655
2656 i = cookie_find(&base->i_ck);
2657 if (i < 0) {
2658 if (iszero((const u_char *)&base->r_ck, sizeof(base->r_ck))) {
2659 /* the first packet */
2660 ND_PRINT((ndo," I"));
2661 if (bp2)
2662 cookie_record(&base->i_ck, bp2);
2663 } else
2664 ND_PRINT((ndo," ?"));
2665 } else {
2666 if (bp2 && cookie_isinitiator(i, bp2))
2667 ND_PRINT((ndo," I"));
2668 else if (bp2 && cookie_isresponder(i, bp2))
2669 ND_PRINT((ndo," R"));
2670 else
2671 ND_PRINT((ndo," ?"));
2672 }
2673
2674 ND_PRINT((ndo," %s", ETYPESTR(base->etype)));
2675 if (base->flags) {
2676 ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
2677 base->flags & ISAKMP_FLAG_C ? "C" : ""));
2678 }
2679
2680 if (ndo->ndo_vflag) {
2681 const struct isakmp_gen *ext;
2682
2683 ND_PRINT((ndo,":"));
2684
2685 /* regardless of phase... */
2686 if (base->flags & ISAKMP_FLAG_E) {
2687 /*
2688 * encrypted, nothing we can do right now.
2689 * we hope to decrypt the packet in the future...
2690 */
2691 ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np)));
2692 goto done;
2693 }
2694
2695 CHECKLEN(p + 1, base->np);
2696 np = base->np;
2697 ext = (const struct isakmp_gen *)(p + 1);
2698 ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
2699 }
2700
2701 done:
2702 if (ndo->ndo_vflag) {
2703 if (ntohl(base->len) != length) {
2704 ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
2705 (uint32_t)ntohl(base->len), length));
2706 }
2707 }
2708 }
2709
2710 static const u_char *
2711 ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
2712 u_char np, int pcount,
2713 const struct isakmp_gen *ext, const u_char *ep,
2714 uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2715 {
2716 const u_char *cp;
2717 struct isakmp_gen e;
2718 u_int item_len;
2719
2720 cp = (const u_char *)ext;
2721 ND_TCHECK(*ext);
2722 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2723
2724 /*
2725 * Since we can't have a payload length of less than 4 bytes,
2726 * we need to bail out here if the generic header is nonsensical
2727 * or truncated, otherwise we could loop forever processing
2728 * zero-length items or otherwise misdissect the packet.
2729 */
2730 item_len = ntohs(e.len);
2731 if (item_len <= 4)
2732 return NULL;
2733
2734 if(np == ISAKMP_NPTYPE_P) {
2735 cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
2736 ep, phase, doi, proto, depth);
2737 } else if(np == ISAKMP_NPTYPE_T) {
2738 cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
2739 ep, phase, doi, proto, depth);
2740 } else if(np == ISAKMP_NPTYPE_v2E) {
2741 cp = ikev2_e_print(ndo, base, np, ext, item_len,
2742 ep, phase, doi, proto, depth);
2743 } else if (NPFUNC(np)) {
2744 /*
2745 * XXX - what if item_len is too short, or too long,
2746 * for this payload type?
2747 */
2748 cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len,
2749 ep, phase, doi, proto, depth);
2750 } else {
2751 ND_PRINT((ndo,"%s", NPSTR(np)));
2752 cp += item_len;
2753 }
2754
2755 return cp;
2756 trunc:
2757 ND_PRINT((ndo," [|isakmp]"));
2758 return NULL;
2759 }
2760
2761 static const u_char *
2762 ikev2_sub_print(netdissect_options *ndo,
2763 struct isakmp *base,
2764 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2765 uint32_t phase, uint32_t doi, uint32_t proto, int depth)
2766 {
2767 const u_char *cp;
2768 int i;
2769 int pcount;
2770 struct isakmp_gen e;
2771
2772 cp = (const u_char *)ext;
2773 pcount = 0;
2774 while (np) {
2775 pcount++;
2776 ND_TCHECK(*ext);
2777
2778 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2779
2780 ND_TCHECK2(*ext, ntohs(e.len));
2781
2782 depth++;
2783 ND_PRINT((ndo,"\n"));
2784 for (i = 0; i < depth; i++)
2785 ND_PRINT((ndo," "));
2786 ND_PRINT((ndo,"("));
2787 cp = ikev2_sub0_print(ndo, base, np, pcount,
2788 ext, ep, phase, doi, proto, depth);
2789 ND_PRINT((ndo,")"));
2790 depth--;
2791
2792 if (cp == NULL) {
2793 /* Zero-length subitem */
2794 return NULL;
2795 }
2796
2797 np = e.np;
2798 ext = (const struct isakmp_gen *)cp;
2799 }
2800 return cp;
2801 trunc:
2802 ND_PRINT((ndo," [|%s]", NPSTR(np)));
2803 return NULL;
2804 }
2805
2806 static void
2807 ikev2_print(netdissect_options *ndo,
2808 const u_char *bp, u_int length,
2809 const u_char *bp2 _U_, struct isakmp *base)
2810 {
2811 const struct isakmp *p;
2812 const u_char *ep;
2813 u_char np;
2814 int phase;
2815
2816 p = (const struct isakmp *)bp;
2817 ep = ndo->ndo_snapend;
2818
2819 phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2820 if (phase == 1)
2821 ND_PRINT((ndo, " parent_sa"));
2822 else
2823 ND_PRINT((ndo, " child_sa "));
2824
2825 ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
2826 if (base->flags) {
2827 ND_PRINT((ndo, "[%s%s%s]",
2828 base->flags & ISAKMP_FLAG_I ? "I" : "",
2829 base->flags & ISAKMP_FLAG_V ? "V" : "",
2830 base->flags & ISAKMP_FLAG_R ? "R" : ""));
2831 }
2832
2833 if (ndo->ndo_vflag) {
2834 const struct isakmp_gen *ext;
2835
2836 ND_PRINT((ndo, ":"));
2837
2838 /* regardless of phase... */
2839 if (base->flags & ISAKMP_FLAG_E) {
2840 /*
2841 * encrypted, nothing we can do right now.
2842 * we hope to decrypt the packet in the future...
2843 */
2844 ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np)));
2845 goto done;
2846 }
2847
2848 CHECKLEN(p + 1, base->np)
2849
2850 np = base->np;
2851 ext = (const struct isakmp_gen *)(p + 1);
2852 ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
2853 }
2854
2855 done:
2856 if (ndo->ndo_vflag) {
2857 if (ntohl(base->len) != length) {
2858 ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)",
2859 (uint32_t)ntohl(base->len), length));
2860 }
2861 }
2862 }
2863
2864 void
2865 isakmp_print(netdissect_options *ndo,
2866 const u_char *bp, u_int length,
2867 const u_char *bp2)
2868 {
2869 const struct isakmp *p;
2870 struct isakmp base;
2871 const u_char *ep;
2872 int major, minor;
2873
2874 #ifdef HAVE_LIBCRYPTO
2875 /* initialize SAs */
2876 if (ndo->ndo_sa_list_head == NULL) {
2877 if (ndo->ndo_espsecret)
2878 esp_print_decodesecret(ndo);
2879 }
2880 #endif
2881
2882 p = (const struct isakmp *)bp;
2883 ep = ndo->ndo_snapend;
2884
2885 if ((const struct isakmp *)ep < p + 1) {
2886 ND_PRINT((ndo,"[|isakmp]"));
2887 return;
2888 }
2889
2890 UNALIGNED_MEMCPY(&base, p, sizeof(base));
2891
2892 ND_PRINT((ndo,"isakmp"));
2893 major = (base.vers & ISAKMP_VERS_MAJOR)
2894 >> ISAKMP_VERS_MAJOR_SHIFT;
2895 minor = (base.vers & ISAKMP_VERS_MINOR)
2896 >> ISAKMP_VERS_MINOR_SHIFT;
2897
2898 if (ndo->ndo_vflag) {
2899 ND_PRINT((ndo," %d.%d", major, minor));
2900 }
2901
2902 if (ndo->ndo_vflag) {
2903 ND_PRINT((ndo," msgid "));
2904 hexprint(ndo, (const uint8_t *)&base.msgid, sizeof(base.msgid));
2905 }
2906
2907 if (1 < ndo->ndo_vflag) {
2908 ND_PRINT((ndo," cookie "));
2909 hexprint(ndo, (const uint8_t *)&base.i_ck, sizeof(base.i_ck));
2910 ND_PRINT((ndo,"->"));
2911 hexprint(ndo, (const uint8_t *)&base.r_ck, sizeof(base.r_ck));
2912 }
2913 ND_PRINT((ndo,":"));
2914
2915 switch(major) {
2916 case IKEv1_MAJOR_VERSION:
2917 ikev1_print(ndo, bp, length, bp2, &base);
2918 break;
2919
2920 case IKEv2_MAJOR_VERSION:
2921 ikev2_print(ndo, bp, length, bp2, &base);
2922 break;
2923 }
2924 }
2925
2926 void
2927 isakmp_rfc3948_print(netdissect_options *ndo,
2928 const u_char *bp, u_int length,
2929 const u_char *bp2)
2930 {
2931
2932 if(length == 1 && bp[0]==0xff) {
2933 ND_PRINT((ndo, "isakmp-nat-keep-alive"));
2934 return;
2935 }
2936
2937 if(length < 4) {
2938 goto trunc;
2939 }
2940
2941 /*
2942 * see if this is an IKE packet
2943 */
2944 if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
2945 ND_PRINT((ndo, "NONESP-encap: "));
2946 isakmp_print(ndo, bp+4, length-4, bp2);
2947 return;
2948 }
2949
2950 /* must be an ESP packet */
2951 {
2952 int nh, enh, padlen;
2953 int advance;
2954
2955 ND_PRINT((ndo, "UDP-encap: "));
2956
2957 advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
2958 if(advance <= 0)
2959 return;
2960
2961 bp += advance;
2962 length -= advance + padlen;
2963 nh = enh & 0xff;
2964
2965 ip_print_inner(ndo, bp, length, nh, bp2);
2966 return;
2967 }
2968
2969 trunc:
2970 ND_PRINT((ndo,"[|isakmp]"));
2971 return;
2972 }
2973
2974 /*
2975 * Local Variables:
2976 * c-style: whitesmith
2977 * c-basic-offset: 8
2978 * End:
2979 */
2980
2981
2982
2983