]> The Tcpdump Group git mirrors - tcpdump/blob - print-isakmp.c
Put a null statement after a label that had no statement after it, to
[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.44 2004-03-12 01:13:53 guy Exp $ (LBL)";
34 #endif
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <tcpdump-stdinc.h>
41
42 #include <string.h>
43
44 #include <stdio.h>
45
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 */
52
53 #include "ip.h"
54 #ifdef INET6
55 #include "ip6.h"
56 #endif
57
58 #ifndef HAVE_SOCKADDR_STORAGE
59 #define sockaddr_storage sockaddr
60 #endif
61
62 static const u_char *isakmp_sa_print(const struct isakmp_gen *,
63 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 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 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 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 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 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 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 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 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 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 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 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 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);
94
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];
102
103 /* protocol id */
104 static const char *protoidstr[] = {
105 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
106 };
107
108 /* isakmp->np */
109 static const char *npstr[] = {
110 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
111 "sig", "nonce", "n", "d", "vid"
112 };
113
114 /* isakmp->np */
115 static const u_char *(*npfunc[])(const struct isakmp_gen *, const u_char *,
116 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,
131 };
132
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",
140 };
141
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)
147
148 #define NPFUNC(x) \
149 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
150 ? npfunc[(x)] : NULL)
151
152 static int
153 iszero(u_char *p, size_t l)
154 {
155 while (l--) {
156 if (*p++)
157 return 0;
158 }
159 return 1;
160 }
161
162 /* find cookie from initiator cache */
163 static int
164 cookie_find(cookie_t *in)
165 {
166 int i;
167
168 for (i = 0; i < MAXINITIATORS; i++) {
169 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
170 return i;
171 }
172
173 return -1;
174 }
175
176 /* record initiator */
177 static void
178 cookie_record(cookie_t *in, const u_char *bp2)
179 {
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
187
188 i = cookie_find(in);
189 if (0 <= i) {
190 ninitiator = (i + 1) % MAXINITIATORS;
191 return;
192 }
193
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));
201
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));
221
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;
239 }
240 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
241 ninitiator = (ninitiator + 1) % MAXINITIATORS;
242 }
243
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)
248 {
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;
258
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;
283 }
284
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;
320 }
321 return 0;
322 }
323
324 static void
325 rawprint(caddr_t loc, size_t len)
326 {
327 static u_char *p;
328 size_t i;
329
330 TCHECK2(*loc, len);
331
332 p = (u_char *)loc;
333 for (i = 0; i < len; i++)
334 printf("%02x", p[i] & 0xff);
335 trunc:
336 ;
337 }
338
339 struct attrmap {
340 const char *type;
341 u_int nvalue;
342 const char *value[30]; /*XXX*/
343 };
344
345 static const u_char *
346 isakmp_attrmap_print(const u_char *p, const u_char *ep,
347 const struct attrmap *map, size_t nmap)
348 {
349 u_int16_t *q;
350 int totlen;
351 u_int32_t t, v;
352
353 q = (u_int16_t *)p;
354 if (p[0] & 0x80)
355 totlen = 4;
356 else
357 totlen = 4 + EXTRACT_16BITS(&q[1]);
358 if (ep < p + totlen) {
359 printf("[|attr]");
360 return ep + 1;
361 }
362
363 printf("(");
364 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
365 if (map && t < nmap && map[t].type)
366 printf("type=%s ", map[t].type);
367 else
368 printf("type=#%d ", t);
369 if (p[0] & 0x80) {
370 printf("value=");
371 v = EXTRACT_16BITS(&q[1]);
372 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
373 printf("%s", map[t].value[v]);
374 else
375 rawprint((caddr_t)&q[1], 2);
376 } else {
377 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
378 rawprint((caddr_t)&p[4], EXTRACT_16BITS(&q[1]));
379 }
380 printf(")");
381 return p + totlen;
382 }
383
384 static const u_char *
385 isakmp_attr_print(const u_char *p, const u_char *ep)
386 {
387 u_int16_t *q;
388 int totlen;
389 u_int32_t t;
390
391 q = (u_int16_t *)p;
392 if (p[0] & 0x80)
393 totlen = 4;
394 else
395 totlen = 4 + EXTRACT_16BITS(&q[1]);
396 if (ep < p + totlen) {
397 printf("[|attr]");
398 return ep + 1;
399 }
400
401 printf("(");
402 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
403 printf("type=#%d ", t);
404 if (p[0] & 0x80) {
405 printf("value=");
406 t = q[1];
407 rawprint((caddr_t)&q[1], 2);
408 } else {
409 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
410 rawprint((caddr_t)&p[2], EXTRACT_16BITS(&q[1]));
411 }
412 printf(")");
413 return p + totlen;
414 }
415
416 static const u_char *
417 isakmp_sa_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase,
418 u_int32_t doi0 _U_, u_int32_t proto0, int depth)
419 {
420 const struct isakmp_pl_sa *p;
421 struct isakmp_pl_sa sa;
422 const u_int32_t *q;
423 u_int32_t doi, sit, ident;
424 const u_char *cp, *np;
425 int t;
426
427 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA));
428
429 p = (struct isakmp_pl_sa *)ext;
430 safememcpy(&sa, ext, sizeof(sa));
431 doi = ntohl(sa.doi);
432 sit = ntohl(sa.sit);
433 if (doi != 1) {
434 printf(" doi=%d", doi);
435 printf(" situation=%u", (u_int32_t)ntohl(sa.sit));
436 return (u_char *)(p + 1);
437 }
438
439 printf(" doi=ipsec");
440 q = (u_int32_t *)&sa.sit;
441 printf(" situation=");
442 t = 0;
443 if (sit & 0x01) {
444 printf("identity");
445 t++;
446 }
447 if (sit & 0x02) {
448 printf("%ssecrecy", t ? "+" : "");
449 t++;
450 }
451 if (sit & 0x04)
452 printf("%sintegrity", t ? "+" : "");
453
454 np = (u_char *)ext + sizeof(sa);
455 if (sit != 0x01) {
456 safememcpy(&ident, ext + 1, sizeof(ident));
457 printf(" ident=%u", (u_int32_t)ntohl(ident));
458 np += sizeof(ident);
459 }
460
461 ext = (struct isakmp_gen *)np;
462
463 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
464 depth);
465
466 return cp;
467 }
468
469 static const u_char *
470 isakmp_p_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase,
471 u_int32_t doi0, u_int32_t proto0 _U_, int depth)
472 {
473 const struct isakmp_pl_p *p;
474 struct isakmp_pl_p prop;
475 const u_char *cp;
476
477 printf("%s:", NPSTR(ISAKMP_NPTYPE_P));
478
479 p = (struct isakmp_pl_p *)ext;
480 safememcpy(&prop, ext, sizeof(prop));
481 printf(" #%d protoid=%s transform=%d",
482 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t);
483 if (prop.spi_size) {
484 printf(" spi=");
485 rawprint((caddr_t)(p + 1), prop.spi_size);
486 }
487
488 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
489
490 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
491 prop.prot_id, depth);
492
493 return cp;
494 }
495
496 static const char *isakmp_p_map[] = {
497 NULL, "ike",
498 };
499
500 static const char *ah_p_map[] = {
501 NULL, "(reserved)", "md5", "sha", "1des",
502 "sha2-256", "sha2-384", "sha2-512",
503 };
504
505 static const char *esp_p_map[] = {
506 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
507 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
508 };
509
510 static const char *ipcomp_p_map[] = {
511 NULL, "oui", "deflate", "lzs",
512 };
513
514 const struct attrmap ipsec_t_map[] = {
515 { NULL, 0, { NULL } },
516 { "lifetype", 3, { NULL, "sec", "kb", }, },
517 { "life", 0, { NULL } },
518 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
519 "EC2N 2^185", }, },
520 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
521 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
522 { "keylen", 0, { NULL } },
523 { "rounds", 0, { NULL } },
524 { "dictsize", 0, { NULL } },
525 { "privalg", 0, { NULL } },
526 };
527
528 const struct attrmap oakley_t_map[] = {
529 { NULL, 0, { NULL } },
530 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
531 "3des", "cast", "aes", }, },
532 { "hash", 7, { NULL, "md5", "sha1", "tiger",
533 "sha2-256", "sha2-384", "sha2-512", }, },
534 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
535 "rsa enc revised", }, },
536 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
537 "EC2N 2^185", }, },
538 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
539 { "group prime", 0, { NULL } },
540 { "group gen1", 0, { NULL } },
541 { "group gen2", 0, { NULL } },
542 { "group curve A", 0, { NULL } },
543 { "group curve B", 0, { NULL } },
544 { "lifetype", 3, { NULL, "sec", "kb", }, },
545 { "lifeduration", 0, { NULL } },
546 { "prf", 0, { NULL } },
547 { "keylen", 0, { NULL } },
548 { "field", 0, { NULL } },
549 { "order", 0, { NULL } },
550 };
551
552 static const u_char *
553 isakmp_t_print(const struct isakmp_gen *ext, const u_char *ep,
554 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto,
555 int depth _U_)
556 {
557 const struct isakmp_pl_t *p;
558 struct isakmp_pl_t t;
559 const u_char *cp;
560 const char *idstr;
561 const struct attrmap *map;
562 size_t nmap;
563 const u_char *ep2;
564
565 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
566
567 p = (struct isakmp_pl_t *)ext;
568 safememcpy(&t, ext, sizeof(t));
569
570 switch (proto) {
571 case 1:
572 idstr = STR_OR_ID(t.t_id, isakmp_p_map);
573 map = oakley_t_map;
574 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
575 break;
576 case 2:
577 idstr = STR_OR_ID(t.t_id, ah_p_map);
578 map = ipsec_t_map;
579 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
580 break;
581 case 3:
582 idstr = STR_OR_ID(t.t_id, esp_p_map);
583 map = ipsec_t_map;
584 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
585 break;
586 case 4:
587 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
588 map = ipsec_t_map;
589 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
590 break;
591 default:
592 idstr = NULL;
593 map = NULL;
594 nmap = 0;
595 break;
596 }
597
598 if (idstr)
599 printf(" #%d id=%s ", t.t_no, idstr);
600 else
601 printf(" #%d id=%d ", t.t_no, t.t_id);
602 cp = (u_char *)(p + 1);
603 ep2 = (u_char *)p + ntohs(t.h.len);
604 while (cp < ep && cp < ep2) {
605 if (map && nmap) {
606 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
607 map, nmap);
608 } else
609 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
610 }
611 if (ep < ep2)
612 printf("...");
613 return cp;
614 }
615
616 static const u_char *
617 isakmp_ke_print(const struct isakmp_gen *ext, const u_char *ep _U_,
618 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_,
619 int depth _U_)
620 {
621 struct isakmp_gen e;
622
623 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
624
625 safememcpy(&e, ext, sizeof(e));
626 printf(" key len=%d", ntohs(e.len) - 4);
627 if (2 < vflag && 4 < ntohs(e.len)) {
628 printf(" ");
629 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
630 }
631 return (u_char *)ext + ntohs(e.len);
632 }
633
634 static const u_char *
635 isakmp_id_print(const struct isakmp_gen *ext, const u_char *ep _U_,
636 u_int32_t phase, u_int32_t doi _U_, u_int32_t proto _U_,
637 int depth _U_)
638 {
639 #define USE_IPSECDOI_IN_PHASE1 1
640 const struct isakmp_pl_id *p;
641 struct isakmp_pl_id id;
642 static const char *idtypestr[] = {
643 "IPv4", "IPv4net", "IPv6", "IPv6net",
644 };
645 static const char *ipsecidtypestr[] = {
646 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
647 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
648 "keyid",
649 };
650 int len;
651 const u_char *data;
652
653 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
654
655 p = (struct isakmp_pl_id *)ext;
656 safememcpy(&id, ext, sizeof(id));
657 if (sizeof(*p) < id.h.len)
658 data = (u_char *)(p + 1);
659 else
660 data = NULL;
661 len = ntohs(id.h.len) - sizeof(*p);
662
663 #if 0 /*debug*/
664 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
665 #endif
666 switch (phase) {
667 #ifndef USE_IPSECDOI_IN_PHASE1
668 case 1:
669 #endif
670 default:
671 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr));
672 printf(" doi_data=%u",
673 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff));
674 break;
675
676 #ifdef USE_IPSECDOI_IN_PHASE1
677 case 1:
678 #endif
679 case 2:
680 {
681 const struct ipsecdoi_id *p;
682 struct ipsecdoi_id id;
683 struct protoent *pe;
684
685 p = (struct ipsecdoi_id *)ext;
686 safememcpy(&id, ext, sizeof(id));
687 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr));
688 if (id.proto_id) {
689 #ifndef WIN32
690 setprotoent(1);
691 #endif /* WIN32 */
692 pe = getprotobynumber(id.proto_id);
693 if (pe)
694 printf(" protoid=%s", pe->p_name);
695 #ifndef WIN32
696 endprotoent();
697 #endif /* WIN32 */
698 } else {
699 /* it DOES NOT mean IPPROTO_IP! */
700 printf(" protoid=%s", "0");
701 }
702 printf(" port=%d", ntohs(id.port));
703 if (!len)
704 break;
705 switch (id.type) {
706 case IPSECDOI_ID_IPV4_ADDR:
707 printf(" len=%d %s", len, ipaddr_string(data));
708 len = 0;
709 break;
710 case IPSECDOI_ID_FQDN:
711 case IPSECDOI_ID_USER_FQDN:
712 {
713 int i;
714 printf(" len=%d ", len);
715 for (i = 0; i < len; i++)
716 safeputchar(data[i]);
717 len = 0;
718 break;
719 }
720 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
721 {
722 const u_char *mask;
723 mask = data + sizeof(struct in_addr);
724 printf(" len=%d %s/%u.%u.%u.%u", len,
725 ipaddr_string(data),
726 mask[0], mask[1], mask[2], mask[3]);
727 len = 0;
728 break;
729 }
730 #ifdef INET6
731 case IPSECDOI_ID_IPV6_ADDR:
732 printf(" len=%d %s", len, ip6addr_string(data));
733 len = 0;
734 break;
735 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
736 {
737 const u_int32_t *mask;
738 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
739 /*XXX*/
740 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
741 ip6addr_string(data),
742 mask[0], mask[1], mask[2], mask[3]);
743 len = 0;
744 break;
745 }
746 #endif /*INET6*/
747 case IPSECDOI_ID_IPV4_ADDR_RANGE:
748 printf(" len=%d %s-%s", len, ipaddr_string(data),
749 ipaddr_string(data + sizeof(struct in_addr)));
750 len = 0;
751 break;
752 #ifdef INET6
753 case IPSECDOI_ID_IPV6_ADDR_RANGE:
754 printf(" len=%d %s-%s", len, ip6addr_string(data),
755 ip6addr_string(data + sizeof(struct in6_addr)));
756 len = 0;
757 break;
758 #endif /*INET6*/
759 case IPSECDOI_ID_DER_ASN1_DN:
760 case IPSECDOI_ID_DER_ASN1_GN:
761 case IPSECDOI_ID_KEY_ID:
762 break;
763 }
764 break;
765 }
766 }
767 if (data && len) {
768 printf(" len=%d", len);
769 if (2 < vflag) {
770 printf(" ");
771 rawprint((caddr_t)data, len);
772 }
773 }
774 return (u_char *)ext + ntohs(id.h.len);
775 }
776
777 static const u_char *
778 isakmp_cert_print(const struct isakmp_gen *ext, const u_char *ep _U_,
779 u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_,
780 int depth _U_)
781 {
782 const struct isakmp_pl_cert *p;
783 struct isakmp_pl_cert cert;
784 static const char *certstr[] = {
785 "none", "pkcs7", "pgp", "dns",
786 "x509sign", "x509ke", "kerberos", "crl",
787 "arl", "spki", "x509attr",
788 };
789
790 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
791
792 p = (struct isakmp_pl_cert *)ext;
793 safememcpy(&cert, ext, sizeof(cert));
794 printf(" len=%d", ntohs(cert.h.len) - 4);
795 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
796 if (2 < vflag && 4 < ntohs(cert.h.len)) {
797 printf(" ");
798 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4);
799 }
800 return (u_char *)ext + ntohs(cert.h.len);
801 }
802
803 static const u_char *
804 isakmp_cr_print(const struct isakmp_gen *ext, const u_char *ep _U_,
805 u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_,
806 int depth _U_)
807 {
808 const struct isakmp_pl_cert *p;
809 struct isakmp_pl_cert cert;
810 static const char *certstr[] = {
811 "none", "pkcs7", "pgp", "dns",
812 "x509sign", "x509ke", "kerberos", "crl",
813 "arl", "spki", "x509attr",
814 };
815
816 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
817
818 p = (struct isakmp_pl_cert *)ext;
819 safememcpy(&cert, ext, sizeof(cert));
820 printf(" len=%d", ntohs(cert.h.len) - 4);
821 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
822 if (2 < vflag && 4 < ntohs(cert.h.len)) {
823 printf(" ");
824 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4);
825 }
826 return (u_char *)ext + ntohs(cert.h.len);
827 }
828
829 static const u_char *
830 isakmp_hash_print(const struct isakmp_gen *ext, const u_char *ep _U_,
831 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_,
832 int depth _U_)
833 {
834 struct isakmp_gen e;
835
836 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
837
838 safememcpy(&e, ext, sizeof(e));
839 printf(" len=%d", ntohs(e.len) - 4);
840 if (2 < vflag && 4 < ntohs(e.len)) {
841 printf(" ");
842 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
843 }
844 return (u_char *)ext + ntohs(e.len);
845 }
846
847 static const u_char *
848 isakmp_sig_print(const struct isakmp_gen *ext, const u_char *ep _U_,
849 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_,
850 int depth _U_)
851 {
852 struct isakmp_gen e;
853
854 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
855
856 safememcpy(&e, ext, sizeof(e));
857 printf(" len=%d", ntohs(e.len) - 4);
858 if (2 < vflag && 4 < ntohs(e.len)) {
859 printf(" ");
860 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
861 }
862 return (u_char *)ext + ntohs(e.len);
863 }
864
865 static const u_char *
866 isakmp_nonce_print(const struct isakmp_gen *ext, const u_char *ep _U_,
867 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_,
868 int depth _U_)
869 {
870 struct isakmp_gen e;
871
872 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
873
874 safememcpy(&e, ext, sizeof(e));
875 printf(" n len=%d", ntohs(e.len) - 4);
876 if (2 < vflag && 4 < ntohs(e.len)) {
877 printf(" ");
878 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
879 }
880 return (u_char *)ext + ntohs(e.len);
881 }
882
883 static const u_char *
884 isakmp_n_print(const struct isakmp_gen *ext, const u_char *ep, u_int32_t phase,
885 u_int32_t doi0 _U_, u_int32_t proto0 _U_, int depth)
886 {
887 struct isakmp_pl_n *p, n;
888 const u_char *cp;
889 u_char *ep2;
890 u_int32_t doi;
891 u_int32_t proto;
892 static const char *notify_error_str[] = {
893 NULL, "INVALID-PAYLOAD-TYPE",
894 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
895 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
896 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
897 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
898 "INVALID-PROTOCOL-ID", "INVALID-SPI",
899 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
900 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
901 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
902 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
903 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
904 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
905 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
906 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
907 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
908 "UNEQUAL-PAYLOAD-LENGTHS",
909 };
910 static const char *ipsec_notify_error_str[] = {
911 "RESERVED",
912 };
913 static const char *notify_status_str[] = {
914 "CONNECTED",
915 };
916 static const char *ipsec_notify_status_str[] = {
917 "RESPONDER-LIFETIME", "REPLAY-STATUS",
918 "INITIAL-CONTACT",
919 };
920 /* NOTE: these macro must be called with x in proper range */
921
922 /* 0 - 8191 */
923 #define NOTIFY_ERROR_STR(x) \
924 STR_OR_ID((x), notify_error_str)
925
926 /* 8192 - 16383 */
927 #define IPSEC_NOTIFY_ERROR_STR(x) \
928 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
929
930 /* 16384 - 24575 */
931 #define NOTIFY_STATUS_STR(x) \
932 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
933
934 /* 24576 - 32767 */
935 #define IPSEC_NOTIFY_STATUS_STR(x) \
936 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
937
938 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
939
940 p = (struct isakmp_pl_n *)ext;
941 safememcpy(&n, ext, sizeof(n));
942 doi = ntohl(n.doi);
943 proto = n.prot_id;
944 if (doi != 1) {
945 printf(" doi=%d", doi);
946 printf(" proto=%d", proto);
947 if (ntohs(n.type) < 8192)
948 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
949 else if (ntohs(n.type) < 16384)
950 printf(" type=%s", numstr(ntohs(n.type)));
951 else if (ntohs(n.type) < 24576)
952 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
953 else
954 printf(" type=%s", numstr(ntohs(n.type)));
955 if (n.spi_size) {
956 printf(" spi=");
957 rawprint((caddr_t)(p + 1), n.spi_size);
958 }
959 return (u_char *)(p + 1) + n.spi_size;
960 }
961
962 printf(" doi=ipsec");
963 printf(" proto=%s", PROTOIDSTR(proto));
964 if (ntohs(n.type) < 8192)
965 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
966 else if (ntohs(n.type) < 16384)
967 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)));
968 else if (ntohs(n.type) < 24576)
969 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
970 else if (ntohs(n.type) < 32768)
971 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)));
972 else
973 printf(" type=%s", numstr(ntohs(n.type)));
974 if (n.spi_size) {
975 printf(" spi=");
976 rawprint((caddr_t)(p + 1), n.spi_size);
977 }
978
979 cp = (u_char *)(p + 1) + n.spi_size;
980 ep2 = (u_char *)p + ntohs(n.h.len);
981
982 if (cp < ep) {
983 printf(" orig=(");
984 switch (ntohs(n.type)) {
985 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
986 {
987 const struct attrmap *map = oakley_t_map;
988 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
989 while (cp < ep && cp < ep2) {
990 cp = isakmp_attrmap_print(cp,
991 (ep < ep2) ? ep : ep2, map, nmap);
992 }
993 break;
994 }
995 case IPSECDOI_NTYPE_REPLAY_STATUS:
996 printf("replay detection %sabled",
997 (*(u_int32_t *)cp) ? "en" : "dis");
998 break;
999 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1000 if (isakmp_sub_print(ISAKMP_NPTYPE_SA,
1001 (struct isakmp_gen *)cp, ep, phase, doi, proto,
1002 depth) == NULL)
1003 return NULL;
1004 break;
1005 default:
1006 /* NULL is dummy */
1007 isakmp_print(cp,
1008 ntohs(n.h.len) - sizeof(*p) - n.spi_size,
1009 NULL);
1010 }
1011 printf(")");
1012 }
1013 return (u_char *)ext + ntohs(n.h.len);
1014 }
1015
1016 static const u_char *
1017 isakmp_d_print(const struct isakmp_gen *ext, const u_char *ep _U_,
1018 u_int32_t phase _U_, u_int32_t doi0 _U_, u_int32_t proto0 _U_,
1019 int depth _U_)
1020 {
1021 const struct isakmp_pl_d *p;
1022 struct isakmp_pl_d d;
1023 const u_int8_t *q;
1024 u_int32_t doi;
1025 u_int32_t proto;
1026 int i;
1027
1028 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
1029
1030 p = (struct isakmp_pl_d *)ext;
1031 safememcpy(&d, ext, sizeof(d));
1032 doi = ntohl(d.doi);
1033 proto = d.prot_id;
1034 if (doi != 1) {
1035 printf(" doi=%u", doi);
1036 printf(" proto=%u", proto);
1037 } else {
1038 printf(" doi=ipsec");
1039 printf(" proto=%s", PROTOIDSTR(proto));
1040 }
1041 printf(" spilen=%u", d.spi_size);
1042 printf(" nspi=%u", ntohs(d.num_spi));
1043 printf(" spi=");
1044 q = (u_int8_t *)(p + 1);
1045 for (i = 0; i < ntohs(d.num_spi); i++) {
1046 if (i != 0)
1047 printf(",");
1048 rawprint((caddr_t)q, d.spi_size);
1049 q += d.spi_size;
1050 }
1051 return q;
1052 }
1053
1054 static const u_char *
1055 isakmp_vid_print(const struct isakmp_gen *ext, const u_char *ep _U_,
1056 u_int32_t phase _U_, u_int32_t doi _U_, u_int32_t proto _U_,
1057 int depth _U_)
1058 {
1059 struct isakmp_gen e;
1060
1061 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1062
1063 safememcpy(&e, ext, sizeof(e));
1064 printf(" len=%d", ntohs(e.len) - 4);
1065 if (2 < vflag && 4 < ntohs(e.len)) {
1066 printf(" ");
1067 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
1068 }
1069 return (u_char *)ext + ntohs(e.len);
1070 }
1071
1072 static const u_char *
1073 isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1074 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1075 {
1076 const u_char *cp;
1077 struct isakmp_gen e;
1078 u_int item_len;
1079
1080 cp = (u_char *)ext;
1081 safememcpy(&e, ext, sizeof(e));
1082
1083 /*
1084 * Since we can't have a payload length of less than 4 bytes,
1085 * we need to bail out here if the generic header is nonsensical
1086 * or truncated, otherwise we could loop forever processing
1087 * zero-length items or otherwise misdissect the packet.
1088 */
1089 item_len = ntohs(e.len);
1090 if (item_len <= 4)
1091 return NULL;
1092
1093 if (NPFUNC(np)) {
1094 /*
1095 * XXX - what if item_len is too short, or too long,
1096 * for this payload type?
1097 */
1098 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto, depth);
1099 } else {
1100 printf("%s", NPSTR(np));
1101 cp += item_len;
1102 }
1103
1104 return cp;
1105 }
1106
1107 static const u_char *
1108 isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1109 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1110 {
1111 const u_char *cp;
1112 int i;
1113 struct isakmp_gen e;
1114
1115 cp = (const u_char *)ext;
1116
1117 while (np) {
1118 TCHECK2(*ext, sizeof(e));
1119
1120 safememcpy(&e, ext, sizeof(e));
1121
1122 if (ep < (u_char *)ext + ntohs(e.len)) {
1123 printf(" [|%s]", NPSTR(np));
1124 cp = ep + 1;
1125 break;
1126 }
1127 depth++;
1128 printf("\n");
1129 for (i = 0; i < depth; i++)
1130 printf(" ");
1131 printf("(");
1132 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth);
1133 printf(")");
1134 depth--;
1135
1136 if (cp == NULL) {
1137 /* Zero-length subitem */
1138 return NULL;
1139 }
1140
1141 np = e.np;
1142 ext = (struct isakmp_gen *)cp;
1143 }
1144 return cp;
1145 trunc:
1146 return NULL;
1147 }
1148
1149 static char *
1150 numstr(int x)
1151 {
1152 static char buf[20];
1153 snprintf(buf, sizeof(buf), "#%d", x);
1154 return buf;
1155 }
1156
1157 /*
1158 * some compiler tries to optimize memcpy(), using the alignment constraint
1159 * on the argument pointer type. by using this function, we try to avoid the
1160 * optimization.
1161 */
1162 static void
1163 safememcpy(void *p, const void *q, size_t l)
1164 {
1165 memcpy(p, q, l);
1166 }
1167
1168 void
1169 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1170 {
1171 const struct isakmp *p;
1172 struct isakmp base;
1173 const u_char *ep;
1174 u_char np;
1175 int i;
1176 int phase;
1177 int major, minor;
1178
1179 p = (const struct isakmp *)bp;
1180 ep = snapend;
1181
1182 if ((struct isakmp *)ep < p + 1) {
1183 printf("[|isakmp]");
1184 return;
1185 }
1186
1187 safememcpy(&base, p, sizeof(base));
1188
1189 printf("isakmp");
1190 if (vflag) {
1191 major = (base.vers & ISAKMP_VERS_MAJOR)
1192 >> ISAKMP_VERS_MAJOR_SHIFT;
1193 minor = (base.vers & ISAKMP_VERS_MINOR)
1194 >> ISAKMP_VERS_MINOR_SHIFT;
1195 printf(" %d.%d", major, minor);
1196 }
1197
1198 if (vflag) {
1199 printf(" msgid ");
1200 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1201 }
1202
1203 if (1 < vflag) {
1204 printf(" cookie ");
1205 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1206 printf("->");
1207 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1208 }
1209 printf(":");
1210
1211 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1212 if (phase == 1)
1213 printf(" phase %d", phase);
1214 else
1215 printf(" phase %d/others", phase);
1216
1217 i = cookie_find(&base.i_ck);
1218 if (i < 0) {
1219 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1220 /* the first packet */
1221 printf(" I");
1222 if (bp2)
1223 cookie_record(&base.i_ck, bp2);
1224 } else
1225 printf(" ?");
1226 } else {
1227 if (bp2 && cookie_isinitiator(i, bp2))
1228 printf(" I");
1229 else if (bp2 && cookie_isresponder(i, bp2))
1230 printf(" R");
1231 else
1232 printf(" ?");
1233 }
1234
1235 printf(" %s", ETYPESTR(base.etype));
1236 if (base.flags) {
1237 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1238 base.flags & ISAKMP_FLAG_C ? "C" : "");
1239 }
1240
1241 if (vflag) {
1242 const struct isakmp_gen *ext;
1243 int nparen;
1244
1245 #define CHECKLEN(p, np) \
1246 if (ep < (u_char *)(p)) { \
1247 printf(" [|%s]", NPSTR(np)); \
1248 goto done; \
1249 }
1250
1251 printf(":");
1252
1253 /* regardless of phase... */
1254 if (base.flags & ISAKMP_FLAG_E) {
1255 /*
1256 * encrypted, nothing we can do right now.
1257 * we hope to decrypt the packet in the future...
1258 */
1259 printf(" [encrypted %s]", NPSTR(base.np));
1260 goto done;
1261 }
1262
1263 nparen = 0;
1264 CHECKLEN(p + 1, base.np)
1265
1266 np = base.np;
1267 ext = (struct isakmp_gen *)(p + 1);
1268 isakmp_sub_print(np, ext, ep, phase, 0, 0, 0);
1269 }
1270
1271 done:
1272 if (vflag) {
1273 if (ntohl(base.len) != length) {
1274 printf(" (len mismatch: isakmp %u/ip %u)",
1275 (u_int32_t)ntohl(base.len), length);
1276 }
1277 }
1278 }