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[] =
33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29 2001/10/26 03:41:29 itojun Exp $ (LBL)";
42 #include <sys/param.h>
44 #include <sys/socket.h>
49 #include <netinet/in.h>
55 #include "ipsec_doi.h"
57 #include "interface.h"
58 #include "addrtoname.h"
59 #include "extract.h" /* must come after interface.h */
66 #ifndef HAVE_SOCKADDR_STORAGE
67 #define sockaddr_storage sockaddr
70 static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t,
71 u_int32_t, u_int32_t);
72 static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t,
73 u_int32_t, u_int32_t);
74 static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t,
75 u_int32_t, u_int32_t);
76 static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t,
77 u_int32_t, u_int32_t);
78 static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t,
79 u_int32_t, u_int32_t);
80 static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t,
81 u_int32_t, u_int32_t);
82 static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t,
83 u_int32_t, u_int32_t);
84 static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t,
85 u_int32_t, u_int32_t);
86 static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *,
87 u_int32_t, u_int32_t, u_int32_t);
88 static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *,
89 u_int32_t, u_int32_t, u_int32_t);
90 static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t,
91 u_int32_t, u_int32_t);
92 static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t,
93 u_int32_t, u_int32_t);
94 static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t,
95 u_int32_t, u_int32_t);
96 static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *,
97 u_int32_t, u_int32_t, u_int32_t);
98 static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *,
99 u_int32_t, u_int32_t, u_int32_t);
100 static char *numstr(int);
101 static void safememcpy(void *, void *, size_t);
103 #define MAXINITIATORS 20
107 struct sockaddr_storage iaddr;
108 struct sockaddr_storage raddr;
109 } cookiecache[MAXINITIATORS];
112 static char *protoidstr[] = {
113 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
117 static char *npstr[] = {
118 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
119 "sig", "nonce", "n", "d", "vid"
123 static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t,
124 u_int32_t, u_int32_t) = {
142 static char *etypestr[] = {
143 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL,
144 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
145 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
146 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
147 "oakley-quick", "oakley-newgroup",
150 #define STR_OR_ID(x, tab) \
151 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
152 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
153 #define NPSTR(x) STR_OR_ID(x, npstr)
154 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
157 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
158 ? npfunc[(x)] : NULL)
161 iszero(u_char *p, size_t l)
170 /* find cookie from initiator cache */
172 cookie_find(cookie_t *in)
176 for (i = 0; i < MAXINITIATORS; i++) {
177 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
184 /* record initiator */
186 cookie_record(cookie_t *in, const u_char *bp2)
190 struct sockaddr_in *sin;
193 struct sockaddr_in6 *sin6;
198 ninitiator = (i + 1) % MAXINITIATORS;
202 ip = (struct ip *)bp2;
205 memset(&cookiecache[ninitiator].iaddr, 0,
206 sizeof(cookiecache[ninitiator].iaddr));
207 memset(&cookiecache[ninitiator].raddr, 0,
208 sizeof(cookiecache[ninitiator].raddr));
210 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
211 #ifdef HAVE_SOCKADDR_SA_LEN
212 sin->sin_len = sizeof(struct sockaddr_in);
214 sin->sin_family = AF_INET;
215 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
216 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
217 #ifdef HAVE_SOCKADDR_SA_LEN
218 sin->sin_len = sizeof(struct sockaddr_in);
220 sin->sin_family = AF_INET;
221 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
225 memset(&cookiecache[ninitiator].iaddr, 0,
226 sizeof(cookiecache[ninitiator].iaddr));
227 memset(&cookiecache[ninitiator].raddr, 0,
228 sizeof(cookiecache[ninitiator].raddr));
230 ip6 = (struct ip6_hdr *)bp2;
231 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
232 #ifdef HAVE_SOCKADDR_SA_LEN
233 sin6->sin6_len = sizeof(struct sockaddr_in6);
235 sin6->sin6_family = AF_INET6;
236 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
237 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
238 #ifdef HAVE_SOCKADDR_SA_LEN
239 sin6->sin6_len = sizeof(struct sockaddr_in6);
241 sin6->sin6_family = AF_INET6;
242 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
248 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
249 ninitiator = (ninitiator + 1) % MAXINITIATORS;
252 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
253 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
255 cookie_sidecheck(int i, const u_char *bp2, int initiator)
257 struct sockaddr_storage ss;
260 struct sockaddr_in *sin;
263 struct sockaddr_in6 *sin6;
267 memset(&ss, 0, sizeof(ss));
268 ip = (struct ip *)bp2;
271 sin = (struct sockaddr_in *)&ss;
272 #ifdef HAVE_SOCKADDR_SA_LEN
273 sin->sin_len = sizeof(struct sockaddr_in);
275 sin->sin_family = AF_INET;
276 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
280 ip6 = (struct ip6_hdr *)bp2;
281 sin6 = (struct sockaddr_in6 *)&ss;
282 #ifdef HAVE_SOCKADDR_SA_LEN
283 sin6->sin6_len = sizeof(struct sockaddr_in6);
285 sin6->sin6_family = AF_INET6;
286 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
293 sa = (struct sockaddr *)&ss;
295 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
297 #ifdef HAVE_SOCKADDR_SA_LEN
301 if (sa->sa_family == AF_INET6)
302 salen = sizeof(struct sockaddr_in6);
304 salen = sizeof(struct sockaddr);
306 salen = sizeof(struct sockaddr);
309 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
312 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
314 #ifdef HAVE_SOCKADDR_SA_LEN
318 if (sa->sa_family == AF_INET6)
319 salen = sizeof(struct sockaddr_in6);
321 salen = sizeof(struct sockaddr);
323 salen = sizeof(struct sockaddr);
326 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
333 rawprint(caddr_t loc, size_t len)
339 for (i = 0; i < len; i++)
340 printf("%02x", p[i] & 0xff);
346 char *value[30]; /*XXX*/
350 isakmp_attrmap_print(u_char *p, u_char *ep, struct attrmap *map, size_t nmap)
360 totlen = 4 + ntohs(q[1]);
361 if (ep < p + totlen) {
367 t = ntohs(q[0]) & 0x7fff;
368 if (map && t < nmap && map[t].type)
369 printf("type=%s ", map[t].type);
371 printf("type=#%d ", t);
375 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
376 printf("%s", map[t].value[v]);
378 rawprint((caddr_t)&q[1], 2);
380 printf("len=%d value=", ntohs(q[1]));
381 rawprint((caddr_t)&p[4], ntohs(q[1]));
388 isakmp_attr_print(u_char *p, u_char *ep)
398 totlen = 4 + ntohs(q[1]);
399 if (ep < p + totlen) {
405 t = ntohs(q[0]) & 0x7fff;
406 printf("type=#%d ", t);
410 rawprint((caddr_t)&q[1], 2);
412 printf("len=%d value=", ntohs(q[1]));
413 rawprint((caddr_t)&p[2], ntohs(q[1]));
420 isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
421 u_int32_t doi0, u_int32_t proto0)
423 struct isakmp_pl_sa *p, sa;
425 u_int32_t doi, sit, ident;
429 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA));
431 p = (struct isakmp_pl_sa *)ext;
432 safememcpy(&sa, ext, sizeof(sa));
436 printf(" doi=%d", doi);
437 printf(" situation=%u", (u_int32_t)ntohl(sa.sit));
438 return (u_char *)(p + 1);
441 printf(" doi=ipsec");
442 q = (u_int32_t *)&sa.sit;
443 printf(" situation=");
450 printf("%ssecrecy", t ? "+" : "");
454 printf("%sintegrity", t ? "+" : "");
456 np = (u_char *)ext + sizeof(sa);
458 safememcpy(&ident, ext + 1, sizeof(ident));
459 printf(" ident=%u", (u_int32_t)ntohl(ident));
463 ext = (struct isakmp_gen *)np;
465 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0);
471 isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
472 u_int32_t doi0, u_int32_t proto0)
474 struct isakmp_pl_p *p, prop;
477 printf("%s:", NPSTR(ISAKMP_NPTYPE_P));
479 p = (struct isakmp_pl_p *)ext;
480 safememcpy(&prop, ext, sizeof(prop));
481 printf(" #%d protoid=%s transform=%d",
482 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t);
485 rawprint((caddr_t)(p + 1), prop.spi_size);
488 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
490 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
496 static char *isakmp_p_map[] = {
500 static char *ah_p_map[] = {
501 NULL, "(reserved)", "md5", "sha", "1des",
502 "sha2-256", "sha2-384", "sha2-512",
505 static char *esp_p_map[] = {
506 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
507 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
510 static char *ipcomp_p_map[] = {
511 NULL, "oui", "deflate", "lzs",
514 struct attrmap ipsec_t_map[] = {
516 { "lifetype", 3, { NULL, "sec", "kb", }, },
518 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
520 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
521 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
528 struct attrmap oakley_t_map[] = {
530 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
531 "3des", "cast", "aes", }, },
532 { "hash", 7, { NULL, "md5", "sha1", "tiger",
533 "sha2-256", "sha2-384", "sha2-512", }, },
534 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
535 "rsa enc revised", }, },
536 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
538 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
539 { "group prime", 0, },
540 { "group gen1", 0, },
541 { "group gen2", 0, },
542 { "group curve A", 0, },
543 { "group curve B", 0, },
544 { "lifetype", 3, { NULL, "sec", "kb", }, },
545 { "lifeduration", 0, },
553 isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
554 u_int32_t doi, u_int32_t proto)
556 struct isakmp_pl_t *p, t;
563 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
565 p = (struct isakmp_pl_t *)ext;
566 safememcpy(&t, ext, sizeof(t));
570 idstr = STR_OR_ID(t.t_id, isakmp_p_map);
572 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
575 idstr = STR_OR_ID(t.t_id, ah_p_map);
577 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
580 idstr = STR_OR_ID(t.t_id, esp_p_map);
582 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
585 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
587 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
597 printf(" #%d id=%s ", t.t_no, idstr);
599 printf(" #%d id=%d ", t.t_no, t.t_id);
600 cp = (u_char *)(p + 1);
601 ep2 = (u_char *)p + ntohs(t.h.len);
602 while (cp < ep && cp < ep2) {
604 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
607 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
615 isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
616 u_int32_t doi, u_int32_t proto)
620 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
622 safememcpy(&e, ext, sizeof(e));
623 printf(" key len=%d", ntohs(e.len) - 4);
624 if (2 < vflag && 4 < ntohs(e.len)) {
626 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
628 return (u_char *)ext + ntohs(e.len);
632 isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
633 u_int32_t doi, u_int32_t proto)
635 #define USE_IPSECDOI_IN_PHASE1 1
636 struct isakmp_pl_id *p, id;
637 static char *idtypestr[] = {
638 "IPv4", "IPv4net", "IPv6", "IPv6net",
640 static char *ipsecidtypestr[] = {
641 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
642 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
648 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
650 p = (struct isakmp_pl_id *)ext;
651 safememcpy(&id, ext, sizeof(id));
652 if (sizeof(*p) < id.h.len)
653 data = (u_char *)(p + 1);
656 len = ntohs(id.h.len) - sizeof(*p);
659 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
662 #ifndef USE_IPSECDOI_IN_PHASE1
666 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr));
667 printf(" doi_data=%u",
668 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff));
671 #ifdef USE_IPSECDOI_IN_PHASE1
676 struct ipsecdoi_id *p, id;
679 p = (struct ipsecdoi_id *)ext;
680 safememcpy(&id, ext, sizeof(id));
681 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr));
684 pe = getprotobynumber(id.proto_id);
686 printf(" protoid=%s", pe->p_name);
689 /* it DOES NOT mean IPPROTO_IP! */
690 printf(" protoid=%s", "0");
692 printf(" port=%d", ntohs(id.port));
696 case IPSECDOI_ID_IPV4_ADDR:
697 printf(" len=%d %s", len, ipaddr_string(data));
700 case IPSECDOI_ID_FQDN:
701 case IPSECDOI_ID_USER_FQDN:
704 printf(" len=%d ", len);
705 for (i = 0; i < len; i++)
706 safeputchar(data[i]);
710 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
713 mask = data + sizeof(struct in_addr);
714 printf(" len=%d %s/%u.%u.%u.%u", len,
716 mask[0], mask[1], mask[2], mask[3]);
721 case IPSECDOI_ID_IPV6_ADDR:
722 printf(" len=%d %s", len, ip6addr_string(data));
725 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
728 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
730 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
731 ip6addr_string(data),
732 mask[0], mask[1], mask[2], mask[3]);
737 case IPSECDOI_ID_IPV4_ADDR_RANGE:
738 printf(" len=%d %s-%s", len, ipaddr_string(data),
739 ipaddr_string(data + sizeof(struct in_addr)));
743 case IPSECDOI_ID_IPV6_ADDR_RANGE:
744 printf(" len=%d %s-%s", len, ip6addr_string(data),
745 ip6addr_string(data + sizeof(struct in6_addr)));
749 case IPSECDOI_ID_DER_ASN1_DN:
750 case IPSECDOI_ID_DER_ASN1_GN:
751 case IPSECDOI_ID_KEY_ID:
758 printf(" len=%d", len);
761 rawprint((caddr_t)data, len);
764 return (u_char *)ext + ntohs(id.h.len);
768 isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
769 u_int32_t doi0, u_int32_t proto0)
771 struct isakmp_pl_cert *p, cert;
772 static char *certstr[] = {
773 "none", "pkcs7", "pgp", "dns",
774 "x509sign", "x509ke", "kerberos", "crl",
775 "arl", "spki", "x509attr",
778 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
780 p = (struct isakmp_pl_cert *)ext;
781 safememcpy(&cert, ext, sizeof(cert));
782 printf(" len=%d", ntohs(cert.h.len) - 4);
783 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
784 if (2 < vflag && 4 < ntohs(cert.h.len)) {
786 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4);
788 return (u_char *)ext + ntohs(cert.h.len);
792 isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
793 u_int32_t doi0, u_int32_t proto0)
795 struct isakmp_pl_cert *p, cert;
796 static char *certstr[] = {
797 "none", "pkcs7", "pgp", "dns",
798 "x509sign", "x509ke", "kerberos", "crl",
799 "arl", "spki", "x509attr",
802 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
804 p = (struct isakmp_pl_cert *)ext;
805 safememcpy(&cert, ext, sizeof(cert));
806 printf(" len=%d", ntohs(cert.h.len) - 4);
807 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
808 if (2 < vflag && 4 < ntohs(cert.h.len)) {
810 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4);
812 return (u_char *)ext + ntohs(cert.h.len);
816 isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
817 u_int32_t doi, u_int32_t proto)
821 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
823 safememcpy(&e, ext, sizeof(e));
824 printf(" len=%d", ntohs(e.len) - 4);
825 if (2 < vflag && 4 < ntohs(e.len)) {
827 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
829 return (u_char *)ext + ntohs(e.len);
833 isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
834 u_int32_t doi, u_int32_t proto)
838 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
840 safememcpy(&e, ext, sizeof(e));
841 printf(" len=%d", ntohs(e.len) - 4);
842 if (2 < vflag && 4 < ntohs(e.len)) {
844 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
846 return (u_char *)ext + ntohs(e.len);
850 isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
851 u_int32_t doi, u_int32_t proto)
855 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
857 safememcpy(&e, ext, sizeof(e));
858 printf(" n len=%d", ntohs(e.len) - 4);
859 if (2 < vflag && 4 < ntohs(e.len)) {
861 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
863 return (u_char *)ext + ntohs(e.len);
867 isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
868 u_int32_t doi0, u_int32_t proto0)
870 struct isakmp_pl_n *p, n;
875 static char *notifystr[] = {
876 NULL, "INVALID-PAYLOAD-TYPE",
877 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
878 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
879 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
880 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
881 "INVALID-PROTOCOL-ID", "INVALID-SPI",
882 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
883 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
884 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
885 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
886 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
887 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
888 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
889 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
890 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
891 "UNEQUAL-PAYLOAD-LENGTHS",
893 static char *ipsecnotifystr[] = {
894 "RESPONDER-LIFETIME", "REPLAY-STATUS",
897 /* NOTE: these macro must be called with x in proper range */
898 #define NOTIFYSTR(x) \
899 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr))
900 #define IPSECNOTIFYSTR(x) \
901 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr))
903 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
905 p = (struct isakmp_pl_n *)ext;
906 safememcpy(&n, ext, sizeof(n));
910 printf(" doi=%d", doi);
911 printf(" proto=%d", proto);
912 printf(" type=%s", NOTIFYSTR(ntohs(n.type)));
915 rawprint((caddr_t)(p + 1), n.spi_size);
917 return (u_char *)(p + 1) + n.spi_size;
920 printf(" doi=ipsec");
921 printf(" proto=%s", PROTOIDSTR(proto));
922 if (ntohs(n.type) < 8192)
923 printf(" type=%s", NOTIFYSTR(ntohs(n.type)));
924 else if (ntohs(n.type) < 16384)
925 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type)));
926 else if (ntohs(n.type) < 24576)
927 printf(" type=%s", NOTIFYSTR(ntohs(n.type)));
928 else if (ntohs(n.type) < 40960)
929 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type)));
931 printf(" type=%s", NOTIFYSTR(ntohs(n.type)));
934 rawprint((caddr_t)(p + 1), n.spi_size);
937 cp = (u_char *)(p + 1) + n.spi_size;
938 ep2 = (u_char *)p + ntohs(n.h.len);
942 switch (ntohs(n.type)) {
943 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
945 struct attrmap *map = oakley_t_map;
946 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
947 while (cp < ep && cp < ep2) {
948 cp = isakmp_attrmap_print(cp,
949 (ep < ep2) ? ep : ep2, map, nmap);
953 case IPSECDOI_NTYPE_REPLAY_STATUS:
954 printf("replay detection %sabled",
955 (*(u_int32_t *)cp) ? "en" : "dis");
957 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
958 isakmp_sub_print(ISAKMP_NPTYPE_SA,
959 (struct isakmp_gen *)cp, ep, phase, doi, proto);
964 ntohs(n.h.len) - sizeof(*p) - n.spi_size,
969 return (u_char *)ext + ntohs(n.h.len);
973 isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
974 u_int32_t doi0, u_int32_t proto0)
976 struct isakmp_pl_d *p, d;
982 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
984 p = (struct isakmp_pl_d *)ext;
985 safememcpy(&d, ext, sizeof(d));
989 printf(" doi=%u", doi);
990 printf(" proto=%u", proto);
992 printf(" doi=ipsec");
993 printf(" proto=%s", PROTOIDSTR(proto));
995 printf(" spilen=%u", d.spi_size);
996 printf(" nspi=%u", ntohs(d.num_spi));
998 q = (u_int8_t *)(p + 1);
999 for (i = 0; i < ntohs(d.num_spi); i++) {
1002 rawprint((caddr_t)q, d.spi_size);
1009 isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase,
1010 u_int32_t doi, u_int32_t proto)
1012 struct isakmp_gen e;
1014 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1016 safememcpy(&e, ext, sizeof(e));
1017 printf(" len=%d", ntohs(e.len) - 4);
1018 if (2 < vflag && 4 < ntohs(e.len)) {
1020 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4);
1022 return (u_char *)ext + ntohs(e.len);
1026 isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1027 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1030 struct isakmp_gen e;
1033 safememcpy(&e, ext, sizeof(e));
1036 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto);
1038 printf("%s", NPSTR(np));
1045 isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep,
1046 u_int32_t phase, u_int32_t doi, u_int32_t proto)
1049 static int depth = 0;
1051 struct isakmp_gen e;
1056 safememcpy(&e, ext, sizeof(e));
1058 if (ep < (u_char *)ext + ntohs(e.len)) {
1059 printf(" [|%s]", NPSTR(np));
1065 for (i = 0; i < depth; i++)
1068 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto);
1073 ext = (struct isakmp_gen *)cp;
1081 static char buf[20];
1082 snprintf(buf, sizeof(buf), "#%d", x);
1087 * some compiler tries to optimize memcpy(), using the alignment constraint
1088 * on the argument pointer type. by using this function, we try to avoid the
1092 safememcpy(void *p, void *q, size_t l)
1098 isakmp_print(const u_char *bp, u_int length, const u_char *bp2)
1100 struct isakmp *p, base;
1107 p = (struct isakmp *)bp;
1108 ep = (u_char *)snapend;
1110 if ((struct isakmp *)ep < p + 1) {
1111 printf("[|isakmp]");
1115 safememcpy(&base, p, sizeof(base));
1119 major = (base.vers & ISAKMP_VERS_MAJOR)
1120 >> ISAKMP_VERS_MAJOR_SHIFT;
1121 minor = (base.vers & ISAKMP_VERS_MINOR)
1122 >> ISAKMP_VERS_MINOR_SHIFT;
1123 printf(" %d.%d", major, minor);
1128 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1133 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1135 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1139 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1141 printf(" phase %d", phase);
1143 printf(" phase %d/others", phase);
1145 i = cookie_find(&base.i_ck);
1147 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1148 /* the first packet */
1151 cookie_record(&base.i_ck, bp2);
1155 if (bp2 && cookie_isinitiator(i, bp2))
1157 else if (bp2 && cookie_isresponder(i, bp2))
1163 printf(" %s", ETYPESTR(base.etype));
1165 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1166 base.flags & ISAKMP_FLAG_C ? "C" : "");
1171 struct isakmp_gen *ext;
1174 #define CHECKLEN(p, np) \
1175 if (ep < (u_char *)(p)) { \
1176 printf(" [|%s]", NPSTR(np)); \
1180 /* regardless of phase... */
1181 if (base.flags & ISAKMP_FLAG_E) {
1183 * encrypted, nothing we can do right now.
1184 * we hope to decrypt the packet in the future...
1186 printf(" [encrypted %s]", NPSTR(base.np));
1191 CHECKLEN(p + 1, base.np)
1194 ext = (struct isakmp_gen *)(p + 1);
1195 isakmp_sub_print(np, ext, ep, phase, 0, 0);
1200 if (ntohl(base.len) != length) {
1201 printf(" (len mismatch: isakmp %u/ip %d)",
1202 (u_int32_t)ntohl(base.len), length);