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