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.28 2001-02-20 18:55:14 fenner 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
:
759 printf(" len=%d", len
);
762 rawprint((caddr_t
)data
, len
);
765 return (u_char
*)ext
+ ntohs(id
.h
.len
);
769 isakmp_cert_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
770 u_int32_t doi0
, u_int32_t proto0
)
772 struct isakmp_pl_cert
*p
, cert
;
773 static char *certstr
[] = {
774 "none", "pkcs7", "pgp", "dns",
775 "x509sign", "x509ke", "kerberos", "crl",
776 "arl", "spki", "x509attr",
779 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT
));
781 p
= (struct isakmp_pl_cert
*)ext
;
782 safememcpy(&cert
, ext
, sizeof(cert
));
783 printf(" len=%d", ntohs(cert
.h
.len
) - 4);
784 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
785 if (2 < vflag
&& 4 < ntohs(cert
.h
.len
)) {
787 rawprint((caddr_t
)(ext
+ 1), ntohs(cert
.h
.len
) - 4);
789 return (u_char
*)ext
+ ntohs(cert
.h
.len
);
793 isakmp_cr_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
794 u_int32_t doi0
, u_int32_t proto0
)
796 struct isakmp_pl_cert
*p
, cert
;
797 static char *certstr
[] = {
798 "none", "pkcs7", "pgp", "dns",
799 "x509sign", "x509ke", "kerberos", "crl",
800 "arl", "spki", "x509attr",
803 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR
));
805 p
= (struct isakmp_pl_cert
*)ext
;
806 safememcpy(&cert
, ext
, sizeof(cert
));
807 printf(" len=%d", ntohs(cert
.h
.len
) - 4);
808 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
809 if (2 < vflag
&& 4 < ntohs(cert
.h
.len
)) {
811 rawprint((caddr_t
)(ext
+ 1), ntohs(cert
.h
.len
) - 4);
813 return (u_char
*)ext
+ ntohs(cert
.h
.len
);
817 isakmp_hash_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
818 u_int32_t doi
, u_int32_t proto
)
822 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH
));
824 safememcpy(&e
, ext
, sizeof(e
));
825 printf(" len=%d", ntohs(e
.len
) - 4);
826 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
828 rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4);
830 return (u_char
*)ext
+ ntohs(e
.len
);
834 isakmp_sig_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
835 u_int32_t doi
, u_int32_t proto
)
839 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG
));
841 safememcpy(&e
, ext
, sizeof(e
));
842 printf(" len=%d", ntohs(e
.len
) - 4);
843 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
845 rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4);
847 return (u_char
*)ext
+ ntohs(e
.len
);
851 isakmp_nonce_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
852 u_int32_t doi
, u_int32_t proto
)
856 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE
));
858 safememcpy(&e
, ext
, sizeof(e
));
859 printf(" n len=%d", ntohs(e
.len
) - 4);
860 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
862 rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4);
864 return (u_char
*)ext
+ ntohs(e
.len
);
868 isakmp_n_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
869 u_int32_t doi0
, u_int32_t proto0
)
871 struct isakmp_pl_n
*p
, n
;
876 static char *notifystr
[] = {
877 NULL
, "INVALID-PAYLOAD-TYPE",
878 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
879 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
880 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
881 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
882 "INVALID-PROTOCOL-ID", "INVALID-SPI",
883 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
884 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
885 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
886 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
887 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
888 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
889 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
890 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
891 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
892 "UNEQUAL-PAYLOAD-LENGTHS",
894 static char *ipsecnotifystr
[] = {
895 "RESPONDER-LIFETIME", "REPLAY-STATUS",
898 /* NOTE: these macro must be called with x in proper range */
899 #define NOTIFYSTR(x) \
900 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr))
901 #define IPSECNOTIFYSTR(x) \
902 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr))
904 printf("%s:", NPSTR(ISAKMP_NPTYPE_N
));
906 p
= (struct isakmp_pl_n
*)ext
;
907 safememcpy(&n
, ext
, sizeof(n
));
911 printf(" doi=%d", doi
);
912 printf(" proto=%d", proto
);
913 printf(" type=%s", NOTIFYSTR(ntohs(n
.type
)));
916 rawprint((caddr_t
)(p
+ 1), n
.spi_size
);
918 return (u_char
*)(p
+ 1) + n
.spi_size
;
921 printf(" doi=ipsec");
922 printf(" proto=%s", PROTOIDSTR(proto
));
923 if (ntohs(n
.type
) < 8192)
924 printf(" type=%s", NOTIFYSTR(ntohs(n
.type
)));
925 else if (ntohs(n
.type
) < 16384)
926 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n
.type
)));
927 else if (ntohs(n
.type
) < 24576)
928 printf(" type=%s", NOTIFYSTR(ntohs(n
.type
)));
929 else if (ntohs(n
.type
) < 40960)
930 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n
.type
)));
932 printf(" type=%s", NOTIFYSTR(ntohs(n
.type
)));
935 rawprint((caddr_t
)(p
+ 1), n
.spi_size
);
938 cp
= (u_char
*)(p
+ 1) + n
.spi_size
;
939 ep2
= (u_char
*)p
+ ntohs(n
.h
.len
);
943 switch (ntohs(n
.type
)) {
944 case IPSECDOI_NTYPE_RESPONDER_LIFETIME
:
946 struct attrmap
*map
= oakley_t_map
;
947 size_t nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
948 while (cp
< ep
&& cp
< ep2
) {
949 cp
= isakmp_attrmap_print(cp
,
950 (ep
< ep2
) ? ep
: ep2
, map
, nmap
);
954 case IPSECDOI_NTYPE_REPLAY_STATUS
:
955 printf("replay detection %sabled",
956 (*(u_int32_t
*)cp
) ? "en" : "dis");
958 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
:
959 isakmp_sub_print(ISAKMP_NPTYPE_SA
,
960 (struct isakmp_gen
*)cp
, ep
, phase
, doi
, proto
);
965 ntohs(n
.h
.len
) - sizeof(*p
) - n
.spi_size
,
970 return (u_char
*)ext
+ ntohs(n
.h
.len
);
974 isakmp_d_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
975 u_int32_t doi0
, u_int32_t proto0
)
977 struct isakmp_pl_d
*p
, d
;
983 printf("%s:", NPSTR(ISAKMP_NPTYPE_D
));
985 p
= (struct isakmp_pl_d
*)ext
;
986 safememcpy(&d
, ext
, sizeof(d
));
990 printf(" doi=%u", doi
);
991 printf(" proto=%u", proto
);
993 printf(" doi=ipsec");
994 printf(" proto=%s", PROTOIDSTR(proto
));
996 printf(" spilen=%u", d
.spi_size
);
997 printf(" nspi=%u", ntohs(d
.num_spi
));
999 q
= (u_int8_t
*)(p
+ 1);
1000 for (i
= 0; i
< ntohs(d
.num_spi
); i
++) {
1003 rawprint((caddr_t
)q
, d
.spi_size
);
1010 isakmp_vid_print(struct isakmp_gen
*ext
, u_char
*ep
, u_int32_t phase
,
1011 u_int32_t doi
, u_int32_t proto
)
1013 struct isakmp_gen e
;
1015 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID
));
1017 safememcpy(&e
, ext
, sizeof(e
));
1018 printf(" len=%d", ntohs(e
.len
) - 4);
1019 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
1021 rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4);
1023 return (u_char
*)ext
+ ntohs(e
.len
);
1027 isakmp_sub0_print(u_char np
, struct isakmp_gen
*ext
, u_char
*ep
,
1028 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
)
1031 struct isakmp_gen e
;
1034 safememcpy(&e
, ext
, sizeof(e
));
1037 cp
= (*NPFUNC(np
))(ext
, ep
, phase
, doi
, proto
);
1039 printf("%s", NPSTR(np
));
1046 isakmp_sub_print(u_char np
, struct isakmp_gen
*ext
, u_char
*ep
,
1047 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
)
1050 static int depth
= 0;
1052 struct isakmp_gen e
;
1057 safememcpy(&e
, ext
, sizeof(e
));
1059 if (ep
< (u_char
*)ext
+ ntohs(e
.len
)) {
1060 printf(" [|%s]", NPSTR(np
));
1066 for (i
= 0; i
< depth
; i
++)
1069 cp
= isakmp_sub0_print(np
, ext
, ep
, phase
, doi
, proto
);
1074 ext
= (struct isakmp_gen
*)cp
;
1082 static char buf
[20];
1083 snprintf(buf
, sizeof(buf
), "#%d", x
);
1088 * some compiler tries to optimize memcpy(), using the alignment constraint
1089 * on the argument pointer type. by using this function, we try to avoid the
1093 safememcpy(void *p
, void *q
, size_t l
)
1099 isakmp_print(const u_char
*bp
, u_int length
, const u_char
*bp2
)
1101 struct isakmp
*p
, base
;
1108 p
= (struct isakmp
*)bp
;
1109 ep
= (u_char
*)snapend
;
1111 if ((struct isakmp
*)ep
< p
+ 1) {
1112 printf("[|isakmp]");
1116 safememcpy(&base
, p
, sizeof(base
));
1120 major
= (base
.vers
& ISAKMP_VERS_MAJOR
)
1121 >> ISAKMP_VERS_MAJOR_SHIFT
;
1122 minor
= (base
.vers
& ISAKMP_VERS_MINOR
)
1123 >> ISAKMP_VERS_MINOR_SHIFT
;
1124 printf(" %d.%d", major
, minor
);
1129 rawprint((caddr_t
)&base
.msgid
, sizeof(base
.msgid
));
1134 rawprint((caddr_t
)&base
.i_ck
, sizeof(base
.i_ck
));
1136 rawprint((caddr_t
)&base
.r_ck
, sizeof(base
.r_ck
));
1140 phase
= (*(u_int32_t
*)base
.msgid
== 0) ? 1 : 2;
1142 printf(" phase %d", phase
);
1144 printf(" phase %d/others", phase
);
1146 i
= cookie_find(&base
.i_ck
);
1148 if (iszero((u_char
*)&base
.r_ck
, sizeof(base
.r_ck
))) {
1149 /* the first packet */
1152 cookie_record(&base
.i_ck
, bp2
);
1156 if (bp2
&& cookie_isinitiator(i
, bp2
))
1158 else if (bp2
&& cookie_isresponder(i
, bp2
))
1164 printf(" %s", ETYPESTR(base
.etype
));
1166 printf("[%s%s]", base
.flags
& ISAKMP_FLAG_E
? "E" : "",
1167 base
.flags
& ISAKMP_FLAG_C
? "C" : "");
1172 struct isakmp_gen
*ext
;
1175 #define CHECKLEN(p, np) \
1176 if (ep < (u_char *)(p)) { \
1177 printf(" [|%s]", NPSTR(np)); \
1181 /* regardless of phase... */
1182 if (base
.flags
& ISAKMP_FLAG_E
) {
1184 * encrypted, nothing we can do right now.
1185 * we hope to decrypt the packet in the future...
1187 printf(" [encrypted %s]", NPSTR(base
.np
));
1192 CHECKLEN(p
+ 1, base
.np
)
1195 ext
= (struct isakmp_gen
*)(p
+ 1);
1196 isakmp_sub_print(np
, ext
, ep
, phase
, 0, 0);
1201 if (ntohl(base
.len
) != length
) {
1202 printf(" (len mismatch: isakmp %u/ip %d)",
1203 (u_int32_t
)ntohl(base
.len
), length
);