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