Merge from vendor branch LIBPCAP:
[dragonfly.git] / contrib / tcpdump-3.8.3 / print-isakmp.c
blobd5caa739db45bded185e5c0883b6410f00ac821a
1 /*
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
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.
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.
31 #ifndef lint
32 static const char rcsid[] _U_ =
33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.36.2.11 2004/03/24 01:32:42 guy Exp $ (LBL)";
34 #endif
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
40 #include <tcpdump-stdinc.h>
42 #include <string.h>
44 #include <stdio.h>
46 #include "isakmp.h"
47 #include "ipsec_doi.h"
48 #include "oakley.h"
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h" /* must come after interface.h */
53 #include "ip.h"
54 #ifdef INET6
55 #include "ip6.h"
56 #endif
58 #ifndef HAVE_SOCKADDR_STORAGE
59 #define sockaddr_storage sockaddr
60 #endif
62 static const u_char *isakmp_sa_print(const struct isakmp_gen *,
63 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
64 static const u_char *isakmp_p_print(const struct isakmp_gen *,
65 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
66 static const u_char *isakmp_t_print(const struct isakmp_gen *,
67 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
68 static const u_char *isakmp_ke_print(const struct isakmp_gen *,
69 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
70 static const u_char *isakmp_id_print(const struct isakmp_gen *,
71 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
72 static const u_char *isakmp_cert_print(const struct isakmp_gen *,
73 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
74 static const u_char *isakmp_cr_print(const struct isakmp_gen *,
75 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
76 static const u_char *isakmp_sig_print(const struct isakmp_gen *,
77 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
78 static const u_char *isakmp_hash_print(const struct isakmp_gen *,
79 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
80 static const u_char *isakmp_nonce_print(const struct isakmp_gen *,
81 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
82 static const u_char *isakmp_n_print(const struct isakmp_gen *,
83 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
84 static const u_char *isakmp_d_print(const struct isakmp_gen *,
85 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
86 static const u_char *isakmp_vid_print(const struct isakmp_gen *,
87 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
88 static const u_char *isakmp_sub0_print(u_char, const struct isakmp_gen *,
89 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
90 static const u_char *isakmp_sub_print(u_char, const struct isakmp_gen *,
91 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
92 static char *numstr(int);
93 static void safememcpy(void *, const void *, size_t);
95 #define MAXINITIATORS 20
96 int ninitiator = 0;
97 struct {
98 cookie_t initiator;
99 struct sockaddr_storage iaddr;
100 struct sockaddr_storage raddr;
101 } cookiecache[MAXINITIATORS];
103 /* protocol id */
104 static const char *protoidstr[] = {
105 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
108 /* isakmp->np */
109 static const char *npstr[] = {
110 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
111 "sig", "nonce", "n", "d", "vid"
114 /* isakmp->np */
115 static const u_char *(*npfunc[])(const struct isakmp_gen *, u_int,
116 const u_char *, u_int32_t, u_int32_t, u_int32_t, int) = {
117 NULL,
118 isakmp_sa_print,
119 isakmp_p_print,
120 isakmp_t_print,
121 isakmp_ke_print,
122 isakmp_id_print,
123 isakmp_cert_print,
124 isakmp_cr_print,
125 isakmp_hash_print,
126 isakmp_sig_print,
127 isakmp_nonce_print,
128 isakmp_n_print,
129 isakmp_d_print,
130 isakmp_vid_print,
133 /* isakmp->etype */
134 static const char *etypestr[] = {
135 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL,
136 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
137 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
138 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
139 "oakley-quick", "oakley-newgroup",
142 #define STR_OR_ID(x, tab) \
143 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
144 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
145 #define NPSTR(x) STR_OR_ID(x, npstr)
146 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
148 #define NPFUNC(x) \
149 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
150 ? npfunc[(x)] : NULL)
152 static int
153 iszero(u_char *p, size_t l)
155 while (l--) {
156 if (*p++)
157 return 0;
159 return 1;
162 /* find cookie from initiator cache */
163 static int
164 cookie_find(cookie_t *in)
166 int i;
168 for (i = 0; i < MAXINITIATORS; i++) {
169 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
170 return i;
173 return -1;
176 /* record initiator */
177 static void
178 cookie_record(cookie_t *in, const u_char *bp2)
180 int i;
181 struct ip *ip;
182 struct sockaddr_in *sin;
183 #ifdef INET6
184 struct ip6_hdr *ip6;
185 struct sockaddr_in6 *sin6;
186 #endif
188 i = cookie_find(in);
189 if (0 <= i) {
190 ninitiator = (i + 1) % MAXINITIATORS;
191 return;
194 ip = (struct ip *)bp2;
195 switch (IP_V(ip)) {
196 case 4:
197 memset(&cookiecache[ninitiator].iaddr, 0,
198 sizeof(cookiecache[ninitiator].iaddr));
199 memset(&cookiecache[ninitiator].raddr, 0,
200 sizeof(cookiecache[ninitiator].raddr));
202 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
203 #ifdef HAVE_SOCKADDR_SA_LEN
204 sin->sin_len = sizeof(struct sockaddr_in);
205 #endif
206 sin->sin_family = AF_INET;
207 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
208 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
209 #ifdef HAVE_SOCKADDR_SA_LEN
210 sin->sin_len = sizeof(struct sockaddr_in);
211 #endif
212 sin->sin_family = AF_INET;
213 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
214 break;
215 #ifdef INET6
216 case 6:
217 memset(&cookiecache[ninitiator].iaddr, 0,
218 sizeof(cookiecache[ninitiator].iaddr));
219 memset(&cookiecache[ninitiator].raddr, 0,
220 sizeof(cookiecache[ninitiator].raddr));
222 ip6 = (struct ip6_hdr *)bp2;
223 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
224 #ifdef HAVE_SOCKADDR_SA_LEN
225 sin6->sin6_len = sizeof(struct sockaddr_in6);
226 #endif
227 sin6->sin6_family = AF_INET6;
228 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
229 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
230 #ifdef HAVE_SOCKADDR_SA_LEN
231 sin6->sin6_len = sizeof(struct sockaddr_in6);
232 #endif
233 sin6->sin6_family = AF_INET6;
234 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
235 break;
236 #endif
237 default:
238 return;
240 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
241 ninitiator = (ninitiator + 1) % MAXINITIATORS;
244 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
245 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
246 static int
247 cookie_sidecheck(int i, const u_char *bp2, int initiator)
249 struct sockaddr_storage ss;
250 struct sockaddr *sa;
251 struct ip *ip;
252 struct sockaddr_in *sin;
253 #ifdef INET6
254 struct ip6_hdr *ip6;
255 struct sockaddr_in6 *sin6;
256 #endif
257 int salen;
259 memset(&ss, 0, sizeof(ss));
260 ip = (struct ip *)bp2;
261 switch (IP_V(ip)) {
262 case 4:
263 sin = (struct sockaddr_in *)&ss;
264 #ifdef HAVE_SOCKADDR_SA_LEN
265 sin->sin_len = sizeof(struct sockaddr_in);
266 #endif
267 sin->sin_family = AF_INET;
268 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
269 break;
270 #ifdef INET6
271 case 6:
272 ip6 = (struct ip6_hdr *)bp2;
273 sin6 = (struct sockaddr_in6 *)&ss;
274 #ifdef HAVE_SOCKADDR_SA_LEN
275 sin6->sin6_len = sizeof(struct sockaddr_in6);
276 #endif
277 sin6->sin6_family = AF_INET6;
278 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
279 break;
280 #endif
281 default:
282 return 0;
285 sa = (struct sockaddr *)&ss;
286 if (initiator) {
287 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
288 return 0;
289 #ifdef HAVE_SOCKADDR_SA_LEN
290 salen = sa->sa_len;
291 #else
292 #ifdef INET6
293 if (sa->sa_family == AF_INET6)
294 salen = sizeof(struct sockaddr_in6);
295 else
296 salen = sizeof(struct sockaddr);
297 #else
298 salen = sizeof(struct sockaddr);
299 #endif
300 #endif
301 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
302 return 1;
303 } else {
304 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
305 return 0;
306 #ifdef HAVE_SOCKADDR_SA_LEN
307 salen = sa->sa_len;
308 #else
309 #ifdef INET6
310 if (sa->sa_family == AF_INET6)
311 salen = sizeof(struct sockaddr_in6);
312 else
313 salen = sizeof(struct sockaddr);
314 #else
315 salen = sizeof(struct sockaddr);
316 #endif
317 #endif
318 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
319 return 1;
321 return 0;
324 static int
325 rawprint(caddr_t loc, size_t len)
327 static u_char *p;
328 size_t i;
330 TCHECK2(*loc, len);
332 p = (u_char *)loc;
333 for (i = 0; i < len; i++)
334 printf("%02x", p[i] & 0xff);
335 return 1;
336 trunc:
337 return 0;
340 struct attrmap {
341 const char *type;
342 u_int nvalue;
343 const char *value[30]; /*XXX*/
346 static const u_char *
347 isakmp_attrmap_print(const u_char *p, const u_char *ep,
348 const struct attrmap *map, size_t nmap)
350 u_int16_t *q;
351 int totlen;
352 u_int32_t t, v;
354 q = (u_int16_t *)p;
355 if (p[0] & 0x80)
356 totlen = 4;
357 else
358 totlen = 4 + EXTRACT_16BITS(&q[1]);
359 if (ep < p + totlen) {
360 printf("[|attr]");
361 return ep + 1;
364 printf("(");
365 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
366 if (map && t < nmap && map[t].type)
367 printf("type=%s ", map[t].type);
368 else
369 printf("type=#%d ", t);
370 if (p[0] & 0x80) {
371 printf("value=");
372 v = EXTRACT_16BITS(&q[1]);
373 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
374 printf("%s", map[t].value[v]);
375 else
376 rawprint((caddr_t)&q[1], 2);
377 } else {
378 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
379 rawprint((caddr_t)&p[4], EXTRACT_16BITS(&q[1]));
381 printf(")");
382 return p + totlen;
385 static const u_char *
386 isakmp_attr_print(const u_char *p, const u_char *ep)
388 u_int16_t *q;
389 int totlen;
390 u_int32_t t;
392 q = (u_int16_t *)p;
393 if (p[0] & 0x80)
394 totlen = 4;
395 else
396 totlen = 4 + EXTRACT_16BITS(&q[1]);
397 if (ep < p + totlen) {
398 printf("[|attr]");
399 return ep + 1;
402 printf("(");
403 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
404 printf("type=#%d ", t);
405 if (p[0] & 0x80) {
406 printf("value=");
407 t = q[1];
408 rawprint((caddr_t)&q[1], 2);
409 } else {
410 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
411 rawprint((caddr_t)&p[2], EXTRACT_16BITS(&q[1]));
413 printf(")");
414 return p + totlen;
417 static const u_char *
418 isakmp_sa_print(const struct isakmp_gen *ext, u_int item_len,
419 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
420 u_int32_t proto0, int depth)
422 const struct isakmp_pl_sa *p;
423 struct isakmp_pl_sa sa;
424 const u_int32_t *q;
425 u_int32_t doi, sit, ident;
426 const u_char *cp, *np;
427 int t;
429 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA));
431 p = (struct isakmp_pl_sa *)ext;
432 TCHECK(*p);
433 safememcpy(&sa, ext, sizeof(sa));
434 doi = ntohl(sa.doi);
435 sit = ntohl(sa.sit);
436 if (doi != 1) {
437 printf(" doi=%d", doi);
438 printf(" situation=%u", (u_int32_t)ntohl(sa.sit));
439 return (u_char *)(p + 1);
442 printf(" doi=ipsec");
443 q = (u_int32_t *)&sa.sit;
444 printf(" situation=");
445 t = 0;
446 if (sit & 0x01) {
447 printf("identity");
448 t++;
450 if (sit & 0x02) {
451 printf("%ssecrecy", t ? "+" : "");
452 t++;
454 if (sit & 0x04)
455 printf("%sintegrity", t ? "+" : "");
457 np = (u_char *)ext + sizeof(sa);
458 if (sit != 0x01) {
459 TCHECK2(*(ext + 1), sizeof(ident));
460 safememcpy(&ident, ext + 1, sizeof(ident));
461 printf(" ident=%u", (u_int32_t)ntohl(ident));
462 np += sizeof(ident);
465 ext = (struct isakmp_gen *)np;
466 TCHECK(*ext);
468 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
469 depth);
471 return cp;
472 trunc:
473 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA));
474 return NULL;
477 static const u_char *
478 isakmp_p_print(const struct isakmp_gen *ext, u_int item_len,
479 const u_char *ep, u_int32_t phase, u_int32_t doi0,
480 u_int32_t proto0 _U_, int depth)
482 const struct isakmp_pl_p *p;
483 struct isakmp_pl_p prop;
484 const u_char *cp;
486 printf("%s:", NPSTR(ISAKMP_NPTYPE_P));
488 p = (struct isakmp_pl_p *)ext;
489 TCHECK(*p);
490 safememcpy(&prop, ext, sizeof(prop));
491 printf(" #%d protoid=%s transform=%d",
492 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t);
493 if (prop.spi_size) {
494 printf(" spi=");
495 if (!rawprint((caddr_t)(p + 1), prop.spi_size))
496 goto trunc;
499 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
500 TCHECK(*ext);
502 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
503 prop.prot_id, depth);
505 return cp;
506 trunc:
507 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P));
508 return NULL;
511 static const char *isakmp_p_map[] = {
512 NULL, "ike",
515 static const char *ah_p_map[] = {
516 NULL, "(reserved)", "md5", "sha", "1des",
517 "sha2-256", "sha2-384", "sha2-512",
520 static const char *esp_p_map[] = {
521 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
522 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
525 static const char *ipcomp_p_map[] = {
526 NULL, "oui", "deflate", "lzs",
529 const struct attrmap ipsec_t_map[] = {
530 { NULL, 0, { NULL } },
531 { "lifetype", 3, { NULL, "sec", "kb", }, },
532 { "life", 0, { NULL } },
533 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
534 "EC2N 2^185", }, },
535 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
536 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
537 { "keylen", 0, { NULL } },
538 { "rounds", 0, { NULL } },
539 { "dictsize", 0, { NULL } },
540 { "privalg", 0, { NULL } },
543 const struct attrmap oakley_t_map[] = {
544 { NULL, 0, { NULL } },
545 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
546 "3des", "cast", "aes", }, },
547 { "hash", 7, { NULL, "md5", "sha1", "tiger",
548 "sha2-256", "sha2-384", "sha2-512", }, },
549 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
550 "rsa enc revised", }, },
551 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
552 "EC2N 2^185", }, },
553 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
554 { "group prime", 0, { NULL } },
555 { "group gen1", 0, { NULL } },
556 { "group gen2", 0, { NULL } },
557 { "group curve A", 0, { NULL } },
558 { "group curve B", 0, { NULL } },
559 { "lifetype", 3, { NULL, "sec", "kb", }, },
560 { "lifeduration", 0, { NULL } },
561 { "prf", 0, { NULL } },
562 { "keylen", 0, { NULL } },
563 { "field", 0, { NULL } },
564 { "order", 0, { NULL } },
567 static const u_char *
568 isakmp_t_print(const struct isakmp_gen *ext, u_int item_len,
569 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
570 u_int32_t proto, int depth _U_)
572 const struct isakmp_pl_t *p;
573 struct isakmp_pl_t t;
574 const u_char *cp;
575 const char *idstr;
576 const struct attrmap *map;
577 size_t nmap;
578 const u_char *ep2;
580 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
582 p = (struct isakmp_pl_t *)ext;
583 TCHECK(*p);
584 safememcpy(&t, ext, sizeof(t));
586 switch (proto) {
587 case 1:
588 idstr = STR_OR_ID(t.t_id, isakmp_p_map);
589 map = oakley_t_map;
590 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
591 break;
592 case 2:
593 idstr = STR_OR_ID(t.t_id, ah_p_map);
594 map = ipsec_t_map;
595 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
596 break;
597 case 3:
598 idstr = STR_OR_ID(t.t_id, esp_p_map);
599 map = ipsec_t_map;
600 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
601 break;
602 case 4:
603 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
604 map = ipsec_t_map;
605 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
606 break;
607 default:
608 idstr = NULL;
609 map = NULL;
610 nmap = 0;
611 break;
614 if (idstr)
615 printf(" #%d id=%s ", t.t_no, idstr);
616 else
617 printf(" #%d id=%d ", t.t_no, t.t_id);
618 cp = (u_char *)(p + 1);
619 ep2 = (u_char *)p + item_len;
620 while (cp < ep && cp < ep2) {
621 if (map && nmap) {
622 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
623 map, nmap);
624 } else
625 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
627 if (ep < ep2)
628 printf("...");
629 return cp;
630 trunc:
631 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T));
632 return NULL;
635 static const u_char *
636 isakmp_ke_print(const struct isakmp_gen *ext, u_int item_len,
637 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
638 u_int32_t proto _U_, int depth _U_)
640 struct isakmp_gen e;
642 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
644 TCHECK(*ext);
645 safememcpy(&e, ext, sizeof(e));
646 printf(" key len=%d", ntohs(e.len) - 4);
647 if (2 < vflag && 4 < ntohs(e.len)) {
648 printf(" ");
649 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
650 goto trunc;
652 return (u_char *)ext + ntohs(e.len);
653 trunc:
654 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE));
655 return NULL;
658 static const u_char *
659 isakmp_id_print(const struct isakmp_gen *ext, u_int item_len,
660 const u_char *ep, u_int32_t phase, u_int32_t doi _U_,
661 u_int32_t proto _U_, int depth _U_)
663 #define USE_IPSECDOI_IN_PHASE1 1
664 const struct isakmp_pl_id *p;
665 struct isakmp_pl_id id;
666 static const char *idtypestr[] = {
667 "IPv4", "IPv4net", "IPv6", "IPv6net",
669 static const char *ipsecidtypestr[] = {
670 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
671 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
672 "keyid",
674 int len;
675 const u_char *data;
677 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
679 p = (struct isakmp_pl_id *)ext;
680 TCHECK(*p);
681 safememcpy(&id, ext, sizeof(id));
682 if (sizeof(*p) < item_len) {
683 data = (u_char *)(p + 1);
684 len = item_len - sizeof(*p);
685 } else {
686 data = NULL;
687 len = 0;
690 #if 0 /*debug*/
691 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
692 #endif
693 switch (phase) {
694 #ifndef USE_IPSECDOI_IN_PHASE1
695 case 1:
696 #endif
697 default:
698 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr));
699 printf(" doi_data=%u",
700 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff));
701 break;
703 #ifdef USE_IPSECDOI_IN_PHASE1
704 case 1:
705 #endif
706 case 2:
708 const struct ipsecdoi_id *p;
709 struct ipsecdoi_id id;
710 struct protoent *pe;
712 p = (struct ipsecdoi_id *)ext;
713 TCHECK(*p);
714 safememcpy(&id, ext, sizeof(id));
715 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr));
716 if (id.proto_id) {
717 #ifndef WIN32
718 setprotoent(1);
719 #endif /* WIN32 */
720 pe = getprotobynumber(id.proto_id);
721 if (pe)
722 printf(" protoid=%s", pe->p_name);
723 #ifndef WIN32
724 endprotoent();
725 #endif /* WIN32 */
726 } else {
727 /* it DOES NOT mean IPPROTO_IP! */
728 printf(" protoid=%s", "0");
730 printf(" port=%d", ntohs(id.port));
731 if (!len)
732 break;
733 if (data == NULL)
734 goto trunc;
735 TCHECK2(*data, len);
736 switch (id.type) {
737 case IPSECDOI_ID_IPV4_ADDR:
738 if (len < 4)
739 printf(" len=%d [bad: < 4]", len);
740 else
741 printf(" len=%d %s", len, ipaddr_string(data));
742 len = 0;
743 break;
744 case IPSECDOI_ID_FQDN:
745 case IPSECDOI_ID_USER_FQDN:
747 int i;
748 printf(" len=%d ", len);
749 for (i = 0; i < len; i++)
750 safeputchar(data[i]);
751 len = 0;
752 break;
754 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
756 const u_char *mask;
757 if (len < 8)
758 printf(" len=%d [bad: < 8]", len);
759 else {
760 mask = data + sizeof(struct in_addr);
761 printf(" len=%d %s/%u.%u.%u.%u", len,
762 ipaddr_string(data),
763 mask[0], mask[1], mask[2], mask[3]);
765 len = 0;
766 break;
768 #ifdef INET6
769 case IPSECDOI_ID_IPV6_ADDR:
770 if (len < 16)
771 printf(" len=%d [bad: < 16]", len);
772 else
773 printf(" len=%d %s", len, ip6addr_string(data));
774 len = 0;
775 break;
776 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
778 const u_int32_t *mask;
779 if (len < 20)
780 printf(" len=%d [bad: < 20]", len);
781 else {
782 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
783 /*XXX*/
784 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
785 ip6addr_string(data),
786 mask[0], mask[1], mask[2], mask[3]);
788 len = 0;
789 break;
791 #endif /*INET6*/
792 case IPSECDOI_ID_IPV4_ADDR_RANGE:
793 if (len < 8)
794 printf(" len=%d [bad: < 8]", len);
795 else {
796 printf(" len=%d %s-%s", len,
797 ipaddr_string(data),
798 ipaddr_string(data + sizeof(struct in_addr)));
800 len = 0;
801 break;
802 #ifdef INET6
803 case IPSECDOI_ID_IPV6_ADDR_RANGE:
804 if (len < 32)
805 printf(" len=%d [bad: < 32]", len);
806 else {
807 printf(" len=%d %s-%s", len,
808 ip6addr_string(data),
809 ip6addr_string(data + sizeof(struct in6_addr)));
811 len = 0;
812 break;
813 #endif /*INET6*/
814 case IPSECDOI_ID_DER_ASN1_DN:
815 case IPSECDOI_ID_DER_ASN1_GN:
816 case IPSECDOI_ID_KEY_ID:
817 break;
819 break;
822 if (data && len) {
823 printf(" len=%d", len);
824 if (2 < vflag) {
825 printf(" ");
826 if (!rawprint((caddr_t)data, len))
827 goto trunc;
830 return (u_char *)ext + item_len;
831 trunc:
832 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID));
833 return NULL;
836 static const u_char *
837 isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len,
838 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
839 u_int32_t proto0 _U_, int depth _U_)
841 const struct isakmp_pl_cert *p;
842 struct isakmp_pl_cert cert;
843 static const char *certstr[] = {
844 "none", "pkcs7", "pgp", "dns",
845 "x509sign", "x509ke", "kerberos", "crl",
846 "arl", "spki", "x509attr",
849 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
851 p = (struct isakmp_pl_cert *)ext;
852 TCHECK(*p);
853 safememcpy(&cert, ext, sizeof(cert));
854 printf(" len=%d", item_len - 4);
855 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
856 if (2 < vflag && 4 < item_len) {
857 printf(" ");
858 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
859 goto trunc;
861 return (u_char *)ext + item_len;
862 trunc:
863 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT));
864 return NULL;
867 static const u_char *
868 isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len,
869 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
870 u_int32_t proto0 _U_, int depth _U_)
872 const struct isakmp_pl_cert *p;
873 struct isakmp_pl_cert cert;
874 static const char *certstr[] = {
875 "none", "pkcs7", "pgp", "dns",
876 "x509sign", "x509ke", "kerberos", "crl",
877 "arl", "spki", "x509attr",
880 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
882 p = (struct isakmp_pl_cert *)ext;
883 TCHECK(*p);
884 safememcpy(&cert, ext, sizeof(cert));
885 printf(" len=%d", item_len - 4);
886 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
887 if (2 < vflag && 4 < item_len) {
888 printf(" ");
889 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
890 goto trunc;
892 return (u_char *)ext + item_len;
893 trunc:
894 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR));
895 return NULL;
898 static const u_char *
899 isakmp_hash_print(const struct isakmp_gen *ext, u_int item_len,
900 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
901 u_int32_t proto _U_, int depth _U_)
903 struct isakmp_gen e;
905 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
907 TCHECK(*ext);
908 safememcpy(&e, ext, sizeof(e));
909 printf(" len=%d", ntohs(e.len) - 4);
910 if (2 < vflag && 4 < ntohs(e.len)) {
911 printf(" ");
912 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
913 goto trunc;
915 return (u_char *)ext + ntohs(e.len);
916 trunc:
917 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH));
918 return NULL;
921 static const u_char *
922 isakmp_sig_print(const struct isakmp_gen *ext, u_int item_len,
923 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
924 u_int32_t proto _U_, int depth _U_)
926 struct isakmp_gen e;
928 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
930 TCHECK(*ext);
931 safememcpy(&e, ext, sizeof(e));
932 printf(" len=%d", ntohs(e.len) - 4);
933 if (2 < vflag && 4 < ntohs(e.len)) {
934 printf(" ");
935 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
936 goto trunc;
938 return (u_char *)ext + ntohs(e.len);
939 trunc:
940 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG));
941 return NULL;
944 static const u_char *
945 isakmp_nonce_print(const struct isakmp_gen *ext, u_int item_len,
946 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
947 u_int32_t proto _U_, int depth _U_)
949 struct isakmp_gen e;
951 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
953 TCHECK(*ext);
954 safememcpy(&e, ext, sizeof(e));
955 printf(" n len=%d", ntohs(e.len) - 4);
956 if (2 < vflag && 4 < ntohs(e.len)) {
957 printf(" ");
958 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
959 goto trunc;
961 return (u_char *)ext + ntohs(e.len);
962 trunc:
963 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE));
964 return NULL;
967 static const u_char *
968 isakmp_n_print(const struct isakmp_gen *ext, u_int item_len,
969 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
970 u_int32_t proto0 _U_, int depth)
972 struct isakmp_pl_n *p, n;
973 const u_char *cp;
974 u_char *ep2;
975 u_int32_t doi;
976 u_int32_t proto;
977 static const char *notify_error_str[] = {
978 NULL, "INVALID-PAYLOAD-TYPE",
979 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
980 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
981 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
982 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
983 "INVALID-PROTOCOL-ID", "INVALID-SPI",
984 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
985 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
986 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
987 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
988 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
989 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
990 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
991 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
992 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
993 "UNEQUAL-PAYLOAD-LENGTHS",
995 static const char *ipsec_notify_error_str[] = {
996 "RESERVED",
998 static const char *notify_status_str[] = {
999 "CONNECTED",
1001 static const char *ipsec_notify_status_str[] = {
1002 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1003 "INITIAL-CONTACT",
1005 /* NOTE: these macro must be called with x in proper range */
1007 /* 0 - 8191 */
1008 #define NOTIFY_ERROR_STR(x) \
1009 STR_OR_ID((x), notify_error_str)
1011 /* 8192 - 16383 */
1012 #define IPSEC_NOTIFY_ERROR_STR(x) \
1013 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1015 /* 16384 - 24575 */
1016 #define NOTIFY_STATUS_STR(x) \
1017 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1019 /* 24576 - 32767 */
1020 #define IPSEC_NOTIFY_STATUS_STR(x) \
1021 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1023 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
1025 p = (struct isakmp_pl_n *)ext;
1026 TCHECK(*p);
1027 safememcpy(&n, ext, sizeof(n));
1028 doi = ntohl(n.doi);
1029 proto = n.prot_id;
1030 if (doi != 1) {
1031 printf(" doi=%d", doi);
1032 printf(" proto=%d", proto);
1033 if (ntohs(n.type) < 8192)
1034 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1035 else if (ntohs(n.type) < 16384)
1036 printf(" type=%s", numstr(ntohs(n.type)));
1037 else if (ntohs(n.type) < 24576)
1038 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1039 else
1040 printf(" type=%s", numstr(ntohs(n.type)));
1041 if (n.spi_size) {
1042 printf(" spi=");
1043 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1044 goto trunc;
1046 return (u_char *)(p + 1) + n.spi_size;
1049 printf(" doi=ipsec");
1050 printf(" proto=%s", PROTOIDSTR(proto));
1051 if (ntohs(n.type) < 8192)
1052 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1053 else if (ntohs(n.type) < 16384)
1054 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)));
1055 else if (ntohs(n.type) < 24576)
1056 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1057 else if (ntohs(n.type) < 32768)
1058 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)));
1059 else
1060 printf(" type=%s", numstr(ntohs(n.type)));
1061 if (n.spi_size) {
1062 printf(" spi=");
1063 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1064 goto trunc;
1067 cp = (u_char *)(p + 1) + n.spi_size;
1068 ep2 = (u_char *)p + item_len;
1070 if (cp < ep) {
1071 printf(" orig=(");
1072 switch (ntohs(n.type)) {
1073 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1075 const struct attrmap *map = oakley_t_map;
1076 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1077 while (cp < ep && cp < ep2) {
1078 cp = isakmp_attrmap_print(cp,
1079 (ep < ep2) ? ep : ep2, map, nmap);
1081 break;
1083 case IPSECDOI_NTYPE_REPLAY_STATUS:
1084 printf("replay detection %sabled",
1085 (*(u_int32_t *)cp) ? "en" : "dis");
1086 break;
1087 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1088 if (isakmp_sub_print(ISAKMP_NPTYPE_SA,
1089 (struct isakmp_gen *)cp, ep, phase, doi, proto,
1090 depth) == NULL)
1091 return NULL;
1092 break;
1093 default:
1094 /* NULL is dummy */
1095 isakmp_print(cp, item_len - sizeof(*p) - n.spi_size,
1096 NULL);
1098 printf(")");
1100 return (u_char *)ext + item_len;
1101 trunc:
1102 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N));
1103 return NULL;
1106 static const u_char *
1107 isakmp_d_print(const struct isakmp_gen *ext, u_int item_len,
1108 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
1109 u_int32_t proto0 _U_, int depth _U_)
1111 const struct isakmp_pl_d *p;
1112 struct isakmp_pl_d d;
1113 const u_int8_t *q;
1114 u_int32_t doi;
1115 u_int32_t proto;
1116 int i;
1118 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
1120 p = (struct isakmp_pl_d *)ext;
1121 TCHECK(*p);
1122 safememcpy(&d, ext, sizeof(d));
1123 doi = ntohl(d.doi);
1124 proto = d.prot_id;
1125 if (doi != 1) {
1126 printf(" doi=%u", doi);
1127 printf(" proto=%u", proto);
1128 } else {
1129 printf(" doi=ipsec");
1130 printf(" proto=%s", PROTOIDSTR(proto));
1132 printf(" spilen=%u", d.spi_size);
1133 printf(" nspi=%u", ntohs(d.num_spi));
1134 printf(" spi=");
1135 q = (u_int8_t *)(p + 1);
1136 for (i = 0; i < ntohs(d.num_spi); i++) {
1137 if (i != 0)
1138 printf(",");
1139 if (!rawprint((caddr_t)q, d.spi_size))
1140 goto trunc;
1141 q += d.spi_size;
1143 return q;
1144 trunc:
1145 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D));
1146 return NULL;
1149 static const u_char *
1150 isakmp_vid_print(const struct isakmp_gen *ext, u_int item_len,
1151 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
1152 u_int32_t proto _U_, int depth _U_)
1154 struct isakmp_gen e;
1156 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1158 TCHECK(*ext);
1159 safememcpy(&e, ext, sizeof(e));
1160 printf(" len=%d", ntohs(e.len) - 4);
1161 if (2 < vflag && 4 < ntohs(e.len)) {
1162 printf(" ");
1163 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
1164 goto trunc;
1166 return (u_char *)ext + ntohs(e.len);
1167 trunc:
1168 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID));
1169 return NULL;
1172 static const u_char *
1173 isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1174 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1176 const u_char *cp;
1177 struct isakmp_gen e;
1178 u_int item_len;
1180 cp = (u_char *)ext;
1181 TCHECK(*ext);
1182 safememcpy(&e, ext, sizeof(e));
1185 * Since we can't have a payload length of less than 4 bytes,
1186 * we need to bail out here if the generic header is nonsensical
1187 * or truncated, otherwise we could loop forever processing
1188 * zero-length items or otherwise misdissect the packet.
1190 item_len = ntohs(e.len);
1191 if (item_len <= 4)
1192 return NULL;
1194 if (NPFUNC(np)) {
1196 * XXX - what if item_len is too short, or too long,
1197 * for this payload type?
1199 cp = (*NPFUNC(np))(ext, item_len, ep, phase, doi, proto, depth);
1200 } else {
1201 printf("%s", NPSTR(np));
1202 cp += item_len;
1205 return cp;
1206 trunc:
1207 printf(" [|isakmp]");
1208 return NULL;
1211 static const u_char *
1212 isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1213 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1215 const u_char *cp;
1216 int i;
1217 struct isakmp_gen e;
1219 cp = (const u_char *)ext;
1221 while (np) {
1222 TCHECK(*ext);
1224 safememcpy(&e, ext, sizeof(e));
1226 TCHECK2(*ext, ntohs(e.len));
1228 depth++;
1229 printf("\n");
1230 for (i = 0; i < depth; i++)
1231 printf(" ");
1232 printf("(");
1233 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth);
1234 printf(")");
1235 depth--;
1237 if (cp == NULL) {
1238 /* Zero-length subitem */
1239 return NULL;
1242 np = e.np;
1243 ext = (struct isakmp_gen *)cp;
1245 return cp;
1246 trunc:
1247 printf(" [|%s]", NPSTR(np));
1248 return NULL;
1251 static char *
1252 numstr(int x)
1254 static char buf[20];
1255 snprintf(buf, sizeof(buf), "#%d", x);
1256 return buf;
1260 * some compiler tries to optimize memcpy(), using the alignment constraint
1261 * on the argument pointer type. by using this function, we try to avoid the
1262 * optimization.
1264 static void
1265 safememcpy(void *p, const void *q, size_t l)
1267 memcpy(p, q, l);
1270 void
1271 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1273 const struct isakmp *p;
1274 struct isakmp base;
1275 const u_char *ep;
1276 u_char np;
1277 int i;
1278 int phase;
1279 int major, minor;
1281 p = (const struct isakmp *)bp;
1282 ep = snapend;
1284 if ((struct isakmp *)ep < p + 1) {
1285 printf("[|isakmp]");
1286 return;
1289 safememcpy(&base, p, sizeof(base));
1291 printf("isakmp");
1292 if (vflag) {
1293 major = (base.vers & ISAKMP_VERS_MAJOR)
1294 >> ISAKMP_VERS_MAJOR_SHIFT;
1295 minor = (base.vers & ISAKMP_VERS_MINOR)
1296 >> ISAKMP_VERS_MINOR_SHIFT;
1297 printf(" %d.%d", major, minor);
1300 if (vflag) {
1301 printf(" msgid ");
1302 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1305 if (1 < vflag) {
1306 printf(" cookie ");
1307 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1308 printf("->");
1309 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1311 printf(":");
1313 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1314 if (phase == 1)
1315 printf(" phase %d", phase);
1316 else
1317 printf(" phase %d/others", phase);
1319 i = cookie_find(&base.i_ck);
1320 if (i < 0) {
1321 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1322 /* the first packet */
1323 printf(" I");
1324 if (bp2)
1325 cookie_record(&base.i_ck, bp2);
1326 } else
1327 printf(" ?");
1328 } else {
1329 if (bp2 && cookie_isinitiator(i, bp2))
1330 printf(" I");
1331 else if (bp2 && cookie_isresponder(i, bp2))
1332 printf(" R");
1333 else
1334 printf(" ?");
1337 printf(" %s", ETYPESTR(base.etype));
1338 if (base.flags) {
1339 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1340 base.flags & ISAKMP_FLAG_C ? "C" : "");
1343 if (vflag) {
1344 const struct isakmp_gen *ext;
1345 int nparen;
1347 #define CHECKLEN(p, np) \
1348 if (ep < (u_char *)(p)) { \
1349 printf(" [|%s]", NPSTR(np)); \
1350 goto done; \
1353 printf(":");
1355 /* regardless of phase... */
1356 if (base.flags & ISAKMP_FLAG_E) {
1358 * encrypted, nothing we can do right now.
1359 * we hope to decrypt the packet in the future...
1361 printf(" [encrypted %s]", NPSTR(base.np));
1362 goto done;
1365 nparen = 0;
1366 CHECKLEN(p + 1, base.np)
1368 np = base.np;
1369 ext = (struct isakmp_gen *)(p + 1);
1370 isakmp_sub_print(np, ext, ep, phase, 0, 0, 0);
1373 done:
1374 if (vflag) {
1375 if (ntohl(base.len) != length) {
1376 printf(" (len mismatch: isakmp %u/ip %u)",
1377 (u_int32_t)ntohl(base.len), length);