2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
32 static const char rcsid[] _U_ =
33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.36.2.11 2004/03/24 01:32:42 guy Exp $ (LBL)";
40 #include <tcpdump-stdinc.h>
47 #include "ipsec_doi.h"
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h" /* must come after interface.h */
58 #ifndef HAVE_SOCKADDR_STORAGE
59 #define sockaddr_storage sockaddr
62 static const u_char *isakmp_sa_print(const struct isakmp_gen *,
63 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
64 static const u_char *isakmp_p_print(const struct isakmp_gen *,
65 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
66 static const u_char *isakmp_t_print(const struct isakmp_gen *,
67 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
68 static const u_char *isakmp_ke_print(const struct isakmp_gen *,
69 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
70 static const u_char *isakmp_id_print(const struct isakmp_gen *,
71 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
72 static const u_char *isakmp_cert_print(const struct isakmp_gen *,
73 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
74 static const u_char *isakmp_cr_print(const struct isakmp_gen *,
75 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
76 static const u_char *isakmp_sig_print(const struct isakmp_gen *,
77 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
78 static const u_char *isakmp_hash_print(const struct isakmp_gen *,
79 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
80 static const u_char *isakmp_nonce_print(const struct isakmp_gen *,
81 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
82 static const u_char *isakmp_n_print(const struct isakmp_gen *,
83 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
84 static const u_char *isakmp_d_print(const struct isakmp_gen *,
85 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
86 static const u_char *isakmp_vid_print(const struct isakmp_gen *,
87 u_int, const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
88 static const u_char *isakmp_sub0_print(u_char, const struct isakmp_gen *,
89 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
90 static const u_char *isakmp_sub_print(u_char, const struct isakmp_gen *,
91 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
92 static char *numstr(int);
93 static void safememcpy(void *, const void *, size_t);
95 #define MAXINITIATORS 20
99 struct sockaddr_storage iaddr;
100 struct sockaddr_storage raddr;
101 } cookiecache[MAXINITIATORS];
104 static const char *protoidstr[] = {
105 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
109 static const char *npstr[] = {
110 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
111 "sig", "nonce", "n", "d", "vid"
115 static const u_char *(*npfunc[])(const struct isakmp_gen *, u_int,
116 const u_char *, u_int32_t, u_int32_t, u_int32_t, int) = {
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",
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)
149 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
150 ? npfunc[(x)] : NULL)
153 iszero(u_char *p, size_t l)
162 /* find cookie from initiator cache */
164 cookie_find(cookie_t *in)
168 for (i = 0; i < MAXINITIATORS; i++) {
169 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
176 /* record initiator */
178 cookie_record(cookie_t *in, const u_char *bp2)
182 struct sockaddr_in *sin;
185 struct sockaddr_in6 *sin6;
190 ninitiator = (i + 1) % MAXINITIATORS;
194 ip = (struct ip *)bp2;
197 memset(&cookiecache[ninitiator].iaddr, 0,
198 sizeof(cookiecache[ninitiator].iaddr));
199 memset(&cookiecache[ninitiator].raddr, 0,
200 sizeof(cookiecache[ninitiator].raddr));
202 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
203 #ifdef HAVE_SOCKADDR_SA_LEN
204 sin->sin_len = sizeof(struct sockaddr_in);
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);
212 sin->sin_family = AF_INET;
213 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
217 memset(&cookiecache[ninitiator].iaddr, 0,
218 sizeof(cookiecache[ninitiator].iaddr));
219 memset(&cookiecache[ninitiator].raddr, 0,
220 sizeof(cookiecache[ninitiator].raddr));
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);
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);
233 sin6->sin6_family = AF_INET6;
234 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
240 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
241 ninitiator = (ninitiator + 1) % MAXINITIATORS;
244 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
245 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
247 cookie_sidecheck(int i, const u_char *bp2, int initiator)
249 struct sockaddr_storage ss;
252 struct sockaddr_in *sin;
255 struct sockaddr_in6 *sin6;
259 memset(&ss, 0, sizeof(ss));
260 ip = (struct ip *)bp2;
263 sin = (struct sockaddr_in *)&ss;
264 #ifdef HAVE_SOCKADDR_SA_LEN
265 sin->sin_len = sizeof(struct sockaddr_in);
267 sin->sin_family = AF_INET;
268 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
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);
277 sin6->sin6_family = AF_INET6;
278 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
285 sa = (struct sockaddr *)&ss;
287 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
289 #ifdef HAVE_SOCKADDR_SA_LEN
293 if (sa->sa_family == AF_INET6)
294 salen = sizeof(struct sockaddr_in6);
296 salen = sizeof(struct sockaddr);
298 salen = sizeof(struct sockaddr);
301 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
304 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
306 #ifdef HAVE_SOCKADDR_SA_LEN
310 if (sa->sa_family == AF_INET6)
311 salen = sizeof(struct sockaddr_in6);
313 salen = sizeof(struct sockaddr);
315 salen = sizeof(struct sockaddr);
318 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
325 rawprint(caddr_t loc, size_t len)
333 for (i = 0; i < len; i++)
334 printf("%02x", p[i] & 0xff);
343 const char *value[30]; /*XXX*/
346 static const u_char *
347 isakmp_attrmap_print(const u_char *p, const u_char *ep,
348 const struct attrmap *map, size_t nmap)
358 totlen = 4 + EXTRACT_16BITS(&q[1]);
359 if (ep < p + totlen) {
365 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
366 if (map && t < nmap && map[t].type)
367 printf("type=%s ", map[t].type);
369 printf("type=#%d ", t);
372 v = EXTRACT_16BITS(&q[1]);
373 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
374 printf("%s", map[t].value[v]);
376 rawprint((caddr_t)&q[1], 2);
378 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
379 rawprint((caddr_t)&p[4], EXTRACT_16BITS(&q[1]));
385 static const u_char *
386 isakmp_attr_print(const u_char *p, const u_char *ep)
396 totlen = 4 + EXTRACT_16BITS(&q[1]);
397 if (ep < p + totlen) {
403 t = EXTRACT_16BITS(&q[0]) & 0x7fff;
404 printf("type=#%d ", t);
408 rawprint((caddr_t)&q[1], 2);
410 printf("len=%d value=", EXTRACT_16BITS(&q[1]));
411 rawprint((caddr_t)&p[2], EXTRACT_16BITS(&q[1]));
417 static const u_char *
418 isakmp_sa_print(const struct isakmp_gen *ext, u_int item_len,
419 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
420 u_int32_t proto0, int depth)
422 const struct isakmp_pl_sa *p;
423 struct isakmp_pl_sa sa;
425 u_int32_t doi, sit, ident;
426 const u_char *cp, *np;
429 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA));
431 p = (struct isakmp_pl_sa *)ext;
433 safememcpy(&sa, ext, sizeof(sa));
437 printf(" doi=%d", doi);
438 printf(" situation=%u", (u_int32_t)ntohl(sa.sit));
439 return (u_char *)(p + 1);
442 printf(" doi=ipsec");
443 q = (u_int32_t *)&sa.sit;
444 printf(" situation=");
451 printf("%ssecrecy", t ? "+" : "");
455 printf("%sintegrity", t ? "+" : "");
457 np = (u_char *)ext + sizeof(sa);
459 TCHECK2(*(ext + 1), sizeof(ident));
460 safememcpy(&ident, ext + 1, sizeof(ident));
461 printf(" ident=%u", (u_int32_t)ntohl(ident));
465 ext = (struct isakmp_gen *)np;
468 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
473 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA));
477 static const u_char *
478 isakmp_p_print(const struct isakmp_gen *ext, u_int item_len,
479 const u_char *ep, u_int32_t phase, u_int32_t doi0,
480 u_int32_t proto0 _U_, int depth)
482 const struct isakmp_pl_p *p;
483 struct isakmp_pl_p prop;
486 printf("%s:", NPSTR(ISAKMP_NPTYPE_P));
488 p = (struct isakmp_pl_p *)ext;
490 safememcpy(&prop, ext, sizeof(prop));
491 printf(" #%d protoid=%s transform=%d",
492 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t);
495 if (!rawprint((caddr_t)(p + 1), prop.spi_size))
499 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
502 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
503 prop.prot_id, depth);
507 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P));
511 static const char *isakmp_p_map[] = {
515 static const char *ah_p_map[] = {
516 NULL, "(reserved)", "md5", "sha", "1des",
517 "sha2-256", "sha2-384", "sha2-512",
520 static const char *esp_p_map[] = {
521 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
522 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
525 static const char *ipcomp_p_map[] = {
526 NULL, "oui", "deflate", "lzs",
529 const struct attrmap ipsec_t_map[] = {
530 { NULL, 0, { NULL } },
531 { "lifetype", 3, { NULL, "sec", "kb", }, },
532 { "life", 0, { NULL } },
533 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
535 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
536 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
537 { "keylen", 0, { NULL } },
538 { "rounds", 0, { NULL } },
539 { "dictsize", 0, { NULL } },
540 { "privalg", 0, { NULL } },
543 const struct attrmap oakley_t_map[] = {
544 { NULL, 0, { NULL } },
545 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
546 "3des", "cast", "aes", }, },
547 { "hash", 7, { NULL, "md5", "sha1", "tiger",
548 "sha2-256", "sha2-384", "sha2-512", }, },
549 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
550 "rsa enc revised", }, },
551 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
553 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
554 { "group prime", 0, { NULL } },
555 { "group gen1", 0, { NULL } },
556 { "group gen2", 0, { NULL } },
557 { "group curve A", 0, { NULL } },
558 { "group curve B", 0, { NULL } },
559 { "lifetype", 3, { NULL, "sec", "kb", }, },
560 { "lifeduration", 0, { NULL } },
561 { "prf", 0, { NULL } },
562 { "keylen", 0, { NULL } },
563 { "field", 0, { NULL } },
564 { "order", 0, { NULL } },
567 static const u_char *
568 isakmp_t_print(const struct isakmp_gen *ext, u_int item_len,
569 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
570 u_int32_t proto, int depth _U_)
572 const struct isakmp_pl_t *p;
573 struct isakmp_pl_t t;
576 const struct attrmap *map;
580 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
582 p = (struct isakmp_pl_t *)ext;
584 safememcpy(&t, ext, sizeof(t));
588 idstr = STR_OR_ID(t.t_id, isakmp_p_map);
590 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
593 idstr = STR_OR_ID(t.t_id, ah_p_map);
595 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
598 idstr = STR_OR_ID(t.t_id, esp_p_map);
600 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
603 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
605 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
615 printf(" #%d id=%s ", t.t_no, idstr);
617 printf(" #%d id=%d ", t.t_no, t.t_id);
618 cp = (u_char *)(p + 1);
619 ep2 = (u_char *)p + item_len;
620 while (cp < ep && cp < ep2) {
622 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
625 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
631 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T));
635 static const u_char *
636 isakmp_ke_print(const struct isakmp_gen *ext, u_int item_len,
637 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
638 u_int32_t proto _U_, int depth _U_)
642 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
645 safememcpy(&e, ext, sizeof(e));
646 printf(" key len=%d", ntohs(e.len) - 4);
647 if (2 < vflag && 4 < ntohs(e.len)) {
649 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
652 return (u_char *)ext + ntohs(e.len);
654 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE));
658 static const u_char *
659 isakmp_id_print(const struct isakmp_gen *ext, u_int item_len,
660 const u_char *ep, u_int32_t phase, u_int32_t doi _U_,
661 u_int32_t proto _U_, int depth _U_)
663 #define USE_IPSECDOI_IN_PHASE1 1
664 const struct isakmp_pl_id *p;
665 struct isakmp_pl_id id;
666 static const char *idtypestr[] = {
667 "IPv4", "IPv4net", "IPv6", "IPv6net",
669 static const char *ipsecidtypestr[] = {
670 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
671 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
677 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
679 p = (struct isakmp_pl_id *)ext;
681 safememcpy(&id, ext, sizeof(id));
682 if (sizeof(*p) < item_len) {
683 data = (u_char *)(p + 1);
684 len = item_len - sizeof(*p);
691 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
694 #ifndef USE_IPSECDOI_IN_PHASE1
698 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr));
699 printf(" doi_data=%u",
700 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff));
703 #ifdef USE_IPSECDOI_IN_PHASE1
708 const struct ipsecdoi_id *p;
709 struct ipsecdoi_id id;
712 p = (struct ipsecdoi_id *)ext;
714 safememcpy(&id, ext, sizeof(id));
715 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr));
720 pe = getprotobynumber(id.proto_id);
722 printf(" protoid=%s", pe->p_name);
727 /* it DOES NOT mean IPPROTO_IP! */
728 printf(" protoid=%s", "0");
730 printf(" port=%d", ntohs(id.port));
737 case IPSECDOI_ID_IPV4_ADDR:
739 printf(" len=%d [bad: < 4]", len);
741 printf(" len=%d %s", len, ipaddr_string(data));
744 case IPSECDOI_ID_FQDN:
745 case IPSECDOI_ID_USER_FQDN:
748 printf(" len=%d ", len);
749 for (i = 0; i < len; i++)
750 safeputchar(data[i]);
754 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
758 printf(" len=%d [bad: < 8]", len);
760 mask = data + sizeof(struct in_addr);
761 printf(" len=%d %s/%u.%u.%u.%u", len,
763 mask[0], mask[1], mask[2], mask[3]);
769 case IPSECDOI_ID_IPV6_ADDR:
771 printf(" len=%d [bad: < 16]", len);
773 printf(" len=%d %s", len, ip6addr_string(data));
776 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
778 const u_int32_t *mask;
780 printf(" len=%d [bad: < 20]", len);
782 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
784 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
785 ip6addr_string(data),
786 mask[0], mask[1], mask[2], mask[3]);
792 case IPSECDOI_ID_IPV4_ADDR_RANGE:
794 printf(" len=%d [bad: < 8]", len);
796 printf(" len=%d %s-%s", len,
798 ipaddr_string(data + sizeof(struct in_addr)));
803 case IPSECDOI_ID_IPV6_ADDR_RANGE:
805 printf(" len=%d [bad: < 32]", len);
807 printf(" len=%d %s-%s", len,
808 ip6addr_string(data),
809 ip6addr_string(data + sizeof(struct in6_addr)));
814 case IPSECDOI_ID_DER_ASN1_DN:
815 case IPSECDOI_ID_DER_ASN1_GN:
816 case IPSECDOI_ID_KEY_ID:
823 printf(" len=%d", len);
826 if (!rawprint((caddr_t)data, len))
830 return (u_char *)ext + item_len;
832 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID));
836 static const u_char *
837 isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len,
838 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
839 u_int32_t proto0 _U_, int depth _U_)
841 const struct isakmp_pl_cert *p;
842 struct isakmp_pl_cert cert;
843 static const char *certstr[] = {
844 "none", "pkcs7", "pgp", "dns",
845 "x509sign", "x509ke", "kerberos", "crl",
846 "arl", "spki", "x509attr",
849 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
851 p = (struct isakmp_pl_cert *)ext;
853 safememcpy(&cert, ext, sizeof(cert));
854 printf(" len=%d", item_len - 4);
855 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
856 if (2 < vflag && 4 < item_len) {
858 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
861 return (u_char *)ext + item_len;
863 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT));
867 static const u_char *
868 isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len,
869 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
870 u_int32_t proto0 _U_, int depth _U_)
872 const struct isakmp_pl_cert *p;
873 struct isakmp_pl_cert cert;
874 static const char *certstr[] = {
875 "none", "pkcs7", "pgp", "dns",
876 "x509sign", "x509ke", "kerberos", "crl",
877 "arl", "spki", "x509attr",
880 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
882 p = (struct isakmp_pl_cert *)ext;
884 safememcpy(&cert, ext, sizeof(cert));
885 printf(" len=%d", item_len - 4);
886 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
887 if (2 < vflag && 4 < item_len) {
889 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
892 return (u_char *)ext + item_len;
894 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR));
898 static const u_char *
899 isakmp_hash_print(const struct isakmp_gen *ext, u_int item_len,
900 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
901 u_int32_t proto _U_, int depth _U_)
905 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
908 safememcpy(&e, ext, sizeof(e));
909 printf(" len=%d", ntohs(e.len) - 4);
910 if (2 < vflag && 4 < ntohs(e.len)) {
912 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
915 return (u_char *)ext + ntohs(e.len);
917 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH));
921 static const u_char *
922 isakmp_sig_print(const struct isakmp_gen *ext, u_int item_len,
923 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
924 u_int32_t proto _U_, int depth _U_)
928 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
931 safememcpy(&e, ext, sizeof(e));
932 printf(" len=%d", ntohs(e.len) - 4);
933 if (2 < vflag && 4 < ntohs(e.len)) {
935 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
938 return (u_char *)ext + ntohs(e.len);
940 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG));
944 static const u_char *
945 isakmp_nonce_print(const struct isakmp_gen *ext, u_int item_len,
946 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
947 u_int32_t proto _U_, int depth _U_)
951 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
954 safememcpy(&e, ext, sizeof(e));
955 printf(" n len=%d", ntohs(e.len) - 4);
956 if (2 < vflag && 4 < ntohs(e.len)) {
958 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
961 return (u_char *)ext + ntohs(e.len);
963 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE));
967 static const u_char *
968 isakmp_n_print(const struct isakmp_gen *ext, u_int item_len,
969 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
970 u_int32_t proto0 _U_, int depth)
972 struct isakmp_pl_n *p, n;
977 static const char *notify_error_str[] = {
978 NULL, "INVALID-PAYLOAD-TYPE",
979 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
980 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
981 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
982 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
983 "INVALID-PROTOCOL-ID", "INVALID-SPI",
984 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
985 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
986 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
987 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
988 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
989 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
990 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
991 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
992 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
993 "UNEQUAL-PAYLOAD-LENGTHS",
995 static const char *ipsec_notify_error_str[] = {
998 static const char *notify_status_str[] = {
1001 static const char *ipsec_notify_status_str[] = {
1002 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1005 /* NOTE: these macro must be called with x in proper range */
1008 #define NOTIFY_ERROR_STR(x) \
1009 STR_OR_ID((x), notify_error_str)
1012 #define IPSEC_NOTIFY_ERROR_STR(x) \
1013 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1016 #define NOTIFY_STATUS_STR(x) \
1017 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1020 #define IPSEC_NOTIFY_STATUS_STR(x) \
1021 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1023 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
1025 p = (struct isakmp_pl_n *)ext;
1027 safememcpy(&n, ext, sizeof(n));
1031 printf(" doi=%d", doi);
1032 printf(" proto=%d", proto);
1033 if (ntohs(n.type) < 8192)
1034 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1035 else if (ntohs(n.type) < 16384)
1036 printf(" type=%s", numstr(ntohs(n.type)));
1037 else if (ntohs(n.type) < 24576)
1038 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1040 printf(" type=%s", numstr(ntohs(n.type)));
1043 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1046 return (u_char *)(p + 1) + n.spi_size;
1049 printf(" doi=ipsec");
1050 printf(" proto=%s", PROTOIDSTR(proto));
1051 if (ntohs(n.type) < 8192)
1052 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1053 else if (ntohs(n.type) < 16384)
1054 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)));
1055 else if (ntohs(n.type) < 24576)
1056 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1057 else if (ntohs(n.type) < 32768)
1058 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)));
1060 printf(" type=%s", numstr(ntohs(n.type)));
1063 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1067 cp = (u_char *)(p + 1) + n.spi_size;
1068 ep2 = (u_char *)p + item_len;
1072 switch (ntohs(n.type)) {
1073 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1075 const struct attrmap *map = oakley_t_map;
1076 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1077 while (cp < ep && cp < ep2) {
1078 cp = isakmp_attrmap_print(cp,
1079 (ep < ep2) ? ep : ep2, map, nmap);
1083 case IPSECDOI_NTYPE_REPLAY_STATUS:
1084 printf("replay detection %sabled",
1085 (*(u_int32_t *)cp) ? "en" : "dis");
1087 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1088 if (isakmp_sub_print(ISAKMP_NPTYPE_SA,
1089 (struct isakmp_gen *)cp, ep, phase, doi, proto,
1095 isakmp_print(cp, item_len - sizeof(*p) - n.spi_size,
1100 return (u_char *)ext + item_len;
1102 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N));
1106 static const u_char *
1107 isakmp_d_print(const struct isakmp_gen *ext, u_int item_len,
1108 const u_char *ep, u_int32_t phase _U_, u_int32_t doi0 _U_,
1109 u_int32_t proto0 _U_, int depth _U_)
1111 const struct isakmp_pl_d *p;
1112 struct isakmp_pl_d d;
1118 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
1120 p = (struct isakmp_pl_d *)ext;
1122 safememcpy(&d, ext, sizeof(d));
1126 printf(" doi=%u", doi);
1127 printf(" proto=%u", proto);
1129 printf(" doi=ipsec");
1130 printf(" proto=%s", PROTOIDSTR(proto));
1132 printf(" spilen=%u", d.spi_size);
1133 printf(" nspi=%u", ntohs(d.num_spi));
1135 q = (u_int8_t *)(p + 1);
1136 for (i = 0; i < ntohs(d.num_spi); i++) {
1139 if (!rawprint((caddr_t)q, d.spi_size))
1145 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D));
1149 static const u_char *
1150 isakmp_vid_print(const struct isakmp_gen *ext, u_int item_len,
1151 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
1152 u_int32_t proto _U_, int depth _U_)
1154 struct isakmp_gen e;
1156 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1159 safememcpy(&e, ext, sizeof(e));
1160 printf(" len=%d", ntohs(e.len) - 4);
1161 if (2 < vflag && 4 < ntohs(e.len)) {
1163 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
1166 return (u_char *)ext + ntohs(e.len);
1168 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID));
1172 static const u_char *
1173 isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1174 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1177 struct isakmp_gen e;
1182 safememcpy(&e, ext, sizeof(e));
1185 * Since we can't have a payload length of less than 4 bytes,
1186 * we need to bail out here if the generic header is nonsensical
1187 * or truncated, otherwise we could loop forever processing
1188 * zero-length items or otherwise misdissect the packet.
1190 item_len = ntohs(e.len);
1196 * XXX - what if item_len is too short, or too long,
1197 * for this payload type?
1199 cp = (*NPFUNC(np))(ext, item_len, ep, phase, doi, proto, depth);
1201 printf("%s", NPSTR(np));
1207 printf(" [|isakmp]");
1211 static const u_char *
1212 isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1213 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1217 struct isakmp_gen e;
1219 cp = (const u_char *)ext;
1224 safememcpy(&e, ext, sizeof(e));
1226 TCHECK2(*ext, ntohs(e.len));
1230 for (i = 0; i < depth; i++)
1233 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth);
1238 /* Zero-length subitem */
1243 ext = (struct isakmp_gen *)cp;
1247 printf(" [|%s]", NPSTR(np));
1254 static char buf[20];
1255 snprintf(buf, sizeof(buf), "#%d", x);
1260 * some compiler tries to optimize memcpy(), using the alignment constraint
1261 * on the argument pointer type. by using this function, we try to avoid the
1265 safememcpy(void *p, const void *q, size_t l)
1271 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1273 const struct isakmp *p;
1281 p = (const struct isakmp *)bp;
1284 if ((struct isakmp *)ep < p + 1) {
1285 printf("[|isakmp]");
1289 safememcpy(&base, p, sizeof(base));
1293 major = (base.vers & ISAKMP_VERS_MAJOR)
1294 >> ISAKMP_VERS_MAJOR_SHIFT;
1295 minor = (base.vers & ISAKMP_VERS_MINOR)
1296 >> ISAKMP_VERS_MINOR_SHIFT;
1297 printf(" %d.%d", major, minor);
1302 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1307 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1309 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1313 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1315 printf(" phase %d", phase);
1317 printf(" phase %d/others", phase);
1319 i = cookie_find(&base.i_ck);
1321 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1322 /* the first packet */
1325 cookie_record(&base.i_ck, bp2);
1329 if (bp2 && cookie_isinitiator(i, bp2))
1331 else if (bp2 && cookie_isresponder(i, bp2))
1337 printf(" %s", ETYPESTR(base.etype));
1339 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1340 base.flags & ISAKMP_FLAG_C ? "C" : "");
1344 const struct isakmp_gen *ext;
1347 #define CHECKLEN(p, np) \
1348 if (ep < (u_char *)(p)) { \
1349 printf(" [|%s]", NPSTR(np)); \
1355 /* regardless of phase... */
1356 if (base.flags & ISAKMP_FLAG_E) {
1358 * encrypted, nothing we can do right now.
1359 * we hope to decrypt the packet in the future...
1361 printf(" [encrypted %s]", NPSTR(base.np));
1366 CHECKLEN(p + 1, base.np)
1369 ext = (struct isakmp_gen *)(p + 1);
1370 isakmp_sub_print(np, ext, ep, phase, 0, 0, 0);
1375 if (ntohl(base.len) != length) {
1376 printf(" (len mismatch: isakmp %u/ip %u)",
1377 (u_int32_t)ntohl(base.len), length);