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