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