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