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