1 /* $NetBSD: print-isakmp.c,v 1.6 2007/07/24 11:53:44 drochner Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include <sys/cdefs.h>
36 static const char rcsid
[] _U_
=
37 "@(#) Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.51 2005/04/07 00:28:17 mcr Exp (LBL)";
39 __RCSID("$NetBSD: print-isakmp.c,v 1.6 2007/07/24 11:53:44 drochner Exp $");
47 #include <tcpdump-stdinc.h>
54 #include "ipsec_doi.h"
56 #include "interface.h"
57 #include "addrtoname.h"
58 #include "extract.h" /* must come after interface.h */
65 #ifndef HAVE_SOCKADDR_STORAGE
66 #define sockaddr_storage sockaddr
69 static const u_char
*isakmp_sa_print(const struct isakmp_gen
*,
70 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
71 static const u_char
*isakmp_p_print(const struct isakmp_gen
*,
72 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
73 static const u_char
*isakmp_t_print(const struct isakmp_gen
*,
74 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
75 static const u_char
*isakmp_ke_print(const struct isakmp_gen
*,
76 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
77 static const u_char
*isakmp_id_print(const struct isakmp_gen
*,
78 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
79 static const u_char
*isakmp_cert_print(const struct isakmp_gen
*,
80 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
81 static const u_char
*isakmp_cr_print(const struct isakmp_gen
*,
82 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
83 static const u_char
*isakmp_sig_print(const struct isakmp_gen
*,
84 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
85 static const u_char
*isakmp_hash_print(const struct isakmp_gen
*,
86 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
87 static const u_char
*isakmp_nonce_print(const struct isakmp_gen
*,
88 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
89 static const u_char
*isakmp_n_print(const struct isakmp_gen
*,
90 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
91 static const u_char
*isakmp_d_print(const struct isakmp_gen
*,
92 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
93 static const u_char
*isakmp_vid_print(const struct isakmp_gen
*,
94 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
95 static const u_char
*isakmp_sub0_print(u_char
, const struct isakmp_gen
*,
96 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
97 static const u_char
*isakmp_sub_print(u_char
, const struct isakmp_gen
*,
98 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
99 static char *numstr(int);
100 static void safememcpy(void *, const void *, size_t);
102 #define MAXINITIATORS 20
106 struct sockaddr_storage iaddr
;
107 struct sockaddr_storage raddr
;
108 } cookiecache
[MAXINITIATORS
];
111 static const char *protoidstr
[] = {
112 NULL
, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
116 static const char *npstr
[] = {
117 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
118 "sig", "nonce", "n", "d", "vid"
122 static const u_char
*(*npfunc
[])(const struct isakmp_gen
*, u_int
,
123 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int) = {
141 static const char *etypestr
[] = {
142 "none", "base", "ident", "auth", "agg", "inf", NULL
, NULL
,
143 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
144 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
145 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
146 "oakley-quick", "oakley-newgroup",
149 #define STR_OR_ID(x, tab) \
150 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
151 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
152 #define NPSTR(x) STR_OR_ID(x, npstr)
153 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
156 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
157 ? npfunc[(x)] : NULL)
160 iszero(u_char
*p
, size_t l
)
169 /* find cookie from initiator cache */
171 cookie_find(cookie_t
*in
)
175 for (i
= 0; i
< MAXINITIATORS
; i
++) {
176 if (memcmp(in
, &cookiecache
[i
].initiator
, sizeof(*in
)) == 0)
183 /* record initiator */
185 cookie_record(cookie_t
*in
, const u_char
*bp2
)
189 struct sockaddr_in
*sin
;
192 struct sockaddr_in6
*sin6
;
197 ninitiator
= (i
+ 1) % MAXINITIATORS
;
201 ip
= (struct ip
*)bp2
;
204 memset(&cookiecache
[ninitiator
].iaddr
, 0,
205 sizeof(cookiecache
[ninitiator
].iaddr
));
206 memset(&cookiecache
[ninitiator
].raddr
, 0,
207 sizeof(cookiecache
[ninitiator
].raddr
));
209 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].iaddr
;
210 #ifdef HAVE_SOCKADDR_SA_LEN
211 sin
->sin_len
= sizeof(struct sockaddr_in
);
213 sin
->sin_family
= AF_INET
;
214 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
215 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].raddr
;
216 #ifdef HAVE_SOCKADDR_SA_LEN
217 sin
->sin_len
= sizeof(struct sockaddr_in
);
219 sin
->sin_family
= AF_INET
;
220 memcpy(&sin
->sin_addr
, &ip
->ip_dst
, sizeof(ip
->ip_dst
));
224 memset(&cookiecache
[ninitiator
].iaddr
, 0,
225 sizeof(cookiecache
[ninitiator
].iaddr
));
226 memset(&cookiecache
[ninitiator
].raddr
, 0,
227 sizeof(cookiecache
[ninitiator
].raddr
));
229 ip6
= (struct ip6_hdr
*)bp2
;
230 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].iaddr
;
231 #ifdef HAVE_SOCKADDR_SA_LEN
232 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
234 sin6
->sin6_family
= AF_INET6
;
235 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
236 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].raddr
;
237 #ifdef HAVE_SOCKADDR_SA_LEN
238 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
240 sin6
->sin6_family
= AF_INET6
;
241 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
247 memcpy(&cookiecache
[ninitiator
].initiator
, in
, sizeof(*in
));
248 ninitiator
= (ninitiator
+ 1) % MAXINITIATORS
;
251 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
252 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
254 cookie_sidecheck(int i
, const u_char
*bp2
, int initiator
)
256 struct sockaddr_storage ss
;
259 struct sockaddr_in
*sin
;
262 struct sockaddr_in6
*sin6
;
266 memset(&ss
, 0, sizeof(ss
));
267 ip
= (struct ip
*)bp2
;
270 sin
= (struct sockaddr_in
*)&ss
;
271 #ifdef HAVE_SOCKADDR_SA_LEN
272 sin
->sin_len
= sizeof(struct sockaddr_in
);
274 sin
->sin_family
= AF_INET
;
275 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
279 ip6
= (struct ip6_hdr
*)bp2
;
280 sin6
= (struct sockaddr_in6
*)&ss
;
281 #ifdef HAVE_SOCKADDR_SA_LEN
282 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
284 sin6
->sin6_family
= AF_INET6
;
285 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
292 sa
= (struct sockaddr
*)&ss
;
294 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].iaddr
)->sa_family
)
296 #ifdef HAVE_SOCKADDR_SA_LEN
300 if (sa
->sa_family
== AF_INET6
)
301 salen
= sizeof(struct sockaddr_in6
);
303 salen
= sizeof(struct sockaddr
);
305 salen
= sizeof(struct sockaddr
);
308 if (memcmp(&ss
, &cookiecache
[i
].iaddr
, salen
) == 0)
311 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].raddr
)->sa_family
)
313 #ifdef HAVE_SOCKADDR_SA_LEN
317 if (sa
->sa_family
== AF_INET6
)
318 salen
= sizeof(struct sockaddr_in6
);
320 salen
= sizeof(struct sockaddr
);
322 salen
= sizeof(struct sockaddr
);
325 if (memcmp(&ss
, &cookiecache
[i
].raddr
, salen
) == 0)
332 rawprint(caddr_t loc
, size_t len
)
340 for (i
= 0; i
< len
; i
++)
341 printf("%02x", p
[i
] & 0xff);
350 const char *value
[30]; /*XXX*/
353 static const u_char
*
354 isakmp_attrmap_print(const u_char
*p
, const u_char
*ep
,
355 const struct attrmap
*map
, size_t nmap
)
365 totlen
= 4 + EXTRACT_16BITS(&q
[1]);
366 if (ep
< p
+ totlen
) {
372 t
= EXTRACT_16BITS(&q
[0]) & 0x7fff;
373 if (map
&& t
< nmap
&& map
[t
].type
)
374 printf("type=%s ", map
[t
].type
);
376 printf("type=#%d ", t
);
379 v
= EXTRACT_16BITS(&q
[1]);
380 if (map
&& t
< nmap
&& v
< map
[t
].nvalue
&& map
[t
].value
[v
])
381 printf("%s", map
[t
].value
[v
]);
383 rawprint((caddr_t
)&q
[1], 2);
385 printf("len=%d value=", EXTRACT_16BITS(&q
[1]));
386 rawprint((caddr_t
)&p
[4], EXTRACT_16BITS(&q
[1]));
392 static const u_char
*
393 isakmp_attr_print(const u_char
*p
, const u_char
*ep
)
403 totlen
= 4 + EXTRACT_16BITS(&q
[1]);
404 if (ep
< p
+ totlen
) {
410 t
= EXTRACT_16BITS(&q
[0]) & 0x7fff;
411 printf("type=#%d ", t
);
415 rawprint((caddr_t
)&q
[1], 2);
417 printf("len=%d value=", EXTRACT_16BITS(&q
[1]));
418 rawprint((caddr_t
)&p
[2], EXTRACT_16BITS(&q
[1]));
424 static const u_char
*
425 isakmp_sa_print(const struct isakmp_gen
*ext
,
427 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0 _U_
,
428 u_int32_t proto0
, int depth
)
430 const struct isakmp_pl_sa
*p
;
431 struct isakmp_pl_sa sa
;
433 u_int32_t doi
, sit
, ident
;
434 const u_char
*cp
, *np
;
437 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA
));
439 p
= (struct isakmp_pl_sa
*)ext
;
441 safememcpy(&sa
, ext
, sizeof(sa
));
445 printf(" doi=%d", doi
);
446 printf(" situation=%u", (u_int32_t
)ntohl(sa
.sit
));
447 return (u_char
*)(p
+ 1);
450 printf(" doi=ipsec");
451 q
= (u_int32_t
*)&sa
.sit
;
452 printf(" situation=");
459 printf("%ssecrecy", t
? "+" : "");
463 printf("%sintegrity", t
? "+" : "");
465 np
= (u_char
*)ext
+ sizeof(sa
);
467 TCHECK2(*(ext
+ 1), sizeof(ident
));
468 safememcpy(&ident
, ext
+ 1, sizeof(ident
));
469 printf(" ident=%u", (u_int32_t
)ntohl(ident
));
473 ext
= (struct isakmp_gen
*)np
;
476 cp
= isakmp_sub_print(ISAKMP_NPTYPE_P
, ext
, ep
, phase
, doi
, proto0
,
481 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA
));
485 static const u_char
*
486 isakmp_p_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
487 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0
,
488 u_int32_t proto0 _U_
, int depth
)
490 const struct isakmp_pl_p
*p
;
491 struct isakmp_pl_p prop
;
494 printf("%s:", NPSTR(ISAKMP_NPTYPE_P
));
496 p
= (struct isakmp_pl_p
*)ext
;
498 safememcpy(&prop
, ext
, sizeof(prop
));
499 printf(" #%d protoid=%s transform=%d",
500 prop
.p_no
, PROTOIDSTR(prop
.prot_id
), prop
.num_t
);
503 if (!rawprint((caddr_t
)(p
+ 1), prop
.spi_size
))
507 ext
= (struct isakmp_gen
*)((u_char
*)(p
+ 1) + prop
.spi_size
);
510 cp
= isakmp_sub_print(ISAKMP_NPTYPE_T
, ext
, ep
, phase
, doi0
,
511 prop
.prot_id
, depth
);
515 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P
));
519 static const char *isakmp_p_map
[] = {
523 static const char *ah_p_map
[] = {
524 NULL
, "(reserved)", "md5", "sha", "1des",
525 "sha2-256", "sha2-384", "sha2-512",
528 static const char *esp_p_map
[] = {
529 NULL
, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
530 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
533 static const char *ipcomp_p_map
[] = {
534 NULL
, "oui", "deflate", "lzs",
537 const struct attrmap ipsec_t_map
[] = {
538 { NULL
, 0, { NULL
} },
539 { "lifetype", 3, { NULL
, "sec", "kb", }, },
540 { "life", 0, { NULL
} },
541 { "group desc", 5, { NULL
, "modp768", "modp1024", "EC2N 2^155",
543 { "enc mode", 3, { NULL
, "tunnel", "transport", }, },
544 { "auth", 5, { NULL
, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
545 { "keylen", 0, { NULL
} },
546 { "rounds", 0, { NULL
} },
547 { "dictsize", 0, { NULL
} },
548 { "privalg", 0, { NULL
} },
551 const struct attrmap oakley_t_map
[] = {
552 { NULL
, 0, { NULL
} },
553 { "enc", 8, { NULL
, "1des", "idea", "blowfish", "rc5",
554 "3des", "cast", "aes", }, },
555 { "hash", 7, { NULL
, "md5", "sha1", "tiger",
556 "sha2-256", "sha2-384", "sha2-512", }, },
557 { "auth", 6, { NULL
, "preshared", "dss", "rsa sig", "rsa enc",
558 "rsa enc revised", }, },
559 { "group desc", 5, { NULL
, "modp768", "modp1024", "EC2N 2^155",
561 { "group type", 4, { NULL
, "MODP", "ECP", "EC2N", }, },
562 { "group prime", 0, { NULL
} },
563 { "group gen1", 0, { NULL
} },
564 { "group gen2", 0, { NULL
} },
565 { "group curve A", 0, { NULL
} },
566 { "group curve B", 0, { NULL
} },
567 { "lifetype", 3, { NULL
, "sec", "kb", }, },
568 { "lifeduration", 0, { NULL
} },
569 { "prf", 0, { NULL
} },
570 { "keylen", 0, { NULL
} },
571 { "field", 0, { NULL
} },
572 { "order", 0, { NULL
} },
575 static const u_char
*
576 isakmp_t_print(const struct isakmp_gen
*ext
, u_int item_len
,
577 const u_char
*ep
, u_int32_t phase _U_
, u_int32_t doi _U_
,
578 u_int32_t proto
, int depth _U_
)
580 const struct isakmp_pl_t
*p
;
581 struct isakmp_pl_t t
;
584 const struct attrmap
*map
;
588 printf("%s:", NPSTR(ISAKMP_NPTYPE_T
));
590 p
= (struct isakmp_pl_t
*)ext
;
592 safememcpy(&t
, ext
, sizeof(t
));
596 idstr
= STR_OR_ID(t
.t_id
, isakmp_p_map
);
598 nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
601 idstr
= STR_OR_ID(t
.t_id
, ah_p_map
);
603 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
606 idstr
= STR_OR_ID(t
.t_id
, esp_p_map
);
608 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
611 idstr
= STR_OR_ID(t
.t_id
, ipcomp_p_map
);
613 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
623 printf(" #%d id=%s ", t
.t_no
, idstr
);
625 printf(" #%d id=%d ", t
.t_no
, t
.t_id
);
626 cp
= (u_char
*)(p
+ 1);
627 ep2
= (u_char
*)p
+ item_len
;
628 while (cp
< ep
&& cp
< ep2
) {
630 cp
= isakmp_attrmap_print(cp
, (ep
< ep2
) ? ep
: ep2
,
633 cp
= isakmp_attr_print(cp
, (ep
< ep2
) ? ep
: ep2
);
639 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T
));
643 static const u_char
*
644 isakmp_ke_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
645 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
646 u_int32_t proto _U_
, int depth _U_
)
650 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE
));
653 safememcpy(&e
, ext
, sizeof(e
));
654 printf(" key len=%d", ntohs(e
.len
) - 4);
655 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
657 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
660 return (u_char
*)ext
+ ntohs(e
.len
);
662 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE
));
666 static const u_char
*
667 isakmp_id_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
668 const u_char
*ep _U_
, u_int32_t phase
, u_int32_t doi _U_
,
669 u_int32_t proto _U_
, int depth _U_
)
671 #define USE_IPSECDOI_IN_PHASE1 1
672 const struct isakmp_pl_id
*p
;
673 struct isakmp_pl_id id
;
674 static const char *idtypestr
[] = {
675 "IPv4", "IPv4net", "IPv6", "IPv6net",
677 static const char *ipsecidtypestr
[] = {
678 NULL
, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
679 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
685 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID
));
687 p
= (struct isakmp_pl_id
*)ext
;
689 safememcpy(&id
, ext
, sizeof(id
));
690 if (sizeof(*p
) < item_len
) {
691 data
= (u_char
*)(p
+ 1);
692 len
= item_len
- sizeof(*p
);
699 printf(" [phase=%d doi=%d proto=%d]", phase
, doi
, proto
);
702 #ifndef USE_IPSECDOI_IN_PHASE1
706 printf(" idtype=%s", STR_OR_ID(id
.d
.id_type
, idtypestr
));
707 printf(" doi_data=%u",
708 (u_int32_t
)(ntohl(id
.d
.doi_data
) & 0xffffff));
711 #ifdef USE_IPSECDOI_IN_PHASE1
716 const struct ipsecdoi_id
*p
;
717 struct ipsecdoi_id id
;
720 p
= (struct ipsecdoi_id
*)ext
;
722 safememcpy(&id
, ext
, sizeof(id
));
723 printf(" idtype=%s", STR_OR_ID(id
.type
, ipsecidtypestr
));
728 pe
= getprotobynumber(id
.proto_id
);
730 printf(" protoid=%s", pe
->p_name
);
735 /* it DOES NOT mean IPPROTO_IP! */
736 printf(" protoid=%s", "0");
738 printf(" port=%d", ntohs(id
.port
));
745 case IPSECDOI_ID_IPV4_ADDR
:
747 printf(" len=%d [bad: < 4]", len
);
749 printf(" len=%d %s", len
, ipaddr_string(data
));
752 case IPSECDOI_ID_FQDN
:
753 case IPSECDOI_ID_USER_FQDN
:
756 printf(" len=%d ", len
);
757 for (i
= 0; i
< len
; i
++)
758 safeputchar(data
[i
]);
762 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
766 printf(" len=%d [bad: < 8]", len
);
768 mask
= data
+ sizeof(struct in_addr
);
769 printf(" len=%d %s/%u.%u.%u.%u", len
,
771 mask
[0], mask
[1], mask
[2], mask
[3]);
777 case IPSECDOI_ID_IPV6_ADDR
:
779 printf(" len=%d [bad: < 16]", len
);
781 printf(" len=%d %s", len
, ip6addr_string(data
));
784 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
786 const u_int32_t
*mask
;
788 printf(" len=%d [bad: < 20]", len
);
790 mask
= (u_int32_t
*)(data
+ sizeof(struct in6_addr
));
792 printf(" len=%d %s/0x%08x%08x%08x%08x", len
,
793 ip6addr_string(data
),
794 mask
[0], mask
[1], mask
[2], mask
[3]);
800 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
802 printf(" len=%d [bad: < 8]", len
);
804 printf(" len=%d %s-%s", len
,
806 ipaddr_string(data
+ sizeof(struct in_addr
)));
811 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
813 printf(" len=%d [bad: < 32]", len
);
815 printf(" len=%d %s-%s", len
,
816 ip6addr_string(data
),
817 ip6addr_string(data
+ sizeof(struct in6_addr
)));
822 case IPSECDOI_ID_DER_ASN1_DN
:
823 case IPSECDOI_ID_DER_ASN1_GN
:
824 case IPSECDOI_ID_KEY_ID
:
831 printf(" len=%d", len
);
834 if (!rawprint((caddr_t
)data
, len
))
838 return (u_char
*)ext
+ item_len
;
840 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID
));
844 static const u_char
*
845 isakmp_cert_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
846 const u_char
*ep _U_
, u_int32_t phase _U_
,
848 u_int32_t proto0 _U_
, int depth _U_
)
850 const struct isakmp_pl_cert
*p
;
851 struct isakmp_pl_cert cert
;
852 static const char *certstr
[] = {
853 "none", "pkcs7", "pgp", "dns",
854 "x509sign", "x509ke", "kerberos", "crl",
855 "arl", "spki", "x509attr",
858 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT
));
860 p
= (struct isakmp_pl_cert
*)ext
;
862 safememcpy(&cert
, ext
, sizeof(cert
));
863 printf(" len=%d", item_len
- 4);
864 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
865 if (2 < vflag
&& 4 < item_len
) {
867 if (!rawprint((caddr_t
)(ext
+ 1), item_len
- 4))
870 return (u_char
*)ext
+ item_len
;
872 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT
));
876 static const u_char
*
877 isakmp_cr_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
878 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi0 _U_
,
879 u_int32_t proto0 _U_
, int depth _U_
)
881 const struct isakmp_pl_cert
*p
;
882 struct isakmp_pl_cert cert
;
883 static const char *certstr
[] = {
884 "none", "pkcs7", "pgp", "dns",
885 "x509sign", "x509ke", "kerberos", "crl",
886 "arl", "spki", "x509attr",
889 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR
));
891 p
= (struct isakmp_pl_cert
*)ext
;
893 safememcpy(&cert
, ext
, sizeof(cert
));
894 printf(" len=%d", item_len
- 4);
895 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
896 if (2 < vflag
&& 4 < item_len
) {
898 if (!rawprint((caddr_t
)(ext
+ 1), item_len
- 4))
901 return (u_char
*)ext
+ item_len
;
903 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR
));
907 static const u_char
*
908 isakmp_hash_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
909 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
910 u_int32_t proto _U_
, int depth _U_
)
914 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH
));
917 safememcpy(&e
, ext
, sizeof(e
));
918 printf(" len=%d", ntohs(e
.len
) - 4);
919 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
921 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
924 return (u_char
*)ext
+ ntohs(e
.len
);
926 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH
));
930 static const u_char
*
931 isakmp_sig_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
932 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
933 u_int32_t proto _U_
, int depth _U_
)
937 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG
));
940 safememcpy(&e
, ext
, sizeof(e
));
941 printf(" len=%d", ntohs(e
.len
) - 4);
942 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
944 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
947 return (u_char
*)ext
+ ntohs(e
.len
);
949 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG
));
953 static const u_char
*
954 isakmp_nonce_print(const struct isakmp_gen
*ext
,
956 const u_char
*ep _U_
,
957 u_int32_t phase _U_
, u_int32_t doi _U_
,
958 u_int32_t proto _U_
, int depth _U_
)
962 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE
));
965 safememcpy(&e
, ext
, sizeof(e
));
966 printf(" n len=%d", ntohs(e
.len
) - 4);
967 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
969 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
972 return (u_char
*)ext
+ ntohs(e
.len
);
974 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE
));
978 static const u_char
*
979 isakmp_n_print(const struct isakmp_gen
*ext
, u_int item_len
,
980 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0 _U_
,
981 u_int32_t proto0 _U_
, int depth
)
983 struct isakmp_pl_n
*p
, n
;
988 static const char *notify_error_str
[] = {
989 NULL
, "INVALID-PAYLOAD-TYPE",
990 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
991 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
992 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
993 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
994 "INVALID-PROTOCOL-ID", "INVALID-SPI",
995 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
996 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
997 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
998 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
999 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
1000 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
1001 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
1002 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
1003 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
1004 "UNEQUAL-PAYLOAD-LENGTHS",
1006 static const char *ipsec_notify_error_str
[] = {
1009 static const char *notify_status_str
[] = {
1012 static const char *ipsec_notify_status_str
[] = {
1013 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1016 /* NOTE: these macro must be called with x in proper range */
1019 #define NOTIFY_ERROR_STR(x) \
1020 STR_OR_ID((x), notify_error_str)
1023 #define IPSEC_NOTIFY_ERROR_STR(x) \
1024 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1027 #define NOTIFY_STATUS_STR(x) \
1028 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1031 #define IPSEC_NOTIFY_STATUS_STR(x) \
1032 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1034 printf("%s:", NPSTR(ISAKMP_NPTYPE_N
));
1036 p
= (struct isakmp_pl_n
*)ext
;
1038 safememcpy(&n
, ext
, sizeof(n
));
1042 printf(" doi=%d", doi
);
1043 printf(" proto=%d", proto
);
1044 if (ntohs(n
.type
) < 8192)
1045 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n
.type
)));
1046 else if (ntohs(n
.type
) < 16384)
1047 printf(" type=%s", numstr(ntohs(n
.type
)));
1048 else if (ntohs(n
.type
) < 24576)
1049 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n
.type
)));
1051 printf(" type=%s", numstr(ntohs(n
.type
)));
1054 if (!rawprint((caddr_t
)(p
+ 1), n
.spi_size
))
1057 return (u_char
*)(p
+ 1) + n
.spi_size
;
1060 printf(" doi=ipsec");
1061 printf(" proto=%s", PROTOIDSTR(proto
));
1062 if (ntohs(n
.type
) < 8192)
1063 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n
.type
)));
1064 else if (ntohs(n
.type
) < 16384)
1065 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n
.type
)));
1066 else if (ntohs(n
.type
) < 24576)
1067 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n
.type
)));
1068 else if (ntohs(n
.type
) < 32768)
1069 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n
.type
)));
1071 printf(" type=%s", numstr(ntohs(n
.type
)));
1074 if (!rawprint((caddr_t
)(p
+ 1), n
.spi_size
))
1078 cp
= (u_char
*)(p
+ 1) + n
.spi_size
;
1079 ep2
= (u_char
*)p
+ item_len
;
1083 switch (ntohs(n
.type
)) {
1084 case IPSECDOI_NTYPE_RESPONDER_LIFETIME
:
1086 const struct attrmap
*map
= oakley_t_map
;
1087 size_t nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
1088 while (cp
< ep
&& cp
< ep2
) {
1089 cp
= isakmp_attrmap_print(cp
,
1090 (ep
< ep2
) ? ep
: ep2
, map
, nmap
);
1094 case IPSECDOI_NTYPE_REPLAY_STATUS
:
1095 printf("replay detection %sabled",
1096 (*(u_int32_t
*)cp
) ? "en" : "dis");
1098 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
:
1099 if (isakmp_sub_print(ISAKMP_NPTYPE_SA
,
1100 (struct isakmp_gen
*)cp
, ep
, phase
, doi
, proto
,
1106 isakmp_print(gndo
, cp
,
1107 item_len
- sizeof(*p
) - n
.spi_size
,
1112 return (u_char
*)ext
+ item_len
;
1114 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N
));
1118 static const u_char
*
1119 isakmp_d_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
1120 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi0 _U_
,
1121 u_int32_t proto0 _U_
, int depth _U_
)
1123 const struct isakmp_pl_d
*p
;
1124 struct isakmp_pl_d d
;
1130 printf("%s:", NPSTR(ISAKMP_NPTYPE_D
));
1132 p
= (struct isakmp_pl_d
*)ext
;
1134 safememcpy(&d
, ext
, sizeof(d
));
1138 printf(" doi=%u", doi
);
1139 printf(" proto=%u", proto
);
1141 printf(" doi=ipsec");
1142 printf(" proto=%s", PROTOIDSTR(proto
));
1144 printf(" spilen=%u", d
.spi_size
);
1145 printf(" nspi=%u", ntohs(d
.num_spi
));
1147 q
= (u_int8_t
*)(p
+ 1);
1148 for (i
= 0; i
< ntohs(d
.num_spi
); i
++) {
1151 if (!rawprint((caddr_t
)q
, d
.spi_size
))
1157 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D
));
1161 static const u_char
*
1162 isakmp_vid_print(const struct isakmp_gen
*ext
,
1163 u_int item_len _U_
, const u_char
*ep _U_
,
1164 u_int32_t phase _U_
, u_int32_t doi _U_
,
1165 u_int32_t proto _U_
, int depth _U_
)
1167 struct isakmp_gen e
;
1169 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID
));
1172 safememcpy(&e
, ext
, sizeof(e
));
1173 printf(" len=%d", ntohs(e
.len
) - 4);
1174 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
1176 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
1179 return (u_char
*)ext
+ ntohs(e
.len
);
1181 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID
));
1185 static const u_char
*
1186 isakmp_sub0_print(u_char np
, const struct isakmp_gen
*ext
, const u_char
*ep
,
1187 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
, int depth
)
1190 struct isakmp_gen e
;
1195 safememcpy(&e
, ext
, sizeof(e
));
1198 * Since we can't have a payload length of less than 4 bytes,
1199 * we need to bail out here if the generic header is nonsensical
1200 * or truncated, otherwise we could loop forever processing
1201 * zero-length items or otherwise misdissect the packet.
1203 item_len
= ntohs(e
.len
);
1209 * XXX - what if item_len is too short, or too long,
1210 * for this payload type?
1212 cp
= (*npfunc
[np
])(ext
, item_len
, ep
, phase
, doi
, proto
, depth
);
1214 printf("%s", NPSTR(np
));
1220 printf(" [|isakmp]");
1224 static const u_char
*
1225 isakmp_sub_print(u_char np
, const struct isakmp_gen
*ext
, const u_char
*ep
,
1226 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
, int depth
)
1230 struct isakmp_gen e
;
1232 cp
= (const u_char
*)ext
;
1237 safememcpy(&e
, ext
, sizeof(e
));
1239 TCHECK2(*ext
, ntohs(e
.len
));
1243 for (i
= 0; i
< depth
; i
++)
1246 cp
= isakmp_sub0_print(np
, ext
, ep
, phase
, doi
, proto
, depth
);
1251 /* Zero-length subitem */
1256 ext
= (struct isakmp_gen
*)cp
;
1260 printf(" [|%s]", NPSTR(np
));
1267 static char buf
[20];
1268 snprintf(buf
, sizeof(buf
), "#%d", x
);
1273 * some compiler tries to optimize memcpy(), using the alignment constraint
1274 * on the argument pointer type. by using this function, we try to avoid the
1278 safememcpy(void *p
, const void *q
, size_t l
)
1284 isakmp_print(netdissect_options
*ndo
,
1285 const u_char
*bp
, u_int length
,
1288 const struct isakmp
*p
;
1296 p
= (const struct isakmp
*)bp
;
1297 ep
= ndo
->ndo_snapend
;
1299 if ((struct isakmp
*)ep
< p
+ 1) {
1300 printf("[|isakmp]");
1304 safememcpy(&base
, p
, sizeof(base
));
1308 major
= (base
.vers
& ISAKMP_VERS_MAJOR
)
1309 >> ISAKMP_VERS_MAJOR_SHIFT
;
1310 minor
= (base
.vers
& ISAKMP_VERS_MINOR
)
1311 >> ISAKMP_VERS_MINOR_SHIFT
;
1312 printf(" %d.%d", major
, minor
);
1317 rawprint((caddr_t
)&base
.msgid
, sizeof(base
.msgid
));
1322 rawprint((caddr_t
)&base
.i_ck
, sizeof(base
.i_ck
));
1324 rawprint((caddr_t
)&base
.r_ck
, sizeof(base
.r_ck
));
1328 phase
= (*(u_int32_t
*)base
.msgid
== 0) ? 1 : 2;
1330 printf(" phase %d", phase
);
1332 printf(" phase %d/others", phase
);
1334 i
= cookie_find(&base
.i_ck
);
1336 if (iszero((u_char
*)&base
.r_ck
, sizeof(base
.r_ck
))) {
1337 /* the first packet */
1340 cookie_record(&base
.i_ck
, bp2
);
1344 if (bp2
&& cookie_isinitiator(i
, bp2
))
1346 else if (bp2
&& cookie_isresponder(i
, bp2
))
1352 printf(" %s", ETYPESTR(base
.etype
));
1354 printf("[%s%s]", base
.flags
& ISAKMP_FLAG_E
? "E" : "",
1355 base
.flags
& ISAKMP_FLAG_C
? "C" : "");
1359 const struct isakmp_gen
*ext
;
1362 #define CHECKLEN(p, np) \
1363 if (ep < (u_char *)(p)) { \
1364 printf(" [|%s]", NPSTR(np)); \
1370 /* regardless of phase... */
1371 if (base
.flags
& ISAKMP_FLAG_E
) {
1373 * encrypted, nothing we can do right now.
1374 * we hope to decrypt the packet in the future...
1376 printf(" [encrypted %s]", NPSTR(base
.np
));
1381 CHECKLEN(p
+ 1, base
.np
)
1384 ext
= (struct isakmp_gen
*)(p
+ 1);
1385 isakmp_sub_print(np
, ext
, ep
, phase
, 0, 0, 0);
1390 if (ntohl(base
.len
) != length
) {
1391 printf(" (len mismatch: isakmp %u/ip %u)",
1392 (u_int32_t
)ntohl(base
.len
), length
);
1398 isakmp_rfc3948_print(netdissect_options
*ndo
,
1399 const u_char
*bp
, u_int length
,
1403 ep
= ndo
->ndo_snapend
;
1405 if(length
== 1 && bp
[0]==0xff) {
1406 ND_PRINT((ndo
, "isakmp-nat-keep-alive"));
1415 * see if this is an IKE packet
1417 if(bp
[0]==0 && bp
[1]==0 && bp
[2]==0 && bp
[3]==0) {
1418 ND_PRINT((ndo
, "NONESP-encap: "));
1419 isakmp_print(ndo
, bp
+4, length
-4, bp2
);
1423 /* must be an ESP packet */
1425 int nh
, enh
, padlen
;
1428 ND_PRINT((ndo
, "UDP-encap: "));
1430 advance
= esp_print(ndo
, bp
, length
, bp2
, &enh
, &padlen
);
1435 length
-= advance
+ padlen
;
1438 ip_print_inner(ndo
, bp
, length
, nh
, bp2
);
1443 printf("[|isakmp]");
1449 * c-style: whitesmith