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.17 2000-09-23 08:26:35 guy Exp $ (LBL)";
42 #include <sys/param.h>
44 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <netinet/in_systm.h>
52 #include <netinet/ip.h>
53 #include <netinet/ip_var.h>
56 #include <netinet/ip6.h>
63 #include "ipsec_doi.h"
65 #include "interface.h"
66 #include "addrtoname.h"
67 #include "extract.h" /* must come after interface.h */
69 #ifndef HAVE_SOCKADDR_STORAGE
70 #define sockaddr_storage sockaddr
73 static u_char
*isakmp_sa_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
74 u_int32_t
, u_int32_t
));
75 static u_char
*isakmp_p_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
76 u_int32_t
, u_int32_t
));
77 static u_char
*isakmp_t_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
78 u_int32_t
, u_int32_t
));
79 static u_char
*isakmp_ke_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
80 u_int32_t
, u_int32_t
));
81 static u_char
*isakmp_id_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
82 u_int32_t
, u_int32_t
));
83 static u_char
*isakmp_cert_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
84 u_int32_t
, u_int32_t
));
85 static u_char
*isakmp_cr_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
86 u_int32_t
, u_int32_t
));
87 static u_char
*isakmp_sig_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
88 u_int32_t
, u_int32_t
));
89 static u_char
*isakmp_hash_print
__P((struct isakmp_gen
*, u_char
*,
90 u_int32_t
, u_int32_t
, u_int32_t
));
91 static u_char
*isakmp_nonce_print
__P((struct isakmp_gen
*, u_char
*,
92 u_int32_t
, u_int32_t
, u_int32_t
));
93 static u_char
*isakmp_n_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
94 u_int32_t
, u_int32_t
));
95 static u_char
*isakmp_d_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
96 u_int32_t
, u_int32_t
));
97 static u_char
*isakmp_vid_print
__P((struct isakmp_gen
*, u_char
*, u_int32_t
,
98 u_int32_t
, u_int32_t
));
99 static u_char
*isakmp_sub0_print
__P((u_char
, struct isakmp_gen
*, u_char
*,
100 u_int32_t
, u_int32_t
, u_int32_t
));
101 static u_char
*isakmp_sub_print
__P((u_char
, struct isakmp_gen
*, u_char
*,
102 u_int32_t
, u_int32_t
, u_int32_t
));
103 static char *numstr
__P((int));
105 #define MAXINITIATORS 20
109 struct sockaddr_storage iaddr
;
110 struct sockaddr_storage raddr
;
111 } cookiecache
[MAXINITIATORS
];
114 static char *protoidstr
[] = {
115 NULL
, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
119 static char *npstr
[] = {
120 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
121 "sig", "nonce", "n", "d", "vid"
125 static u_char
*(*npfunc
[]) __P((struct isakmp_gen
*, u_char
*, u_int32_t
,
126 u_int32_t
, u_int32_t
)) = {
144 static char *etypestr
[] = {
145 "none", "base", "ident", "auth", "agg", "inf", NULL
, NULL
,
146 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
147 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
148 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
149 "oakley-quick", "oakley-newgroup",
152 #define STR_OR_ID(x, tab) \
153 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
154 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
155 #define NPSTR(x) STR_OR_ID(x, npstr)
156 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
159 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
160 ? npfunc[(x)] : NULL)
163 iszero(u_char
*p
, size_t l
)
172 /* find cookie from initiator cache */
174 cookie_find(cookie_t
*in
)
178 for (i
= 0; i
< MAXINITIATORS
; i
++) {
179 if (memcmp(in
, &cookiecache
[i
].initiator
, sizeof(*in
)) == 0)
186 /* record initiator */
188 cookie_record(cookie_t
*in
, const u_char
*bp2
)
192 struct sockaddr_in
*sin
;
195 struct sockaddr_in6
*sin6
;
200 ninitiator
= (i
+ 1) % MAXINITIATORS
;
204 ip
= (struct ip
*)bp2
;
207 memset(&cookiecache
[ninitiator
].iaddr
, 0,
208 sizeof(cookiecache
[ninitiator
].iaddr
));
209 memset(&cookiecache
[ninitiator
].raddr
, 0,
210 sizeof(cookiecache
[ninitiator
].raddr
));
212 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].iaddr
;
213 #ifdef HAVE_SOCKADDR_SA_LEN
214 sin
->sin_len
= sizeof(struct sockaddr_in
);
216 sin
->sin_family
= AF_INET
;
217 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
218 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].raddr
;
219 #ifdef HAVE_SOCKADDR_SA_LEN
220 sin
->sin_len
= sizeof(struct sockaddr_in
);
222 sin
->sin_family
= AF_INET
;
223 memcpy(&sin
->sin_addr
, &ip
->ip_dst
, sizeof(ip
->ip_dst
));
227 memset(&cookiecache
[ninitiator
].iaddr
, 0,
228 sizeof(cookiecache
[ninitiator
].iaddr
));
229 memset(&cookiecache
[ninitiator
].raddr
, 0,
230 sizeof(cookiecache
[ninitiator
].raddr
));
232 ip6
= (struct ip6_hdr
*)bp2
;
233 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].iaddr
;
234 #ifdef HAVE_SOCKADDR_SA_LEN
235 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
237 sin6
->sin6_family
= AF_INET6
;
238 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
239 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].raddr
;
240 #ifdef HAVE_SOCKADDR_SA_LEN
241 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
243 sin6
->sin6_family
= AF_INET6
;
244 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
250 memcpy(&cookiecache
[ninitiator
].initiator
, in
, sizeof(*in
));
251 ninitiator
= (ninitiator
+ 1) % MAXINITIATORS
;
254 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
255 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
257 cookie_sidecheck(int i
, const u_char
*bp2
, int initiator
)
259 struct sockaddr_storage ss
;
262 struct sockaddr_in
*sin
;
265 struct sockaddr_in6
*sin6
;
269 memset(&ss
, 0, sizeof(ss
));
270 ip
= (struct ip
*)bp2
;
273 sin
= (struct sockaddr_in
*)&ss
;
274 #ifdef HAVE_SOCKADDR_SA_LEN
275 sin
->sin_len
= sizeof(struct sockaddr_in
);
277 sin
->sin_family
= AF_INET
;
278 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
282 ip6
= (struct ip6_hdr
*)bp2
;
283 sin6
= (struct sockaddr_in6
*)&ss
;
284 #ifdef HAVE_SOCKADDR_SA_LEN
285 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
287 sin6
->sin6_family
= AF_INET6
;
288 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
295 sa
= (struct sockaddr
*)&ss
;
297 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].iaddr
)->sa_family
)
299 #ifdef HAVE_SOCKADDR_SA_LEN
303 if (sa
->sa_family
== AF_INET6
)
304 salen
= sizeof(struct sockaddr_in6
);
306 salen
= sizeof(struct sockaddr
);
308 salen
= sizeof(struct sockaddr
);
311 if (memcmp(&ss
, &cookiecache
[i
].iaddr
, salen
) == 0)
314 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].raddr
)->sa_family
)
316 #ifdef HAVE_SOCKADDR_SA_LEN
320 if (sa
->sa_family
== AF_INET6
)
321 salen
= sizeof(struct sockaddr_in6
);
323 salen
= sizeof(struct sockaddr
);
325 salen
= sizeof(struct sockaddr
);
328 if (memcmp(&ss
, &cookiecache
[i
].raddr
, salen
) == 0)
335 rawprint(caddr_t loc
, size_t len
)
341 for (i
= 0; i
< len
; i
++)
342 printf("%02x", p
[i
] & 0xff);
348 char *value
[30]; /*XXX*/
352 isakmp_attrmap_print(u_char
*p
, u_char
*ep
, struct attrmap
*map
, size_t nmap
)
362 totlen
= 4 + ntohs(q
[1]);
363 if (ep
< p
+ totlen
) {
369 t
= ntohs(q
[0]) & 0x7fff;
370 if (map
&& t
< nmap
&& map
[t
].type
)
371 printf("type=%s ", map
[t
].type
);
373 printf("type=#%d ", t
);
377 if (map
&& t
< nmap
&& v
< map
[t
].nvalue
&& map
[t
].value
[v
])
378 printf("%s", map
[t
].value
[v
]);
380 rawprint((caddr_t
)&q
[1], 2);
382 printf("len=%d value=", ntohs(q
[1]));
383 rawprint((caddr_t
)&p
[4], ntohs(q
[1]));
390 isakmp_attr_print(u_char
*p
, u_char
*ep
)
400 totlen
= 4 + ntohs(q
[1]);
401 if (ep
< p
+ totlen
) {
407 t
= ntohs(q
[0]) & 0x7fff;
408 printf("type=#%d ", t
);
412 rawprint((caddr_t
)&q
[1], 2);
414 printf("len=%d value=", ntohs(q
[1]));
415 rawprint((caddr_t
)&p
[2], ntohs(q
[1]));
422 isakmp_sa_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
423 u_int32_t doi0
, u_int32_t proto0
)
425 struct isakmp_pl_sa
*p
;
432 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA
));
434 p
= (struct isakmp_pl_sa
*)ext
;
437 printf(" doi=%d", doi
);
438 printf(" situation=%u", (u_int32_t
)ntohl(p
->sit
));
439 return (u_char
*)(p
+ 1);
442 printf(" doi=ipsec");
443 q
= (u_int32_t
*)&p
->sit
;
444 printf(" situation=");
446 if (ntohl(*q
) & 0x01) {
450 if (ntohl(*q
) & 0x02) {
451 printf("%ssecrecy", t
? "+" : "");
454 if (ntohl(*q
) & 0x04)
455 printf("%sintegrity", t
? "+" : "");
459 printf(" ident=%u", (u_int32_t
)ntohl(*q
++));
461 ext
= (struct isakmp_gen
*)q
;
463 cp
= isakmp_sub_print(ISAKMP_NPTYPE_P
, ext
, ep
, phase
, doi
, proto0
);
469 isakmp_p_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
470 u_int32_t doi0
, u_int32_t proto0
)
472 struct isakmp_pl_p
*p
;
475 printf("%s:", NPSTR(ISAKMP_NPTYPE_P
));
477 p
= (struct isakmp_pl_p
*)ext
;
478 printf(" #%d protoid=%s transform=%d",
479 p
->p_no
, PROTOIDSTR(p
->prot_id
), p
->num_t
);
482 rawprint((caddr_t
)(p
+ 1), p
->spi_size
);
485 ext
= (struct isakmp_gen
*)((u_char
*)(p
+ 1) + p
->spi_size
);
487 cp
= isakmp_sub_print(ISAKMP_NPTYPE_T
, ext
, ep
, phase
, doi0
,
493 static char *isakmp_p_map
[] = {
497 static char *ah_p_map
[] = {
498 NULL
, "(reserved)", "md5", "sha", "1des",
501 static char *esp_p_map
[] = {
502 NULL
, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
503 "blowfish", "3idea", "1des-iv32", "rc4", "null"
506 static char *ipcomp_p_map
[] = {
507 NULL
, "oui", "deflate", "lzs",
510 struct attrmap ipsec_t_map
[] = {
512 { "lifetype", 3, { NULL
, "sec", "kb", }, },
514 { "group desc", 5, { NULL
, "modp768", "modp1024", "EC2N 2^155",
516 { "enc mode", 3, { NULL
, "tunnel", "transport", }, },
517 { "auth", 5, { NULL
, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
524 struct attrmap oakley_t_map
[] = {
526 { "enc", 7, { NULL
, "1des", "idea", "blowfish", "rc5",
528 { "hash", 4, { NULL
, "md5", "sha1", "tiger", }, },
529 { "auth", 6, { NULL
, "preshared", "dss", "rsa sig", "rsa enc",
530 "rsa enc revised", }, },
531 { "group desc", 5, { NULL
, "modp768", "modp1024", "EC2N 2^155",
533 { "group type", 4, { NULL
, "MODP", "ECP", "EC2N", }, },
534 { "group prime", 0, },
535 { "group gen1", 0, },
536 { "group gen2", 0, },
537 { "group curve A", 0, },
538 { "group curve B", 0, },
539 { "lifetype", 3, { NULL
, "sec", "kb", }, },
540 { "lifeduration", 0, },
548 isakmp_t_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
549 u_int32_t doi
, u_int32_t proto
)
551 struct isakmp_pl_t
*p
;
558 printf("%s:", NPSTR(ISAKMP_NPTYPE_T
));
560 p
= (struct isakmp_pl_t
*)ext
;
564 idstr
= STR_OR_ID(p
->t_id
, isakmp_p_map
);
566 nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
569 idstr
= STR_OR_ID(p
->t_id
, ah_p_map
);
571 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
574 idstr
= STR_OR_ID(p
->t_id
, esp_p_map
);
576 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
579 idstr
= STR_OR_ID(p
->t_id
, ipcomp_p_map
);
581 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
591 printf(" #%d id=%s ", p
->t_no
, idstr
);
593 printf(" #%d id=%d ", p
->t_no
, p
->t_id
);
594 cp
= (u_char
*)(p
+ 1);
595 ep2
= (u_char
*)p
+ ntohs(ext
->len
);
596 while (cp
< ep
&& cp
< ep2
) {
598 cp
= isakmp_attrmap_print(cp
, (ep
< ep2
) ? ep
: ep2
,
601 cp
= isakmp_attr_print(cp
, (ep
< ep2
) ? ep
: ep2
);
609 isakmp_ke_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
610 u_int32_t doi
, u_int32_t proto
)
612 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE
));
614 printf(" key len=%d", ntohs(ext
->len
) - 4);
615 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
617 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
619 return (u_char
*)ext
+ ntohs(ext
->len
);
623 isakmp_id_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
624 u_int32_t doi
, u_int32_t proto
)
626 #define USE_IPSECDOI_IN_PHASE1 1
627 struct isakmp_pl_id
*p
;
628 static char *idtypestr
[] = {
629 "IPv4", "IPv4net", "IPv6", "IPv6net",
631 static char *ipsecidtypestr
[] = {
632 NULL
, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
633 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
639 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID
));
641 p
= (struct isakmp_pl_id
*)ext
;
642 if (sizeof(*p
) < ext
->len
)
643 data
= (u_char
*)(p
+ 1);
646 len
= ntohs(ext
->len
) - sizeof(*p
);
649 printf(" [phase=%d doi=%d proto=%d]", phase
, doi
, proto
);
652 #ifndef USE_IPSECDOI_IN_PHASE1
656 printf(" idtype=%s", STR_OR_ID(p
->d
.id_type
, idtypestr
));
657 printf(" doi_data=%u",
658 (u_int32_t
)(ntohl(p
->d
.doi_data
) & 0xffffff));
661 #ifdef USE_IPSECDOI_IN_PHASE1
666 struct ipsecdoi_id
*p
;
669 p
= (struct ipsecdoi_id
*)ext
;
670 printf(" idtype=%s", STR_OR_ID(p
->type
, ipsecidtypestr
));
673 pe
= getprotobynumber(p
->proto_id
);
675 printf(" protoid=%s", pe
->p_name
);
678 /* it DOES NOT mean IPPROTO_IP! */
679 printf(" protoid=%s", "0");
681 printf(" port=%d", ntohs(p
->port
));
685 case IPSECDOI_ID_IPV4_ADDR
:
686 printf(" len=%d %s", len
, ipaddr_string(data
));
689 case IPSECDOI_ID_FQDN
:
690 case IPSECDOI_ID_USER_FQDN
:
693 printf(" len=%d ", len
);
694 for (i
= 0; i
< len
; i
++) {
695 if (isprint(data
[i
]))
696 printf("%c", data
[i
]);
698 printf("\\%03o", data
[i
]);
703 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
706 mask
= data
+ sizeof(struct in_addr
);
707 printf(" len=%d %s/%u.%u.%u.%u", len
,
709 mask
[0], mask
[1], mask
[2], mask
[3]);
714 case IPSECDOI_ID_IPV6_ADDR
:
715 printf(" len=%d %s", len
, ip6addr_string(data
));
718 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
721 mask
= (u_int32_t
*)(data
+ sizeof(struct in6_addr
));
723 printf(" len=%d %s/0x%08x%08x%08x%08x", len
,
724 ip6addr_string(data
),
725 mask
[0], mask
[1], mask
[2], mask
[3]);
730 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
731 printf(" len=%d %s-%s", len
, ipaddr_string(data
),
732 ipaddr_string(data
+ sizeof(struct in_addr
)));
736 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
737 printf(" len=%d %s-%s", len
, ip6addr_string(data
),
738 ip6addr_string(data
+ sizeof(struct in6_addr
)));
742 case IPSECDOI_ID_DER_ASN1_DN
:
743 case IPSECDOI_ID_DER_ASN1_GN
:
744 case IPSECDOI_ID_KEY_ID
:
752 printf(" len=%d", len
);
755 rawprint((caddr_t
)data
, len
);
758 return (u_char
*)ext
+ ntohs(ext
->len
);
762 isakmp_cert_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
763 u_int32_t doi0
, u_int32_t proto0
)
765 struct isakmp_pl_cert
*p
;
766 static char *certstr
[] = {
767 "none", "pkcs7", "pgp", "dns",
768 "x509sign", "x509ke", "kerberos", "crl",
769 "arl", "spki", "x509attr",
772 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT
));
774 p
= (struct isakmp_pl_cert
*)ext
;
775 printf(" len=%d", ntohs(ext
->len
) - 4);
776 printf(" type=%s", STR_OR_ID((p
->encode
), certstr
));
777 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
779 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
781 return (u_char
*)ext
+ ntohs(ext
->len
);
785 isakmp_cr_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
786 u_int32_t doi0
, u_int32_t proto0
)
788 struct isakmp_pl_cert
*p
;
789 static char *certstr
[] = {
790 "none", "pkcs7", "pgp", "dns",
791 "x509sign", "x509ke", "kerberos", "crl",
792 "arl", "spki", "x509attr",
795 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR
));
797 p
= (struct isakmp_pl_cert
*)ext
;
798 printf(" len=%d", ntohs(ext
->len
) - 4);
799 printf(" type=%s", STR_OR_ID((p
->encode
), certstr
));
800 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
802 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
804 return (u_char
*)ext
+ ntohs(ext
->len
);
808 isakmp_hash_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
809 u_int32_t doi
, u_int32_t proto
)
811 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH
));
813 printf(" len=%d", ntohs(ext
->len
) - 4);
814 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
816 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
818 return (u_char
*)ext
+ ntohs(ext
->len
);
822 isakmp_sig_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
823 u_int32_t doi
, u_int32_t proto
)
825 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG
));
827 printf(" len=%d", ntohs(ext
->len
) - 4);
828 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
830 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
832 return (u_char
*)ext
+ ntohs(ext
->len
);
836 isakmp_nonce_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
837 u_int32_t doi
, u_int32_t proto
)
839 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE
));
841 printf(" n len=%d", ntohs(ext
->len
) - 4);
842 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
844 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
846 return (u_char
*)ext
+ ntohs(ext
->len
);
850 isakmp_n_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
851 u_int32_t doi0
, u_int32_t proto0
)
853 struct isakmp_pl_n
*p
;
858 static char *notifystr
[] = {
859 NULL
, "INVALID-PAYLOAD-TYPE",
860 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
861 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
862 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
863 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
864 "INVALID-PROTOCOL-ID", "INVALID-SPI",
865 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
866 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
867 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
868 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
869 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
870 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
871 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
872 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
873 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
874 "UNEQUAL-PAYLOAD-LENGTHS",
876 static char *ipsecnotifystr
[] = {
877 "RESPONDER-LIFETIME", "REPLAY-STATUS",
880 /* NOTE: these macro must be called with x in proper range */
881 #define NOTIFYSTR(x) \
882 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr))
883 #define IPSECNOTIFYSTR(x) \
884 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr))
886 printf("%s:", NPSTR(ISAKMP_NPTYPE_N
));
888 p
= (struct isakmp_pl_n
*)ext
;
892 printf(" doi=%d", doi
);
893 printf(" proto=%d", proto
);
894 printf(" type=%s", NOTIFYSTR(ntohs(p
->type
)));
897 rawprint((caddr_t
)(p
+ 1), p
->spi_size
);
899 return (u_char
*)(p
+ 1) + p
->spi_size
;
902 printf(" doi=ipsec");
903 printf(" proto=%s", PROTOIDSTR(proto
));
904 if (ntohs(p
->type
) < 8192)
905 printf(" type=%s", NOTIFYSTR(ntohs(p
->type
)));
906 else if (ntohs(p
->type
) < 16384)
907 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p
->type
)));
908 else if (ntohs(p
->type
) < 24576)
909 printf(" type=%s", NOTIFYSTR(ntohs(p
->type
)));
910 else if (ntohs(p
->type
) < 40960)
911 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p
->type
)));
913 printf(" type=%s", NOTIFYSTR(ntohs(p
->type
)));
916 rawprint((caddr_t
)(p
+ 1), p
->spi_size
);
919 cp
= (u_char
*)(p
+ 1) + p
->spi_size
;
920 ep2
= (u_char
*)p
+ ntohs(ext
->len
);
924 switch (ntohs(p
->type
)) {
925 case IPSECDOI_NTYPE_RESPONDER_LIFETIME
:
927 struct attrmap
*map
= oakley_t_map
;
928 size_t nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
929 while (cp
< ep
&& cp
< ep2
) {
930 cp
= isakmp_attrmap_print(cp
,
931 (ep
< ep2
) ? ep
: ep2
, map
, nmap
);
935 case IPSECDOI_NTYPE_REPLAY_STATUS
:
936 printf("replay detection %sabled",
937 (*(u_int32_t
*)cp
) ? "en" : "dis");
939 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
:
940 isakmp_sub_print(ISAKMP_NPTYPE_SA
,
941 (struct isakmp_gen
*)cp
, ep
, phase
, doi
, proto
);
946 ntohs(ext
->len
) - sizeof(*p
) - p
->spi_size
,
951 return (u_char
*)ext
+ ntohs(ext
->len
);
955 isakmp_d_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
956 u_int32_t doi0
, u_int32_t proto0
)
958 struct isakmp_pl_d
*p
;
964 printf("%s:", NPSTR(ISAKMP_NPTYPE_D
));
966 p
= (struct isakmp_pl_d
*)ext
;
970 printf(" doi=%u", doi
);
971 printf(" proto=%u", proto
);
973 printf(" doi=ipsec");
974 printf(" proto=%s", PROTOIDSTR(proto
));
976 printf(" spilen=%u", p
->spi_size
);
977 printf(" nspi=%u", ntohs(p
->num_spi
));
979 q
= (u_int8_t
*)(p
+ 1);
980 for (i
= 0; i
< ntohs(p
->num_spi
); i
++) {
983 rawprint((caddr_t
)q
, p
->spi_size
);
990 isakmp_vid_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
991 u_int32_t doi
, u_int32_t proto
)
993 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID
));
995 printf(" len=%d", ntohs(ext
->len
) - 4);
996 if (2 < vflag
&& 4 < ntohs(ext
->len
)) {
998 rawprint((caddr_t
)(ext
+ 1), ntohs(ext
->len
) - 4);
1000 return (u_char
*)ext
+ ntohs(ext
->len
);
1004 isakmp_sub0_print(u_char np
, struct isakmp_gen
*ext
, u_char
*ep
,
1005 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
)
1012 cp
= (*NPFUNC(np
))(ext
, ep
, phase
, doi
, proto
);
1014 printf("%s", NPSTR(np
));
1015 cp
+= ntohs(ext
->len
);
1021 isakmp_sub_print(u_char np
, struct isakmp_gen
*ext
, u_char
*ep
,
1022 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
)
1025 static int depth
= 0;
1031 if (ep
< (u_char
*)ext
+ ntohs(ext
->len
)) {
1032 printf(" [|%s]", NPSTR(np
));
1038 for (i
= 0; i
< depth
; i
++)
1041 cp
= isakmp_sub0_print(np
, ext
, ep
, phase
, doi
, proto
);
1046 ext
= (struct isakmp_gen
*)cp
;
1054 static char buf
[20];
1055 snprintf(buf
, sizeof(buf
), "#%d", x
);
1060 isakmp_print(const u_char
*bp
, u_int length
, const u_char
*bp2
)
1062 struct isakmp
*base
;
1069 base
= (struct isakmp
*)bp
;
1070 ep
= (u_char
*)snapend
;
1072 if ((struct isakmp
*)ep
< base
+ 1) {
1073 printf("[|isakmp]");
1079 major
= (base
->vers
& ISAKMP_VERS_MAJOR
)
1080 >> ISAKMP_VERS_MAJOR_SHIFT
;
1081 minor
= (base
->vers
& ISAKMP_VERS_MINOR
)
1082 >> ISAKMP_VERS_MINOR_SHIFT
;
1083 printf(" %d.%d", major
, minor
);
1088 rawprint((caddr_t
)&base
->msgid
, sizeof(base
->msgid
));
1093 rawprint((caddr_t
)&base
->i_ck
, sizeof(base
->i_ck
));
1095 rawprint((caddr_t
)&base
->r_ck
, sizeof(base
->r_ck
));
1099 phase
= (*(u_int32_t
*)base
->msgid
== 0) ? 1 : 2;
1101 printf(" phase %d", phase
);
1103 printf(" phase %d/others", phase
);
1105 i
= cookie_find(&base
->i_ck
);
1107 if (iszero((u_char
*)&base
->r_ck
, sizeof(base
->r_ck
))) {
1108 /* the first packet */
1111 cookie_record(&base
->i_ck
, bp2
);
1115 if (bp2
&& cookie_isinitiator(i
, bp2
))
1117 else if (bp2
&& cookie_isresponder(i
, bp2
))
1123 printf(" %s", ETYPESTR(base
->etype
));
1125 printf("[%s%s]", base
->flags
& ISAKMP_FLAG_E
? "E" : "",
1126 base
->flags
& ISAKMP_FLAG_C
? "C" : "");
1131 struct isakmp_gen
*ext
;
1134 #define CHECKLEN(p, np) \
1135 if (ep < (u_char *)(p)) { \
1136 printf(" [|%s]", NPSTR(np)); \
1140 /* regardless of phase... */
1141 if (base
->flags
& ISAKMP_FLAG_E
) {
1143 * encrypted, nothing we can do right now.
1144 * we hope to decrypt the packet in the future...
1146 printf(" [|%s]", NPSTR(base
->np
));
1151 CHECKLEN(base
+ 1, base
->np
)
1154 ext
= (struct isakmp_gen
*)(base
+ 1);
1155 isakmp_sub_print(np
, ext
, ep
, phase
, 0, 0);
1160 if (ntohl(base
->len
) != length
) {
1161 printf(" (len mismatch: isakmp %u/ip %d)",
1162 (u_int32_t
)ntohl(base
->len
), length
);