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