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