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