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