]> The Tcpdump Group git mirrors - tcpdump/blob - print-isakmp.c
Add a few more GCC warnings on GCC >= 2 for ".devel" builds.
[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.33 2002-09-05 00:00:13 guy 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 const char *protoidstr[] = {
105 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
106 };
107
108 /* isakmp->np */
109 static const 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 const 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 size_t 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 const char *type;
337 u_int nvalue;
338 const 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 const char *isakmp_p_map[] = {
489 NULL, "ike",
490 };
491
492 static const char *ah_p_map[] = {
493 NULL, "(reserved)", "md5", "sha", "1des",
494 "sha2-256", "sha2-384", "sha2-512",
495 };
496
497 static const 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 const char *ipcomp_p_map[] = {
503 NULL, "oui", "deflate", "lzs",
504 };
505
506 struct attrmap ipsec_t_map[] = {
507 { NULL, 0, { NULL } },
508 { "lifetype", 3, { NULL, "sec", "kb", }, },
509 { "life", 0, { NULL } },
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, { NULL } },
515 { "rounds", 0, { NULL } },
516 { "dictsize", 0, { NULL } },
517 { "privalg", 0, { NULL } },
518 };
519
520 struct attrmap oakley_t_map[] = {
521 { NULL, 0, { NULL } },
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, { NULL } },
532 { "group gen1", 0, { NULL } },
533 { "group gen2", 0, { NULL } },
534 { "group curve A", 0, { NULL } },
535 { "group curve B", 0, { NULL } },
536 { "lifetype", 3, { NULL, "sec", "kb", }, },
537 { "lifeduration", 0, { NULL } },
538 { "prf", 0, { NULL } },
539 { "keylen", 0, { NULL } },
540 { "field", 0, { NULL } },
541 { "order", 0, { NULL } },
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 const 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 const char *idtypestr[] = {
630 "IPv4", "IPv4net", "IPv6", "IPv6net",
631 };
632 static const 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 const 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 const 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 const char *notify_error_str[] = {
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 const char *ipsec_notify_error_str[] = {
890 "RESERVED",
891 };
892 static const char *notify_status_str[] = {
893 "CONNECTED",
894 };
895 static const char *ipsec_notify_status_str[] = {
896 "RESPONDER-LIFETIME", "REPLAY-STATUS",
897 "INITIAL-CONTACT",
898 };
899 /* NOTE: these macro must be called with x in proper range */
900
901 /* 0 - 8191 */
902 #define NOTIFY_ERROR_STR(x) \
903 STR_OR_ID((x), notify_error_str)
904
905 /* 8192 - 16383 */
906 #define IPSEC_NOTIFY_ERROR_STR(x) \
907 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
908
909 /* 16384 - 24575 */
910 #define NOTIFY_STATUS_STR(x) \
911 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
912
913 /* 24576 - 32767 */
914 #define IPSEC_NOTIFY_STATUS_STR(x) \
915 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
916
917 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
918
919 p = (struct isakmp_pl_n *)ext;
920 safememcpy(&n, ext, sizeof(n));
921 doi = ntohl(n.doi);
922 proto = n.prot_id;
923 if (doi != 1) {
924 printf(" doi=%d", doi);
925 printf(" proto=%d", proto);
926 if (ntohs(n.type) < 8192)
927 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
928 else if (ntohs(n.type) < 16384)
929 printf(" type=%s", numstr(ntohs(n.type)));
930 else if (ntohs(n.type) < 24576)
931 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
932 else
933 printf(" type=%s", numstr(ntohs(n.type)));
934 if (n.spi_size) {
935 printf(" spi=");
936 rawprint((caddr_t)(p + 1), n.spi_size);
937 }
938 return (u_char *)(p + 1) + n.spi_size;
939 }
940
941 printf(" doi=ipsec");
942 printf(" proto=%s", PROTOIDSTR(proto));
943 if (ntohs(n.type) < 8192)
944 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
945 else if (ntohs(n.type) < 16384)
946 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)));
947 else if (ntohs(n.type) < 24576)
948 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
949 else if (ntohs(n.type) < 32768)
950 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)));
951 else
952 printf(" type=%s", numstr(ntohs(n.type)));
953 if (n.spi_size) {
954 printf(" spi=");
955 rawprint((caddr_t)(p + 1), n.spi_size);
956 }
957
958 cp = (u_char *)(p + 1) + n.spi_size;
959 ep2 = (u_char *)p + ntohs(n.h.len);
960
961 if (cp < ep) {
962 printf(" orig=(");
963 switch (ntohs(n.type)) {
964 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
965 {
966 struct attrmap *map = oakley_t_map;
967 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
968 while (cp < ep && cp < ep2) {
969 cp = isakmp_attrmap_print(cp,
970 (ep < ep2) ? ep : ep2, map, nmap);
971 }
972 break;
973 }
974 case IPSECDOI_NTYPE_REPLAY_STATUS:
975 printf("replay detection %sabled",
976 (*(u_int32_t *)cp) ? "en" : "dis");
977 break;
978 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
979 isakmp_sub_print(ISAKMP_NPTYPE_SA,
980 (struct isakmp_gen *)cp, ep, phase, doi, proto);
981 break;
982 default:
983 /* NULL is dummy */
984 isakmp_print(cp,
985 ntohs(n.h.len) - sizeof(*p) - n.spi_size,
986 NULL);
987 }
988 printf(")");
989 }
990 return (u_char *)ext + ntohs(n.h.len);
991 }
992
993 static u_char *
994 isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
995 u_int32_t doi0, u_int32_t proto0)
996 {
997 struct isakmp_pl_d *p, d;
998 u_int8_t *q;
999 u_int32_t doi;
1000 u_int32_t proto;
1001 int i;
1002
1003 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
1004
1005 p = (struct isakmp_pl_d *)ext;
1006 safememcpy(&d, ext, sizeof(d));
1007 doi = ntohl(d.doi);
1008 proto = d.prot_id;
1009 if (doi != 1) {
1010 printf(" doi=%u", doi);
1011 printf(" proto=%u", proto);
1012 } else {
1013 printf(" doi=ipsec");
1014 printf(" proto=%s", PROTOIDSTR(proto));
1015 }
1016 printf(" spilen=%u", d.spi_size);
1017 printf(" nspi=%u", ntohs(d.num_spi));
1018 printf(" spi=");
1019 q = (u_int8_t *)(p + 1);
1020 for (i = 0; i < ntohs(d.num_spi); i++) {
1021 if (i != 0)
1022 printf(",");
1023 rawprint((caddr_t)q, d.spi_size);
1024 q += d.spi_size;
1025 }
1026 return q;
1027 }
1028
1029 static u_char *
1030 isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
1031 u_int32_t doi, u_int32_t proto)
1032 {
1033 struct isakmp_gen e;
1034
1035 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1036
1037 safememcpy(&e, ext, sizeof(e));
1038 printf(" len=%d", ntohs(e.len) - 4);
1039 if (2 < vflag && 4 < ntohs(e.len)) {
1040 printf(" ");
1041 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
1042 }
1043 return (u_char *)ext + ntohs(e.len);
1044 }
1045
1046 static u_char *
1047 isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1048 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1049 {
1050 u_char *cp;
1051 struct isakmp_gen e;
1052
1053 cp = (u_char *)ext;
1054 safememcpy(&e, ext, sizeof(e));
1055
1056 if (NPFUNC(np))
1057 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto);
1058 else {
1059 printf("%s", NPSTR(np));
1060 cp += ntohs(e.len);
1061 }
1062 return cp;
1063 }
1064
1065 static u_char *
1066 isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1067 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1068 {
1069 u_char *cp;
1070 static int depth = 0;
1071 int i;
1072 struct isakmp_gen e;
1073
1074 cp = (u_char *)ext;
1075
1076 while (np) {
1077 safememcpy(&e, ext, sizeof(e));
1078
1079 if (ep < (u_char *)ext + ntohs(e.len)) {
1080 printf(" [|%s]", NPSTR(np));
1081 cp = ep + 1;
1082 break;
1083 }
1084 depth++;
1085 printf("\n");
1086 for (i = 0; i < depth; i++)
1087 printf(" ");
1088 printf("(");
1089 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto);
1090 printf(")");
1091 depth--;
1092
1093 np = e.np;
1094 ext = (struct isakmp_gen *)cp;
1095 }
1096 return cp;
1097 }
1098
1099 static char *
1100 numstr(int x)
1101 {
1102 static char buf[20];
1103 snprintf(buf, sizeof(buf), "#%d", x);
1104 return buf;
1105 }
1106
1107 /*
1108 * some compiler tries to optimize memcpy(), using the alignment constraint
1109 * on the argument pointer type. by using this function, we try to avoid the
1110 * optimization.
1111 */
1112 static void
1113 safememcpy(void *p, void *q, size_t l)
1114 {
1115 memcpy(p, q, l);
1116 }
1117
1118 void
1119 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1120 {
1121 struct isakmp *p, base;
1122 u_char *ep;
1123 u_char np;
1124 int i;
1125 int phase;
1126 int major, minor;
1127
1128 p = (struct isakmp *)bp;
1129 ep = (u_char *)snapend;
1130
1131 if ((struct isakmp *)ep < p + 1) {
1132 printf("[|isakmp]");
1133 return;
1134 }
1135
1136 safememcpy(&base, p, sizeof(base));
1137
1138 printf("isakmp");
1139 if (vflag) {
1140 major = (base.vers & ISAKMP_VERS_MAJOR)
1141 >> ISAKMP_VERS_MAJOR_SHIFT;
1142 minor = (base.vers & ISAKMP_VERS_MINOR)
1143 >> ISAKMP_VERS_MINOR_SHIFT;
1144 printf(" %d.%d", major, minor);
1145 }
1146
1147 if (vflag) {
1148 printf(" msgid ");
1149 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1150 }
1151
1152 if (1 < vflag) {
1153 printf(" cookie ");
1154 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1155 printf("->");
1156 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1157 }
1158 printf(":");
1159
1160 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1161 if (phase == 1)
1162 printf(" phase %d", phase);
1163 else
1164 printf(" phase %d/others", phase);
1165
1166 i = cookie_find(&base.i_ck);
1167 if (i < 0) {
1168 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1169 /* the first packet */
1170 printf(" I");
1171 if (bp2)
1172 cookie_record(&base.i_ck, bp2);
1173 } else
1174 printf(" ?");
1175 } else {
1176 if (bp2 && cookie_isinitiator(i, bp2))
1177 printf(" I");
1178 else if (bp2 && cookie_isresponder(i, bp2))
1179 printf(" R");
1180 else
1181 printf(" ?");
1182 }
1183
1184 printf(" %s", ETYPESTR(base.etype));
1185 if (base.flags) {
1186 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1187 base.flags & ISAKMP_FLAG_C ? "C" : "");
1188 }
1189 printf(":");
1190
1191 {
1192 struct isakmp_gen *ext;
1193 int nparen;
1194
1195 #define CHECKLEN(p, np) \
1196 if (ep < (u_char *)(p)) { \
1197 printf(" [|%s]", NPSTR(np)); \
1198 goto done; \
1199 }
1200
1201 /* regardless of phase... */
1202 if (base.flags & ISAKMP_FLAG_E) {
1203 /*
1204 * encrypted, nothing we can do right now.
1205 * we hope to decrypt the packet in the future...
1206 */
1207 printf(" [encrypted %s]", NPSTR(base.np));
1208 goto done;
1209 }
1210
1211 nparen = 0;
1212 CHECKLEN(p + 1, base.np)
1213
1214 np = base.np;
1215 ext = (struct isakmp_gen *)(p + 1);
1216 isakmp_sub_print(np, ext, ep, phase, 0, 0);
1217 }
1218
1219 done:
1220 if (vflag) {
1221 if (ntohl(base.len) != length) {
1222 printf(" (len mismatch: isakmp %u/ip %d)",
1223 (u_int32_t)ntohl(base.len), length);
1224 }
1225 }
1226 }