]> The Tcpdump Group git mirrors - tcpdump/blob - print-isakmp.c
90c802685f968b5e4b0f9efd5772449274d402b6
[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[] =
33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.21 2000-09-29 04:58:42 guy Exp $ (LBL)";
34 #endif
35
36 #ifdef HAVE_CONFIG_H
37 #include "config.h"
38 #endif
39
40 #include <string.h>
41 #include <ctype.h>
42 #include <sys/param.h>
43 #include <sys/time.h>
44 #include <sys/socket.h>
45
46 struct mbuf;
47 struct rtentry;
48
49 #include <netinet/in.h>
50
51 #ifdef INET6
52 #include <netinet/ip6.h>
53 #endif
54
55 #include <stdio.h>
56 #include <netdb.h>
57
58 #include "isakmp.h"
59 #include "ipsec_doi.h"
60 #include "oakley.h"
61 #include "interface.h"
62 #include "addrtoname.h"
63 #include "extract.h" /* must come after interface.h */
64
65 #include "ip.h"
66
67 #ifndef HAVE_SOCKADDR_STORAGE
68 #define sockaddr_storage sockaddr
69 #endif
70
71 static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t,
72 u_int32_t, u_int32_t);
73 static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t,
74 u_int32_t, u_int32_t);
75 static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t,
76 u_int32_t, u_int32_t);
77 static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t,
78 u_int32_t, u_int32_t);
79 static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t,
80 u_int32_t, u_int32_t);
81 static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t,
82 u_int32_t, u_int32_t);
83 static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t,
84 u_int32_t, u_int32_t);
85 static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t,
86 u_int32_t, u_int32_t);
87 static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *,
88 u_int32_t, u_int32_t, u_int32_t);
89 static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *,
90 u_int32_t, u_int32_t, u_int32_t);
91 static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t,
92 u_int32_t, u_int32_t);
93 static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t,
94 u_int32_t, u_int32_t);
95 static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t,
96 u_int32_t, u_int32_t);
97 static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *,
98 u_int32_t, u_int32_t, u_int32_t);
99 static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *,
100 u_int32_t, u_int32_t, u_int32_t);
101 static char *numstr(int);
102
103 #define MAXINITIATORS 20
104 int ninitiator = 0;
105 struct {
106 cookie_t initiator;
107 struct sockaddr_storage iaddr;
108 struct sockaddr_storage raddr;
109 } cookiecache[MAXINITIATORS];
110
111 /* protocol id */
112 static char *protoidstr[] = {
113 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
114 };
115
116 /* isakmp->np */
117 static char *npstr[] = {
118 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
119 "sig", "nonce", "n", "d", "vid"
120 };
121
122 /* isakmp->np */
123 static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t,
124 u_int32_t, u_int32_t) = {
125 NULL,
126 isakmp_sa_print,
127 isakmp_p_print,
128 isakmp_t_print,
129 isakmp_ke_print,
130 isakmp_id_print,
131 isakmp_cert_print,
132 isakmp_cr_print,
133 isakmp_hash_print,
134 isakmp_sig_print,
135 isakmp_nonce_print,
136 isakmp_n_print,
137 isakmp_d_print,
138 isakmp_vid_print,
139 };
140
141 /* isakmp->etype */
142 static char *etypestr[] = {
143 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL,
144 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
145 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
146 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
147 "oakley-quick", "oakley-newgroup",
148 };
149
150 #define STR_OR_ID(x, tab) \
151 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
152 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
153 #define NPSTR(x) STR_OR_ID(x, npstr)
154 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
155
156 #define NPFUNC(x) \
157 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
158 ? npfunc[(x)] : NULL)
159
160 static int
161 iszero(u_char *p, size_t l)
162 {
163 while (l--) {
164 if (*p++)
165 return 0;
166 }
167 return 1;
168 }
169
170 /* find cookie from initiator cache */
171 static int
172 cookie_find(cookie_t *in)
173 {
174 int i;
175
176 for (i = 0; i < MAXINITIATORS; i++) {
177 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
178 return i;
179 }
180
181 return -1;
182 }
183
184 /* record initiator */
185 static void
186 cookie_record(cookie_t *in, const u_char *bp2)
187 {
188 int i;
189 struct ip *ip;
190 struct sockaddr_in *sin;
191 #ifdef INET6
192 struct ip6_hdr *ip6;
193 struct sockaddr_in6 *sin6;
194 #endif
195
196 i = cookie_find(in);
197 if (0 <= i) {
198 ninitiator = (i + 1) % MAXINITIATORS;
199 return;
200 }
201
202 ip = (struct ip *)bp2;
203 switch (ip->ip_v) {
204 case 4:
205 memset(&cookiecache[ninitiator].iaddr, 0,
206 sizeof(cookiecache[ninitiator].iaddr));
207 memset(&cookiecache[ninitiator].raddr, 0,
208 sizeof(cookiecache[ninitiator].raddr));
209
210 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
211 #ifdef HAVE_SOCKADDR_SA_LEN
212 sin->sin_len = sizeof(struct sockaddr_in);
213 #endif
214 sin->sin_family = AF_INET;
215 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
216 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
217 #ifdef HAVE_SOCKADDR_SA_LEN
218 sin->sin_len = sizeof(struct sockaddr_in);
219 #endif
220 sin->sin_family = AF_INET;
221 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
222 break;
223 #ifdef INET6
224 case 6:
225 memset(&cookiecache[ninitiator].iaddr, 0,
226 sizeof(cookiecache[ninitiator].iaddr));
227 memset(&cookiecache[ninitiator].raddr, 0,
228 sizeof(cookiecache[ninitiator].raddr));
229
230 ip6 = (struct ip6_hdr *)bp2;
231 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
232 #ifdef HAVE_SOCKADDR_SA_LEN
233 sin6->sin6_len = sizeof(struct sockaddr_in6);
234 #endif
235 sin6->sin6_family = AF_INET6;
236 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
237 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
238 #ifdef HAVE_SOCKADDR_SA_LEN
239 sin6->sin6_len = sizeof(struct sockaddr_in6);
240 #endif
241 sin6->sin6_family = AF_INET6;
242 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
243 break;
244 #endif
245 default:
246 return;
247 }
248 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
249 ninitiator = (ninitiator + 1) % MAXINITIATORS;
250 }
251
252 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
253 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
254 static int
255 cookie_sidecheck(int i, const u_char *bp2, int initiator)
256 {
257 struct sockaddr_storage ss;
258 struct sockaddr *sa;
259 struct ip *ip;
260 struct sockaddr_in *sin;
261 #ifdef INET6
262 struct ip6_hdr *ip6;
263 struct sockaddr_in6 *sin6;
264 #endif
265 int salen;
266
267 memset(&ss, 0, sizeof(ss));
268 ip = (struct ip *)bp2;
269 switch (ip->ip_v) {
270 case 4:
271 sin = (struct sockaddr_in *)&ss;
272 #ifdef HAVE_SOCKADDR_SA_LEN
273 sin->sin_len = sizeof(struct sockaddr_in);
274 #endif
275 sin->sin_family = AF_INET;
276 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
277 break;
278 #ifdef INET6
279 case 6:
280 ip6 = (struct ip6_hdr *)bp2;
281 sin6 = (struct sockaddr_in6 *)&ss;
282 #ifdef HAVE_SOCKADDR_SA_LEN
283 sin6->sin6_len = sizeof(struct sockaddr_in6);
284 #endif
285 sin6->sin6_family = AF_INET6;
286 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
287 break;
288 #endif
289 default:
290 return 0;
291 }
292
293 sa = (struct sockaddr *)&ss;
294 if (initiator) {
295 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
296 return 0;
297 #ifdef HAVE_SOCKADDR_SA_LEN
298 salen = sa->sa_len;
299 #else
300 #ifdef INET6
301 if (sa->sa_family == AF_INET6)
302 salen = sizeof(struct sockaddr_in6);
303 else
304 salen = sizeof(struct sockaddr);
305 #else
306 salen = sizeof(struct sockaddr);
307 #endif
308 #endif
309 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
310 return 1;
311 } else {
312 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
313 return 0;
314 #ifdef HAVE_SOCKADDR_SA_LEN
315 salen = sa->sa_len;
316 #else
317 #ifdef INET6
318 if (sa->sa_family == AF_INET6)
319 salen = sizeof(struct sockaddr_in6);
320 else
321 salen = sizeof(struct sockaddr);
322 #else
323 salen = sizeof(struct sockaddr);
324 #endif
325 #endif
326 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
327 return 1;
328 }
329 return 0;
330 }
331
332 static void
333 rawprint(caddr_t loc, size_t len)
334 {
335 static u_char *p;
336 int i;
337
338 p = (u_char *)loc;
339 for (i = 0; i < len; i++)
340 printf("%02x", p[i] & 0xff);
341 }
342
343 struct attrmap {
344 char *type;
345 int nvalue;
346 char *value[30]; /*XXX*/
347 };
348
349 static u_char *
350 isakmp_attrmap_print(u_char *p, u_char *ep, struct attrmap *map, size_t nmap)
351 {
352 u_int16_t *q;
353 int totlen;
354 u_int32_t t, v;
355
356 q = (u_int16_t *)p;
357 if (p[0] & 0x80)
358 totlen = 4;
359 else
360 totlen = 4 + ntohs(q[1]);
361 if (ep < p + totlen) {
362 printf("[|attr]");
363 return ep + 1;
364 }
365
366 printf("(");
367 t = ntohs(q[0]) & 0x7fff;
368 if (map && t < nmap && map[t].type)
369 printf("type=%s ", map[t].type);
370 else
371 printf("type=#%d ", t);
372 if (p[0] & 0x80) {
373 printf("value=");
374 v = ntohs(q[1]);
375 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
376 printf("%s", map[t].value[v]);
377 else
378 rawprint((caddr_t)&q[1], 2);
379 } else {
380 printf("len=%d value=", ntohs(q[1]));
381 rawprint((caddr_t)&p[4], ntohs(q[1]));
382 }
383 printf(")");
384 return p + totlen;
385 }
386
387 static u_char *
388 isakmp_attr_print(u_char *p, u_char *ep)
389 {
390 u_int16_t *q;
391 int totlen;
392 u_int32_t t;
393
394 q = (u_int16_t *)p;
395 if (p[0] & 0x80)
396 totlen = 4;
397 else
398 totlen = 4 + ntohs(q[1]);
399 if (ep < p + totlen) {
400 printf("[|attr]");
401 return ep + 1;
402 }
403
404 printf("(");
405 t = ntohs(q[0]) & 0x7fff;
406 printf("type=#%d ", t);
407 if (p[0] & 0x80) {
408 printf("value=");
409 t = q[1];
410 rawprint((caddr_t)&q[1], 2);
411 } else {
412 printf("len=%d value=", ntohs(q[1]));
413 rawprint((caddr_t)&p[2], ntohs(q[1]));
414 }
415 printf(")");
416 return p + totlen;
417 }
418
419 static u_char *
420 isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
421 u_int32_t doi0, u_int32_t proto0)
422 {
423 struct isakmp_pl_sa *p;
424 u_int32_t *q;
425 u_int32_t doi;
426 u_int32_t sit;
427 u_char *cp;
428 int t;
429
430 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA));
431
432 p = (struct isakmp_pl_sa *)ext;
433 doi = ntohl(p->doi);
434 if (doi != 1) {
435 printf(" doi=%d", doi);
436 printf(" situation=%u", (u_int32_t)ntohl(p->sit));
437 return (u_char *)(p + 1);
438 }
439
440 printf(" doi=ipsec");
441 q = (u_int32_t *)&p->sit;
442 printf(" situation=");
443 t = 0;
444 if (ntohl(*q) & 0x01) {
445 printf("identity");
446 t++;
447 }
448 if (ntohl(*q) & 0x02) {
449 printf("%ssecrecy", t ? "+" : "");
450 t++;
451 }
452 if (ntohl(*q) & 0x04)
453 printf("%sintegrity", t ? "+" : "");
454 sit = htonl(*q++);
455
456 if (sit != 0x01)
457 printf(" ident=%u", (u_int32_t)ntohl(*q++));
458
459 ext = (struct isakmp_gen *)q;
460
461 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0);
462
463 return cp;
464 }
465
466 static u_char *
467 isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
468 u_int32_t doi0, u_int32_t proto0)
469 {
470 struct isakmp_pl_p *p;
471 u_char *cp;
472
473 printf("%s:", NPSTR(ISAKMP_NPTYPE_P));
474
475 p = (struct isakmp_pl_p *)ext;
476 printf(" #%d protoid=%s transform=%d",
477 p->p_no, PROTOIDSTR(p->prot_id), p->num_t);
478 if (p->spi_size) {
479 printf(" spi=");
480 rawprint((caddr_t)(p + 1), p->spi_size);
481 }
482
483 ext = (struct isakmp_gen *)((u_char *)(p + 1) + p->spi_size);
484
485 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
486 p->prot_id);
487
488 return cp;
489 }
490
491 static char *isakmp_p_map[] = {
492 NULL, "ike",
493 };
494
495 static char *ah_p_map[] = {
496 NULL, "(reserved)", "md5", "sha", "1des",
497 };
498
499 static char *esp_p_map[] = {
500 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
501 "blowfish", "3idea", "1des-iv32", "rc4", "null"
502 };
503
504 static char *ipcomp_p_map[] = {
505 NULL, "oui", "deflate", "lzs",
506 };
507
508 struct attrmap ipsec_t_map[] = {
509 { NULL, 0, },
510 { "lifetype", 3, { NULL, "sec", "kb", }, },
511 { "life", 0, },
512 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
513 "EC2N 2^185", }, },
514 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
515 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
516 { "keylen", 0, },
517 { "rounds", 0, },
518 { "dictsize", 0, },
519 { "privalg", 0, },
520 };
521
522 struct attrmap oakley_t_map[] = {
523 { NULL, 0 },
524 { "enc", 7, { NULL, "1des", "idea", "blowfish", "rc5",
525 "3des", "cast"}, },
526 { "hash", 4, { NULL, "md5", "sha1", "tiger", }, },
527 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
528 "rsa enc revised", }, },
529 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
530 "EC2N 2^185", }, },
531 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
532 { "group prime", 0, },
533 { "group gen1", 0, },
534 { "group gen2", 0, },
535 { "group curve A", 0, },
536 { "group curve B", 0, },
537 { "lifetype", 3, { NULL, "sec", "kb", }, },
538 { "lifeduration", 0, },
539 { "prf", 0, },
540 { "keylen", 0, },
541 { "field", 0, },
542 { "order", 0, },
543 };
544
545 static u_char *
546 isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
547 u_int32_t doi, u_int32_t proto)
548 {
549 struct isakmp_pl_t *p;
550 u_char *cp;
551 char *idstr;
552 struct attrmap *map;
553 size_t nmap;
554 u_char *ep2;
555
556 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
557
558 p = (struct isakmp_pl_t *)ext;
559
560 switch (proto) {
561 case 1:
562 idstr = STR_OR_ID(p->t_id, isakmp_p_map);
563 map = oakley_t_map;
564 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
565 break;
566 case 2:
567 idstr = STR_OR_ID(p->t_id, ah_p_map);
568 map = ipsec_t_map;
569 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
570 break;
571 case 3:
572 idstr = STR_OR_ID(p->t_id, esp_p_map);
573 map = ipsec_t_map;
574 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
575 break;
576 case 4:
577 idstr = STR_OR_ID(p->t_id, ipcomp_p_map);
578 map = ipsec_t_map;
579 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
580 break;
581 default:
582 idstr = NULL;
583 map = NULL;
584 nmap = 0;
585 break;
586 }
587
588 if (idstr)
589 printf(" #%d id=%s ", p->t_no, idstr);
590 else
591 printf(" #%d id=%d ", p->t_no, p->t_id);
592 cp = (u_char *)(p + 1);
593 ep2 = (u_char *)p + ntohs(ext->len);
594 while (cp < ep && cp < ep2) {
595 if (map && nmap) {
596 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
597 map, nmap);
598 } else
599 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
600 }
601 if (ep < ep2)
602 printf("...");
603 return cp;
604 }
605
606 static u_char *
607 isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
608 u_int32_t doi, u_int32_t proto)
609 {
610 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
611
612 printf(" key len=%d", ntohs(ext->len) - 4);
613 if (2 < vflag && 4 < ntohs(ext->len)) {
614 printf(" ");
615 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
616 }
617 return (u_char *)ext + ntohs(ext->len);
618 }
619
620 static u_char *
621 isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
622 u_int32_t doi, u_int32_t proto)
623 {
624 #define USE_IPSECDOI_IN_PHASE1 1
625 struct isakmp_pl_id *p;
626 static char *idtypestr[] = {
627 "IPv4", "IPv4net", "IPv6", "IPv6net",
628 };
629 static char *ipsecidtypestr[] = {
630 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
631 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
632 "keyid",
633 };
634 int len;
635 u_char *data;
636
637 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
638
639 p = (struct isakmp_pl_id *)ext;
640 if (sizeof(*p) < ext->len)
641 data = (u_char *)(p + 1);
642 else
643 data = NULL;
644 len = ntohs(ext->len) - sizeof(*p);
645
646 #if 0 /*debug*/
647 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
648 #endif
649 switch (phase) {
650 #ifndef USE_IPSECDOI_IN_PHASE1
651 case 1:
652 #endif
653 default:
654 printf(" idtype=%s", STR_OR_ID(p->d.id_type, idtypestr));
655 printf(" doi_data=%u",
656 (u_int32_t)(ntohl(p->d.doi_data) & 0xffffff));
657 break;
658
659 #ifdef USE_IPSECDOI_IN_PHASE1
660 case 1:
661 #endif
662 case 2:
663 {
664 struct ipsecdoi_id *p;
665 struct protoent *pe;
666
667 p = (struct ipsecdoi_id *)ext;
668 printf(" idtype=%s", STR_OR_ID(p->type, ipsecidtypestr));
669 if (p->proto_id) {
670 setprotoent(1);
671 pe = getprotobynumber(p->proto_id);
672 if (pe)
673 printf(" protoid=%s", pe->p_name);
674 endprotoent();
675 } else {
676 /* it DOES NOT mean IPPROTO_IP! */
677 printf(" protoid=%s", "0");
678 }
679 printf(" port=%d", ntohs(p->port));
680 if (!len)
681 break;
682 switch (p->type) {
683 case IPSECDOI_ID_IPV4_ADDR:
684 printf(" len=%d %s", len, ipaddr_string(data));
685 len = 0;
686 break;
687 case IPSECDOI_ID_FQDN:
688 case IPSECDOI_ID_USER_FQDN:
689 {
690 int i;
691 printf(" len=%d ", len);
692 for (i = 0; i < len; i++) {
693 if (isprint(data[i]))
694 printf("%c", data[i]);
695 else
696 printf("\\%03o", data[i]);
697 }
698 len = 0;
699 break;
700 }
701 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
702 {
703 u_char *mask;
704 mask = data + sizeof(struct in_addr);
705 printf(" len=%d %s/%u.%u.%u.%u", len,
706 ipaddr_string(data),
707 mask[0], mask[1], mask[2], mask[3]);
708 len = 0;
709 break;
710 }
711 #ifdef INET6
712 case IPSECDOI_ID_IPV6_ADDR:
713 printf(" len=%d %s", len, ip6addr_string(data));
714 len = 0;
715 break;
716 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
717 {
718 u_int32_t *mask;
719 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
720 /*XXX*/
721 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
722 ip6addr_string(data),
723 mask[0], mask[1], mask[2], mask[3]);
724 len = 0;
725 break;
726 }
727 #endif /*INET6*/
728 case IPSECDOI_ID_IPV4_ADDR_RANGE:
729 printf(" len=%d %s-%s", len, ipaddr_string(data),
730 ipaddr_string(data + sizeof(struct in_addr)));
731 len = 0;
732 break;
733 #ifdef INET6
734 case IPSECDOI_ID_IPV6_ADDR_RANGE:
735 printf(" len=%d %s-%s", len, ip6addr_string(data),
736 ip6addr_string(data + sizeof(struct in6_addr)));
737 len = 0;
738 break;
739 #endif /*INET6*/
740 case IPSECDOI_ID_DER_ASN1_DN:
741 case IPSECDOI_ID_DER_ASN1_GN:
742 case IPSECDOI_ID_KEY_ID:
743 break;
744 }
745 break;
746 }
747 }
748 if (data && len) {
749 len -= sizeof(*p);
750 printf(" len=%d", len);
751 if (2 < vflag) {
752 printf(" ");
753 rawprint((caddr_t)data, len);
754 }
755 }
756 return (u_char *)ext + ntohs(ext->len);
757 }
758
759 static u_char *
760 isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
761 u_int32_t doi0, u_int32_t proto0)
762 {
763 struct isakmp_pl_cert *p;
764 static char *certstr[] = {
765 "none", "pkcs7", "pgp", "dns",
766 "x509sign", "x509ke", "kerberos", "crl",
767 "arl", "spki", "x509attr",
768 };
769
770 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
771
772 p = (struct isakmp_pl_cert *)ext;
773 printf(" len=%d", ntohs(ext->len) - 4);
774 printf(" type=%s", STR_OR_ID((p->encode), certstr));
775 if (2 < vflag && 4 < ntohs(ext->len)) {
776 printf(" ");
777 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
778 }
779 return (u_char *)ext + ntohs(ext->len);
780 }
781
782 static u_char *
783 isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
784 u_int32_t doi0, u_int32_t proto0)
785 {
786 struct isakmp_pl_cert *p;
787 static char *certstr[] = {
788 "none", "pkcs7", "pgp", "dns",
789 "x509sign", "x509ke", "kerberos", "crl",
790 "arl", "spki", "x509attr",
791 };
792
793 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
794
795 p = (struct isakmp_pl_cert *)ext;
796 printf(" len=%d", ntohs(ext->len) - 4);
797 printf(" type=%s", STR_OR_ID((p->encode), certstr));
798 if (2 < vflag && 4 < ntohs(ext->len)) {
799 printf(" ");
800 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
801 }
802 return (u_char *)ext + ntohs(ext->len);
803 }
804
805 static u_char *
806 isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
807 u_int32_t doi, u_int32_t proto)
808 {
809 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
810
811 printf(" len=%d", ntohs(ext->len) - 4);
812 if (2 < vflag && 4 < ntohs(ext->len)) {
813 printf(" ");
814 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
815 }
816 return (u_char *)ext + ntohs(ext->len);
817 }
818
819 static u_char *
820 isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
821 u_int32_t doi, u_int32_t proto)
822 {
823 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
824
825 printf(" len=%d", ntohs(ext->len) - 4);
826 if (2 < vflag && 4 < ntohs(ext->len)) {
827 printf(" ");
828 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
829 }
830 return (u_char *)ext + ntohs(ext->len);
831 }
832
833 static u_char *
834 isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
835 u_int32_t doi, u_int32_t proto)
836 {
837 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
838
839 printf(" n len=%d", ntohs(ext->len) - 4);
840 if (2 < vflag && 4 < ntohs(ext->len)) {
841 printf(" ");
842 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
843 }
844 return (u_char *)ext + ntohs(ext->len);
845 }
846
847 static u_char *
848 isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
849 u_int32_t doi0, u_int32_t proto0)
850 {
851 struct isakmp_pl_n *p;
852 u_char *cp;
853 u_char *ep2;
854 u_int32_t doi;
855 u_int32_t proto;
856 static char *notifystr[] = {
857 NULL, "INVALID-PAYLOAD-TYPE",
858 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
859 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
860 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
861 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
862 "INVALID-PROTOCOL-ID", "INVALID-SPI",
863 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
864 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
865 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
866 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
867 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
868 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
869 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
870 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
871 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
872 "UNEQUAL-PAYLOAD-LENGTHS",
873 };
874 static char *ipsecnotifystr[] = {
875 "RESPONDER-LIFETIME", "REPLAY-STATUS",
876 "INITIAL-CONTACT",
877 };
878 /* NOTE: these macro must be called with x in proper range */
879 #define NOTIFYSTR(x) \
880 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr))
881 #define IPSECNOTIFYSTR(x) \
882 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr))
883
884 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
885
886 p = (struct isakmp_pl_n *)ext;
887 doi = ntohl(p->doi);
888 proto = p->prot_id;
889 if (doi != 1) {
890 printf(" doi=%d", doi);
891 printf(" proto=%d", proto);
892 printf(" type=%s", NOTIFYSTR(ntohs(p->type)));
893 if (p->spi_size) {
894 printf(" spi=");
895 rawprint((caddr_t)(p + 1), p->spi_size);
896 }
897 return (u_char *)(p + 1) + p->spi_size;
898 }
899
900 printf(" doi=ipsec");
901 printf(" proto=%s", PROTOIDSTR(proto));
902 if (ntohs(p->type) < 8192)
903 printf(" type=%s", NOTIFYSTR(ntohs(p->type)));
904 else if (ntohs(p->type) < 16384)
905 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p->type)));
906 else if (ntohs(p->type) < 24576)
907 printf(" type=%s", NOTIFYSTR(ntohs(p->type)));
908 else if (ntohs(p->type) < 40960)
909 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p->type)));
910 else
911 printf(" type=%s", NOTIFYSTR(ntohs(p->type)));
912 if (p->spi_size) {
913 printf(" spi=");
914 rawprint((caddr_t)(p + 1), p->spi_size);
915 }
916
917 cp = (u_char *)(p + 1) + p->spi_size;
918 ep2 = (u_char *)p + ntohs(ext->len);
919
920 if (cp < ep) {
921 printf(" orig=(");
922 switch (ntohs(p->type)) {
923 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
924 {
925 struct attrmap *map = oakley_t_map;
926 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
927 while (cp < ep && cp < ep2) {
928 cp = isakmp_attrmap_print(cp,
929 (ep < ep2) ? ep : ep2, map, nmap);
930 }
931 break;
932 }
933 case IPSECDOI_NTYPE_REPLAY_STATUS:
934 printf("replay detection %sabled",
935 (*(u_int32_t *)cp) ? "en" : "dis");
936 break;
937 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
938 isakmp_sub_print(ISAKMP_NPTYPE_SA,
939 (struct isakmp_gen *)cp, ep, phase, doi, proto);
940 break;
941 default:
942 /* NULL is dummy */
943 isakmp_print(cp,
944 ntohs(ext->len) - sizeof(*p) - p->spi_size,
945 NULL);
946 }
947 printf(")");
948 }
949 return (u_char *)ext + ntohs(ext->len);
950 }
951
952 static u_char *
953 isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
954 u_int32_t doi0, u_int32_t proto0)
955 {
956 struct isakmp_pl_d *p;
957 u_int8_t *q;
958 u_int32_t doi;
959 u_int32_t proto;
960 int i;
961
962 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
963
964 p = (struct isakmp_pl_d *)ext;
965 doi = ntohl(p->doi);
966 proto = p->prot_id;
967 if (doi != 1) {
968 printf(" doi=%u", doi);
969 printf(" proto=%u", proto);
970 } else {
971 printf(" doi=ipsec");
972 printf(" proto=%s", PROTOIDSTR(proto));
973 }
974 printf(" spilen=%u", p->spi_size);
975 printf(" nspi=%u", ntohs(p->num_spi));
976 printf(" spi=");
977 q = (u_int8_t *)(p + 1);
978 for (i = 0; i < ntohs(p->num_spi); i++) {
979 if (i != 0)
980 printf(",");
981 rawprint((caddr_t)q, p->spi_size);
982 q += p->spi_size;
983 }
984 return q;
985 }
986
987 static u_char *
988 isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
989 u_int32_t doi, u_int32_t proto)
990 {
991 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
992
993 printf(" len=%d", ntohs(ext->len) - 4);
994 if (2 < vflag && 4 < ntohs(ext->len)) {
995 printf(" ");
996 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4);
997 }
998 return (u_char *)ext + ntohs(ext->len);
999 }
1000
1001 static u_char *
1002 isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1003 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1004 {
1005 u_char *cp;
1006
1007 cp = (u_char *)ext;
1008
1009 if (NPFUNC(np))
1010 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto);
1011 else {
1012 printf("%s", NPSTR(np));
1013 cp += ntohs(ext->len);
1014 }
1015 return cp;
1016 }
1017
1018 static u_char *
1019 isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1020 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1021 {
1022 u_char *cp;
1023 static int depth = 0;
1024 int i;
1025
1026 cp = (u_char *)ext;
1027
1028 while (np) {
1029 if (ep < (u_char *)ext + ntohs(ext->len)) {
1030 printf(" [|%s]", NPSTR(np));
1031 cp = ep + 1;
1032 break;
1033 }
1034 depth++;
1035 printf("\n");
1036 for (i = 0; i < depth; i++)
1037 printf(" ");
1038 printf("(");
1039 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto);
1040 printf(")");
1041 depth--;
1042
1043 np = ext->np;
1044 ext = (struct isakmp_gen *)cp;
1045 }
1046 return cp;
1047 }
1048
1049 static char *
1050 numstr(int x)
1051 {
1052 static char buf[20];
1053 snprintf(buf, sizeof(buf), "#%d", x);
1054 return buf;
1055 }
1056
1057 void
1058 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1059 {
1060 struct isakmp *base;
1061 u_char *ep;
1062 u_char np;
1063 int i;
1064 int phase;
1065 int major, minor;
1066
1067 base = (struct isakmp *)bp;
1068 ep = (u_char *)snapend;
1069
1070 if ((struct isakmp *)ep < base + 1) {
1071 printf("[|isakmp]");
1072 return;
1073 }
1074
1075 printf("isakmp");
1076 if (vflag) {
1077 major = (base->vers & ISAKMP_VERS_MAJOR)
1078 >> ISAKMP_VERS_MAJOR_SHIFT;
1079 minor = (base->vers & ISAKMP_VERS_MINOR)
1080 >> ISAKMP_VERS_MINOR_SHIFT;
1081 printf(" %d.%d", major, minor);
1082 }
1083
1084 if (vflag) {
1085 printf(" msgid ");
1086 rawprint((caddr_t)&base->msgid, sizeof(base->msgid));
1087 }
1088
1089 if (1 < vflag) {
1090 printf(" cookie ");
1091 rawprint((caddr_t)&base->i_ck, sizeof(base->i_ck));
1092 printf("->");
1093 rawprint((caddr_t)&base->r_ck, sizeof(base->r_ck));
1094 }
1095 printf(":");
1096
1097 phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2;
1098 if (phase == 1)
1099 printf(" phase %d", phase);
1100 else
1101 printf(" phase %d/others", phase);
1102
1103 i = cookie_find(&base->i_ck);
1104 if (i < 0) {
1105 if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) {
1106 /* the first packet */
1107 printf(" I");
1108 if (bp2)
1109 cookie_record(&base->i_ck, bp2);
1110 } else
1111 printf(" ?");
1112 } else {
1113 if (bp2 && cookie_isinitiator(i, bp2))
1114 printf(" I");
1115 else if (bp2 && cookie_isresponder(i, bp2))
1116 printf(" R");
1117 else
1118 printf(" ?");
1119 }
1120
1121 printf(" %s", ETYPESTR(base->etype));
1122 if (base->flags) {
1123 printf("[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
1124 base->flags & ISAKMP_FLAG_C ? "C" : "");
1125 }
1126 printf(":");
1127
1128 {
1129 struct isakmp_gen *ext;
1130 int nparen;
1131
1132 #define CHECKLEN(p, np) \
1133 if (ep < (u_char *)(p)) { \
1134 printf(" [|%s]", NPSTR(np)); \
1135 goto done; \
1136 }
1137
1138 /* regardless of phase... */
1139 if (base->flags & ISAKMP_FLAG_E) {
1140 /*
1141 * encrypted, nothing we can do right now.
1142 * we hope to decrypt the packet in the future...
1143 */
1144 printf(" [|%s]", NPSTR(base->np));
1145 goto done;
1146 }
1147
1148 nparen = 0;
1149 CHECKLEN(base + 1, base->np)
1150
1151 np = base->np;
1152 ext = (struct isakmp_gen *)(base + 1);
1153 isakmp_sub_print(np, ext, ep, phase, 0, 0);
1154 }
1155
1156 done:
1157 if (vflag) {
1158 if (ntohl(base->len) != length) {
1159 printf(" (len mismatch: isakmp %u/ip %d)",
1160 (u_int32_t)ntohl(base->len), length);
1161 }
1162 }
1163 }