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