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