2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the project nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 static const char rcsid
[] _U_
=
33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.53 2006-08-27 18:48:29 mcr Exp $ (LBL)";
40 #include <tcpdump-stdinc.h>
47 #include "ipsec_doi.h"
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h" /* must come after interface.h */
58 #ifndef HAVE_SOCKADDR_STORAGE
59 #define sockaddr_storage sockaddr
62 static const u_char
*isakmp_sa_print(const struct isakmp_gen
*,
63 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
64 static const u_char
*isakmp_p_print(const struct isakmp_gen
*,
65 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
66 static const u_char
*isakmp_t_print(const struct isakmp_gen
*,
67 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
68 static const u_char
*isakmp_ke_print(const struct isakmp_gen
*,
69 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
70 static const u_char
*isakmp_id_print(const struct isakmp_gen
*,
71 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
72 static const u_char
*isakmp_cert_print(const struct isakmp_gen
*,
73 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
74 static const u_char
*isakmp_cr_print(const struct isakmp_gen
*,
75 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
76 static const u_char
*isakmp_sig_print(const struct isakmp_gen
*,
77 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
78 static const u_char
*isakmp_hash_print(const struct isakmp_gen
*,
79 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
80 static const u_char
*isakmp_nonce_print(const struct isakmp_gen
*,
81 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
82 static const u_char
*isakmp_n_print(const struct isakmp_gen
*,
83 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
84 static const u_char
*isakmp_d_print(const struct isakmp_gen
*,
85 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
86 static const u_char
*isakmp_vid_print(const struct isakmp_gen
*,
87 u_int
, const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
88 static const u_char
*isakmp_sub0_print(u_char
, const struct isakmp_gen
*,
89 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
90 static const u_char
*isakmp_sub_print(u_char
, const struct isakmp_gen
*,
91 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int);
92 static char *numstr(int);
93 static void safememcpy(void *, const void *, size_t);
95 #define MAXINITIATORS 20
99 struct sockaddr_storage iaddr
;
100 struct sockaddr_storage raddr
;
101 } cookiecache
[MAXINITIATORS
];
104 static const char *protoidstr
[] = {
105 NULL
, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
109 static const char *npstr
[] = {
110 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash",
111 "sig", "nonce", "n", "d", "vid"
115 static const u_char
*(*npfunc
[])(const struct isakmp_gen
*, u_int
,
116 const u_char
*, u_int32_t
, u_int32_t
, u_int32_t
, int) = {
134 static const char *etypestr
[] = {
135 "none", "base", "ident", "auth", "agg", "inf", NULL
, NULL
,
136 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
137 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
138 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
139 "oakley-quick", "oakley-newgroup",
142 #define STR_OR_ID(x, tab) \
143 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
144 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
145 #define NPSTR(x) STR_OR_ID(x, npstr)
146 #define ETYPESTR(x) STR_OR_ID(x, etypestr)
149 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
150 ? npfunc[(x)] : NULL)
153 iszero(u_char
*p
, size_t l
)
162 /* find cookie from initiator cache */
164 cookie_find(cookie_t
*in
)
168 for (i
= 0; i
< MAXINITIATORS
; i
++) {
169 if (memcmp(in
, &cookiecache
[i
].initiator
, sizeof(*in
)) == 0)
176 /* record initiator */
178 cookie_record(cookie_t
*in
, const u_char
*bp2
)
182 struct sockaddr_in
*sin
;
185 struct sockaddr_in6
*sin6
;
190 ninitiator
= (i
+ 1) % MAXINITIATORS
;
194 ip
= (struct ip
*)bp2
;
197 memset(&cookiecache
[ninitiator
].iaddr
, 0,
198 sizeof(cookiecache
[ninitiator
].iaddr
));
199 memset(&cookiecache
[ninitiator
].raddr
, 0,
200 sizeof(cookiecache
[ninitiator
].raddr
));
202 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].iaddr
;
203 #ifdef HAVE_SOCKADDR_SA_LEN
204 sin
->sin_len
= sizeof(struct sockaddr_in
);
206 sin
->sin_family
= AF_INET
;
207 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
208 sin
= (struct sockaddr_in
*)&cookiecache
[ninitiator
].raddr
;
209 #ifdef HAVE_SOCKADDR_SA_LEN
210 sin
->sin_len
= sizeof(struct sockaddr_in
);
212 sin
->sin_family
= AF_INET
;
213 memcpy(&sin
->sin_addr
, &ip
->ip_dst
, sizeof(ip
->ip_dst
));
217 memset(&cookiecache
[ninitiator
].iaddr
, 0,
218 sizeof(cookiecache
[ninitiator
].iaddr
));
219 memset(&cookiecache
[ninitiator
].raddr
, 0,
220 sizeof(cookiecache
[ninitiator
].raddr
));
222 ip6
= (struct ip6_hdr
*)bp2
;
223 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].iaddr
;
224 #ifdef HAVE_SOCKADDR_SA_LEN
225 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
227 sin6
->sin6_family
= AF_INET6
;
228 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
229 sin6
= (struct sockaddr_in6
*)&cookiecache
[ninitiator
].raddr
;
230 #ifdef HAVE_SOCKADDR_SA_LEN
231 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
233 sin6
->sin6_family
= AF_INET6
;
234 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_dst
, sizeof(ip6
->ip6_dst
));
240 memcpy(&cookiecache
[ninitiator
].initiator
, in
, sizeof(*in
));
241 ninitiator
= (ninitiator
+ 1) % MAXINITIATORS
;
244 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
245 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
247 cookie_sidecheck(int i
, const u_char
*bp2
, int initiator
)
249 struct sockaddr_storage ss
;
252 struct sockaddr_in
*sin
;
255 struct sockaddr_in6
*sin6
;
259 memset(&ss
, 0, sizeof(ss
));
260 ip
= (struct ip
*)bp2
;
263 sin
= (struct sockaddr_in
*)&ss
;
264 #ifdef HAVE_SOCKADDR_SA_LEN
265 sin
->sin_len
= sizeof(struct sockaddr_in
);
267 sin
->sin_family
= AF_INET
;
268 memcpy(&sin
->sin_addr
, &ip
->ip_src
, sizeof(ip
->ip_src
));
272 ip6
= (struct ip6_hdr
*)bp2
;
273 sin6
= (struct sockaddr_in6
*)&ss
;
274 #ifdef HAVE_SOCKADDR_SA_LEN
275 sin6
->sin6_len
= sizeof(struct sockaddr_in6
);
277 sin6
->sin6_family
= AF_INET6
;
278 memcpy(&sin6
->sin6_addr
, &ip6
->ip6_src
, sizeof(ip6
->ip6_src
));
285 sa
= (struct sockaddr
*)&ss
;
287 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].iaddr
)->sa_family
)
289 #ifdef HAVE_SOCKADDR_SA_LEN
293 if (sa
->sa_family
== AF_INET6
)
294 salen
= sizeof(struct sockaddr_in6
);
296 salen
= sizeof(struct sockaddr
);
298 salen
= sizeof(struct sockaddr
);
301 if (memcmp(&ss
, &cookiecache
[i
].iaddr
, salen
) == 0)
304 if (sa
->sa_family
!= ((struct sockaddr
*)&cookiecache
[i
].raddr
)->sa_family
)
306 #ifdef HAVE_SOCKADDR_SA_LEN
310 if (sa
->sa_family
== AF_INET6
)
311 salen
= sizeof(struct sockaddr_in6
);
313 salen
= sizeof(struct sockaddr
);
315 salen
= sizeof(struct sockaddr
);
318 if (memcmp(&ss
, &cookiecache
[i
].raddr
, salen
) == 0)
325 rawprint(caddr_t loc
, size_t len
)
333 for (i
= 0; i
< len
; i
++)
334 printf("%02x", p
[i
] & 0xff);
343 const char *value
[30]; /*XXX*/
346 static const u_char
*
347 isakmp_attrmap_print(const u_char
*p
, const u_char
*ep
,
348 const struct attrmap
*map
, size_t nmap
)
358 totlen
= 4 + EXTRACT_16BITS(&q
[1]);
359 if (ep
< p
+ totlen
) {
365 t
= EXTRACT_16BITS(&q
[0]) & 0x7fff;
366 if (map
&& t
< nmap
&& map
[t
].type
)
367 printf("type=%s ", map
[t
].type
);
369 printf("type=#%d ", t
);
372 v
= EXTRACT_16BITS(&q
[1]);
373 if (map
&& t
< nmap
&& v
< map
[t
].nvalue
&& map
[t
].value
[v
])
374 printf("%s", map
[t
].value
[v
]);
376 rawprint((caddr_t
)&q
[1], 2);
378 printf("len=%d value=", EXTRACT_16BITS(&q
[1]));
379 rawprint((caddr_t
)&p
[4], EXTRACT_16BITS(&q
[1]));
385 static const u_char
*
386 isakmp_attr_print(const u_char
*p
, const u_char
*ep
)
396 totlen
= 4 + EXTRACT_16BITS(&q
[1]);
397 if (ep
< p
+ totlen
) {
403 t
= EXTRACT_16BITS(&q
[0]) & 0x7fff;
404 printf("type=#%d ", t
);
408 rawprint((caddr_t
)&q
[1], 2);
410 printf("len=%d value=", EXTRACT_16BITS(&q
[1]));
411 rawprint((caddr_t
)&p
[2], EXTRACT_16BITS(&q
[1]));
417 static const u_char
*
418 isakmp_sa_print(const struct isakmp_gen
*ext
,
420 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0 _U_
,
421 u_int32_t proto0
, int depth
)
423 const struct isakmp_pl_sa
*p
;
424 struct isakmp_pl_sa sa
;
426 u_int32_t doi
, sit
, ident
;
427 const u_char
*cp
, *np
;
430 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA
));
432 p
= (struct isakmp_pl_sa
*)ext
;
434 safememcpy(&sa
, ext
, sizeof(sa
));
438 printf(" doi=%d", doi
);
439 printf(" situation=%u", (u_int32_t
)ntohl(sa
.sit
));
440 return (u_char
*)(p
+ 1);
443 printf(" doi=ipsec");
444 q
= (u_int32_t
*)&sa
.sit
;
445 printf(" situation=");
452 printf("%ssecrecy", t
? "+" : "");
456 printf("%sintegrity", t
? "+" : "");
458 np
= (u_char
*)ext
+ sizeof(sa
);
460 TCHECK2(*(ext
+ 1), sizeof(ident
));
461 safememcpy(&ident
, ext
+ 1, sizeof(ident
));
462 printf(" ident=%u", (u_int32_t
)ntohl(ident
));
466 ext
= (struct isakmp_gen
*)np
;
469 cp
= isakmp_sub_print(ISAKMP_NPTYPE_P
, ext
, ep
, phase
, doi
, proto0
,
474 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SA
));
478 static const u_char
*
479 isakmp_p_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
480 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0
,
481 u_int32_t proto0 _U_
, int depth
)
483 const struct isakmp_pl_p
*p
;
484 struct isakmp_pl_p prop
;
487 printf("%s:", NPSTR(ISAKMP_NPTYPE_P
));
489 p
= (struct isakmp_pl_p
*)ext
;
491 safememcpy(&prop
, ext
, sizeof(prop
));
492 printf(" #%d protoid=%s transform=%d",
493 prop
.p_no
, PROTOIDSTR(prop
.prot_id
), prop
.num_t
);
496 if (!rawprint((caddr_t
)(p
+ 1), prop
.spi_size
))
500 ext
= (struct isakmp_gen
*)((u_char
*)(p
+ 1) + prop
.spi_size
);
503 cp
= isakmp_sub_print(ISAKMP_NPTYPE_T
, ext
, ep
, phase
, doi0
,
504 prop
.prot_id
, depth
);
508 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_P
));
512 static const char *isakmp_p_map
[] = {
516 static const char *ah_p_map
[] = {
517 NULL
, "(reserved)", "md5", "sha", "1des",
518 "sha2-256", "sha2-384", "sha2-512",
521 static const char *esp_p_map
[] = {
522 NULL
, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
523 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
526 static const char *ipcomp_p_map
[] = {
527 NULL
, "oui", "deflate", "lzs",
530 const struct attrmap ipsec_t_map
[] = {
531 { NULL
, 0, { NULL
} },
532 { "lifetype", 3, { NULL
, "sec", "kb", }, },
533 { "life", 0, { NULL
} },
534 { "group desc", 18, { NULL
, "modp768",
535 "modp1024", /* group 2 */
536 "EC2N 2^155", /* group 3 */
537 "EC2N 2^185", /* group 4 */
538 "modp1536", /* group 5 */
539 "iana-grp06", "iana-grp07", /* reserved */
540 "iana-grp08", "iana-grp09",
541 "iana-grp10", "iana-grp11",
542 "iana-grp12", "iana-grp13",
543 "modp2048", /* group 14 */
544 "modp3072", /* group 15 */
545 "modp4096", /* group 16 */
546 "modp6144", /* group 17 */
547 "modp8192", /* group 18 */
549 { "enc mode", 3, { NULL
, "tunnel", "transport", }, },
550 { "auth", 5, { NULL
, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
551 { "keylen", 0, { NULL
} },
552 { "rounds", 0, { NULL
} },
553 { "dictsize", 0, { NULL
} },
554 { "privalg", 0, { NULL
} },
557 const struct attrmap oakley_t_map
[] = {
558 { NULL
, 0, { NULL
} },
559 { "enc", 8, { NULL
, "1des", "idea", "blowfish", "rc5",
560 "3des", "cast", "aes", }, },
561 { "hash", 7, { NULL
, "md5", "sha1", "tiger",
562 "sha2-256", "sha2-384", "sha2-512", }, },
563 { "auth", 6, { NULL
, "preshared", "dss", "rsa sig", "rsa enc",
564 "rsa enc revised", }, },
565 { "group desc", 18, { NULL
, "modp768",
566 "modp1024", /* group 2 */
567 "EC2N 2^155", /* group 3 */
568 "EC2N 2^185", /* group 4 */
569 "modp1536", /* group 5 */
570 "iana-grp06", "iana-grp07", /* reserved */
571 "iana-grp08", "iana-grp09",
572 "iana-grp10", "iana-grp11",
573 "iana-grp12", "iana-grp13",
574 "modp2048", /* group 14 */
575 "modp3072", /* group 15 */
576 "modp4096", /* group 16 */
577 "modp6144", /* group 17 */
578 "modp8192", /* group 18 */
580 { "group type", 4, { NULL
, "MODP", "ECP", "EC2N", }, },
581 { "group prime", 0, { NULL
} },
582 { "group gen1", 0, { NULL
} },
583 { "group gen2", 0, { NULL
} },
584 { "group curve A", 0, { NULL
} },
585 { "group curve B", 0, { NULL
} },
586 { "lifetype", 3, { NULL
, "sec", "kb", }, },
587 { "lifeduration", 0, { NULL
} },
588 { "prf", 0, { NULL
} },
589 { "keylen", 0, { NULL
} },
590 { "field", 0, { NULL
} },
591 { "order", 0, { NULL
} },
594 static const u_char
*
595 isakmp_t_print(const struct isakmp_gen
*ext
, u_int item_len
,
596 const u_char
*ep
, u_int32_t phase _U_
, u_int32_t doi _U_
,
597 u_int32_t proto
, int depth _U_
)
599 const struct isakmp_pl_t
*p
;
600 struct isakmp_pl_t t
;
603 const struct attrmap
*map
;
607 printf("%s:", NPSTR(ISAKMP_NPTYPE_T
));
609 p
= (struct isakmp_pl_t
*)ext
;
611 safememcpy(&t
, ext
, sizeof(t
));
615 idstr
= STR_OR_ID(t
.t_id
, isakmp_p_map
);
617 nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
620 idstr
= STR_OR_ID(t
.t_id
, ah_p_map
);
622 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
625 idstr
= STR_OR_ID(t
.t_id
, esp_p_map
);
627 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
630 idstr
= STR_OR_ID(t
.t_id
, ipcomp_p_map
);
632 nmap
= sizeof(ipsec_t_map
)/sizeof(ipsec_t_map
[0]);
642 printf(" #%d id=%s ", t
.t_no
, idstr
);
644 printf(" #%d id=%d ", t
.t_no
, t
.t_id
);
645 cp
= (u_char
*)(p
+ 1);
646 ep2
= (u_char
*)p
+ item_len
;
647 while (cp
< ep
&& cp
< ep2
) {
649 cp
= isakmp_attrmap_print(cp
, (ep
< ep2
) ? ep
: ep2
,
652 cp
= isakmp_attr_print(cp
, (ep
< ep2
) ? ep
: ep2
);
658 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T
));
662 static const u_char
*
663 isakmp_ke_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
664 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
665 u_int32_t proto _U_
, int depth _U_
)
669 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE
));
672 safememcpy(&e
, ext
, sizeof(e
));
673 printf(" key len=%d", ntohs(e
.len
) - 4);
674 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
676 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
679 return (u_char
*)ext
+ ntohs(e
.len
);
681 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE
));
685 static const u_char
*
686 isakmp_id_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
687 const u_char
*ep _U_
, u_int32_t phase
, u_int32_t doi _U_
,
688 u_int32_t proto _U_
, int depth _U_
)
690 #define USE_IPSECDOI_IN_PHASE1 1
691 const struct isakmp_pl_id
*p
;
692 struct isakmp_pl_id id
;
693 static const char *idtypestr
[] = {
694 "IPv4", "IPv4net", "IPv6", "IPv6net",
696 static const char *ipsecidtypestr
[] = {
697 NULL
, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
698 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
704 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID
));
706 p
= (struct isakmp_pl_id
*)ext
;
708 safememcpy(&id
, ext
, sizeof(id
));
709 if (sizeof(*p
) < item_len
) {
710 data
= (u_char
*)(p
+ 1);
711 len
= item_len
- sizeof(*p
);
718 printf(" [phase=%d doi=%d proto=%d]", phase
, doi
, proto
);
721 #ifndef USE_IPSECDOI_IN_PHASE1
725 printf(" idtype=%s", STR_OR_ID(id
.d
.id_type
, idtypestr
));
726 printf(" doi_data=%u",
727 (u_int32_t
)(ntohl(id
.d
.doi_data
) & 0xffffff));
730 #ifdef USE_IPSECDOI_IN_PHASE1
735 const struct ipsecdoi_id
*p
;
736 struct ipsecdoi_id id
;
739 p
= (struct ipsecdoi_id
*)ext
;
741 safememcpy(&id
, ext
, sizeof(id
));
742 printf(" idtype=%s", STR_OR_ID(id
.type
, ipsecidtypestr
));
747 pe
= getprotobynumber(id
.proto_id
);
749 printf(" protoid=%s", pe
->p_name
);
754 /* it DOES NOT mean IPPROTO_IP! */
755 printf(" protoid=%s", "0");
757 printf(" port=%d", ntohs(id
.port
));
764 case IPSECDOI_ID_IPV4_ADDR
:
766 printf(" len=%d [bad: < 4]", len
);
768 printf(" len=%d %s", len
, ipaddr_string(data
));
771 case IPSECDOI_ID_FQDN
:
772 case IPSECDOI_ID_USER_FQDN
:
775 printf(" len=%d ", len
);
776 for (i
= 0; i
< len
; i
++)
777 safeputchar(data
[i
]);
781 case IPSECDOI_ID_IPV4_ADDR_SUBNET
:
785 printf(" len=%d [bad: < 8]", len
);
787 mask
= data
+ sizeof(struct in_addr
);
788 printf(" len=%d %s/%u.%u.%u.%u", len
,
790 mask
[0], mask
[1], mask
[2], mask
[3]);
796 case IPSECDOI_ID_IPV6_ADDR
:
798 printf(" len=%d [bad: < 16]", len
);
800 printf(" len=%d %s", len
, ip6addr_string(data
));
803 case IPSECDOI_ID_IPV6_ADDR_SUBNET
:
805 const u_int32_t
*mask
;
807 printf(" len=%d [bad: < 20]", len
);
809 mask
= (u_int32_t
*)(data
+ sizeof(struct in6_addr
));
811 printf(" len=%d %s/0x%08x%08x%08x%08x", len
,
812 ip6addr_string(data
),
813 mask
[0], mask
[1], mask
[2], mask
[3]);
819 case IPSECDOI_ID_IPV4_ADDR_RANGE
:
821 printf(" len=%d [bad: < 8]", len
);
823 printf(" len=%d %s-%s", len
,
825 ipaddr_string(data
+ sizeof(struct in_addr
)));
830 case IPSECDOI_ID_IPV6_ADDR_RANGE
:
832 printf(" len=%d [bad: < 32]", len
);
834 printf(" len=%d %s-%s", len
,
835 ip6addr_string(data
),
836 ip6addr_string(data
+ sizeof(struct in6_addr
)));
841 case IPSECDOI_ID_DER_ASN1_DN
:
842 case IPSECDOI_ID_DER_ASN1_GN
:
843 case IPSECDOI_ID_KEY_ID
:
850 printf(" len=%d", len
);
853 if (!rawprint((caddr_t
)data
, len
))
857 return (u_char
*)ext
+ item_len
;
859 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID
));
863 static const u_char
*
864 isakmp_cert_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
865 const u_char
*ep _U_
, u_int32_t phase _U_
,
867 u_int32_t proto0 _U_
, int depth _U_
)
869 const struct isakmp_pl_cert
*p
;
870 struct isakmp_pl_cert cert
;
871 static const char *certstr
[] = {
872 "none", "pkcs7", "pgp", "dns",
873 "x509sign", "x509ke", "kerberos", "crl",
874 "arl", "spki", "x509attr",
877 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT
));
879 p
= (struct isakmp_pl_cert
*)ext
;
881 safememcpy(&cert
, ext
, sizeof(cert
));
882 printf(" len=%d", item_len
- 4);
883 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
884 if (2 < vflag
&& 4 < item_len
) {
886 if (!rawprint((caddr_t
)(ext
+ 1), item_len
- 4))
889 return (u_char
*)ext
+ item_len
;
891 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT
));
895 static const u_char
*
896 isakmp_cr_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
897 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi0 _U_
,
898 u_int32_t proto0 _U_
, int depth _U_
)
900 const struct isakmp_pl_cert
*p
;
901 struct isakmp_pl_cert cert
;
902 static const char *certstr
[] = {
903 "none", "pkcs7", "pgp", "dns",
904 "x509sign", "x509ke", "kerberos", "crl",
905 "arl", "spki", "x509attr",
908 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR
));
910 p
= (struct isakmp_pl_cert
*)ext
;
912 safememcpy(&cert
, ext
, sizeof(cert
));
913 printf(" len=%d", item_len
- 4);
914 printf(" type=%s", STR_OR_ID((cert
.encode
), certstr
));
915 if (2 < vflag
&& 4 < item_len
) {
917 if (!rawprint((caddr_t
)(ext
+ 1), item_len
- 4))
920 return (u_char
*)ext
+ item_len
;
922 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR
));
926 static const u_char
*
927 isakmp_hash_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
928 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
929 u_int32_t proto _U_
, int depth _U_
)
933 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH
));
936 safememcpy(&e
, ext
, sizeof(e
));
937 printf(" len=%d", ntohs(e
.len
) - 4);
938 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
940 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
943 return (u_char
*)ext
+ ntohs(e
.len
);
945 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH
));
949 static const u_char
*
950 isakmp_sig_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
951 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi _U_
,
952 u_int32_t proto _U_
, int depth _U_
)
956 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG
));
959 safememcpy(&e
, ext
, sizeof(e
));
960 printf(" len=%d", ntohs(e
.len
) - 4);
961 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
963 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
966 return (u_char
*)ext
+ ntohs(e
.len
);
968 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG
));
972 static const u_char
*
973 isakmp_nonce_print(const struct isakmp_gen
*ext
,
975 const u_char
*ep _U_
,
976 u_int32_t phase _U_
, u_int32_t doi _U_
,
977 u_int32_t proto _U_
, int depth _U_
)
981 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE
));
984 safememcpy(&e
, ext
, sizeof(e
));
985 printf(" n len=%d", ntohs(e
.len
) - 4);
986 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
988 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
991 return (u_char
*)ext
+ ntohs(e
.len
);
993 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE
));
997 static const u_char
*
998 isakmp_n_print(const struct isakmp_gen
*ext
, u_int item_len
,
999 const u_char
*ep
, u_int32_t phase
, u_int32_t doi0 _U_
,
1000 u_int32_t proto0 _U_
, int depth
)
1002 struct isakmp_pl_n
*p
, n
;
1007 static const char *notify_error_str
[] = {
1008 NULL
, "INVALID-PAYLOAD-TYPE",
1009 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
1010 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
1011 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
1012 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
1013 "INVALID-PROTOCOL-ID", "INVALID-SPI",
1014 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
1015 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
1016 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
1017 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
1018 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
1019 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
1020 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
1021 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
1022 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
1023 "UNEQUAL-PAYLOAD-LENGTHS",
1025 static const char *ipsec_notify_error_str
[] = {
1028 static const char *notify_status_str
[] = {
1031 static const char *ipsec_notify_status_str
[] = {
1032 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1035 /* NOTE: these macro must be called with x in proper range */
1038 #define NOTIFY_ERROR_STR(x) \
1039 STR_OR_ID((x), notify_error_str)
1042 #define IPSEC_NOTIFY_ERROR_STR(x) \
1043 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1046 #define NOTIFY_STATUS_STR(x) \
1047 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1050 #define IPSEC_NOTIFY_STATUS_STR(x) \
1051 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1053 printf("%s:", NPSTR(ISAKMP_NPTYPE_N
));
1055 p
= (struct isakmp_pl_n
*)ext
;
1057 safememcpy(&n
, ext
, sizeof(n
));
1061 printf(" doi=%d", doi
);
1062 printf(" proto=%d", proto
);
1063 if (ntohs(n
.type
) < 8192)
1064 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n
.type
)));
1065 else if (ntohs(n
.type
) < 16384)
1066 printf(" type=%s", numstr(ntohs(n
.type
)));
1067 else if (ntohs(n
.type
) < 24576)
1068 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n
.type
)));
1070 printf(" type=%s", numstr(ntohs(n
.type
)));
1073 if (!rawprint((caddr_t
)(p
+ 1), n
.spi_size
))
1076 return (u_char
*)(p
+ 1) + n
.spi_size
;
1079 printf(" doi=ipsec");
1080 printf(" proto=%s", PROTOIDSTR(proto
));
1081 if (ntohs(n
.type
) < 8192)
1082 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n
.type
)));
1083 else if (ntohs(n
.type
) < 16384)
1084 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n
.type
)));
1085 else if (ntohs(n
.type
) < 24576)
1086 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n
.type
)));
1087 else if (ntohs(n
.type
) < 32768)
1088 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n
.type
)));
1090 printf(" type=%s", numstr(ntohs(n
.type
)));
1093 if (!rawprint((caddr_t
)(p
+ 1), n
.spi_size
))
1097 cp
= (u_char
*)(p
+ 1) + n
.spi_size
;
1098 ep2
= (u_char
*)p
+ item_len
;
1102 switch (ntohs(n
.type
)) {
1103 case IPSECDOI_NTYPE_RESPONDER_LIFETIME
:
1105 const struct attrmap
*map
= oakley_t_map
;
1106 size_t nmap
= sizeof(oakley_t_map
)/sizeof(oakley_t_map
[0]);
1107 while (cp
< ep
&& cp
< ep2
) {
1108 cp
= isakmp_attrmap_print(cp
,
1109 (ep
< ep2
) ? ep
: ep2
, map
, nmap
);
1113 case IPSECDOI_NTYPE_REPLAY_STATUS
:
1114 printf("replay detection %sabled",
1115 (*(u_int32_t
*)cp
) ? "en" : "dis");
1117 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN
:
1118 if (isakmp_sub_print(ISAKMP_NPTYPE_SA
,
1119 (struct isakmp_gen
*)cp
, ep
, phase
, doi
, proto
,
1125 isakmp_print(gndo
, cp
,
1126 item_len
- sizeof(*p
) - n
.spi_size
,
1131 return (u_char
*)ext
+ item_len
;
1133 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N
));
1137 static const u_char
*
1138 isakmp_d_print(const struct isakmp_gen
*ext
, u_int item_len _U_
,
1139 const u_char
*ep _U_
, u_int32_t phase _U_
, u_int32_t doi0 _U_
,
1140 u_int32_t proto0 _U_
, int depth _U_
)
1142 const struct isakmp_pl_d
*p
;
1143 struct isakmp_pl_d d
;
1149 printf("%s:", NPSTR(ISAKMP_NPTYPE_D
));
1151 p
= (struct isakmp_pl_d
*)ext
;
1153 safememcpy(&d
, ext
, sizeof(d
));
1157 printf(" doi=%u", doi
);
1158 printf(" proto=%u", proto
);
1160 printf(" doi=ipsec");
1161 printf(" proto=%s", PROTOIDSTR(proto
));
1163 printf(" spilen=%u", d
.spi_size
);
1164 printf(" nspi=%u", ntohs(d
.num_spi
));
1166 q
= (u_int8_t
*)(p
+ 1);
1167 for (i
= 0; i
< ntohs(d
.num_spi
); i
++) {
1170 if (!rawprint((caddr_t
)q
, d
.spi_size
))
1176 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D
));
1180 static const u_char
*
1181 isakmp_vid_print(const struct isakmp_gen
*ext
,
1182 u_int item_len _U_
, const u_char
*ep _U_
,
1183 u_int32_t phase _U_
, u_int32_t doi _U_
,
1184 u_int32_t proto _U_
, int depth _U_
)
1186 struct isakmp_gen e
;
1188 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID
));
1191 safememcpy(&e
, ext
, sizeof(e
));
1192 printf(" len=%d", ntohs(e
.len
) - 4);
1193 if (2 < vflag
&& 4 < ntohs(e
.len
)) {
1195 if (!rawprint((caddr_t
)(ext
+ 1), ntohs(e
.len
) - 4))
1198 return (u_char
*)ext
+ ntohs(e
.len
);
1200 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID
));
1204 static const u_char
*
1205 isakmp_sub0_print(u_char np
, const struct isakmp_gen
*ext
, const u_char
*ep
,
1206 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
, int depth
)
1209 struct isakmp_gen e
;
1214 safememcpy(&e
, ext
, sizeof(e
));
1217 * Since we can't have a payload length of less than 4 bytes,
1218 * we need to bail out here if the generic header is nonsensical
1219 * or truncated, otherwise we could loop forever processing
1220 * zero-length items or otherwise misdissect the packet.
1222 item_len
= ntohs(e
.len
);
1228 * XXX - what if item_len is too short, or too long,
1229 * for this payload type?
1231 cp
= (*npfunc
[np
])(ext
, item_len
, ep
, phase
, doi
, proto
, depth
);
1233 printf("%s", NPSTR(np
));
1239 printf(" [|isakmp]");
1243 static const u_char
*
1244 isakmp_sub_print(u_char np
, const struct isakmp_gen
*ext
, const u_char
*ep
,
1245 u_int32_t phase
, u_int32_t doi
, u_int32_t proto
, int depth
)
1249 struct isakmp_gen e
;
1251 cp
= (const u_char
*)ext
;
1256 safememcpy(&e
, ext
, sizeof(e
));
1258 TCHECK2(*ext
, ntohs(e
.len
));
1262 for (i
= 0; i
< depth
; i
++)
1265 cp
= isakmp_sub0_print(np
, ext
, ep
, phase
, doi
, proto
, depth
);
1270 /* Zero-length subitem */
1275 ext
= (struct isakmp_gen
*)cp
;
1279 printf(" [|%s]", NPSTR(np
));
1286 static char buf
[20];
1287 snprintf(buf
, sizeof(buf
), "#%d", x
);
1292 * some compiler tries to optimize memcpy(), using the alignment constraint
1293 * on the argument pointer type. by using this function, we try to avoid the
1297 safememcpy(void *p
, const void *q
, size_t l
)
1303 isakmp_print(netdissect_options
*ndo
,
1304 const u_char
*bp
, u_int length
,
1307 const struct isakmp
*p
;
1315 p
= (const struct isakmp
*)bp
;
1316 ep
= ndo
->ndo_snapend
;
1318 if ((struct isakmp
*)ep
< p
+ 1) {
1319 printf("[|isakmp]");
1323 safememcpy(&base
, p
, sizeof(base
));
1327 major
= (base
.vers
& ISAKMP_VERS_MAJOR
)
1328 >> ISAKMP_VERS_MAJOR_SHIFT
;
1329 minor
= (base
.vers
& ISAKMP_VERS_MINOR
)
1330 >> ISAKMP_VERS_MINOR_SHIFT
;
1331 printf(" %d.%d", major
, minor
);
1336 rawprint((caddr_t
)&base
.msgid
, sizeof(base
.msgid
));
1341 rawprint((caddr_t
)&base
.i_ck
, sizeof(base
.i_ck
));
1343 rawprint((caddr_t
)&base
.r_ck
, sizeof(base
.r_ck
));
1347 phase
= (*(u_int32_t
*)base
.msgid
== 0) ? 1 : 2;
1349 printf(" phase %d", phase
);
1351 printf(" phase %d/others", phase
);
1353 i
= cookie_find(&base
.i_ck
);
1355 if (iszero((u_char
*)&base
.r_ck
, sizeof(base
.r_ck
))) {
1356 /* the first packet */
1359 cookie_record(&base
.i_ck
, bp2
);
1363 if (bp2
&& cookie_isinitiator(i
, bp2
))
1365 else if (bp2
&& cookie_isresponder(i
, bp2
))
1371 printf(" %s", ETYPESTR(base
.etype
));
1373 printf("[%s%s]", base
.flags
& ISAKMP_FLAG_E
? "E" : "",
1374 base
.flags
& ISAKMP_FLAG_C
? "C" : "");
1378 const struct isakmp_gen
*ext
;
1381 #define CHECKLEN(p, np) \
1382 if (ep < (u_char *)(p)) { \
1383 printf(" [|%s]", NPSTR(np)); \
1389 /* regardless of phase... */
1390 if (base
.flags
& ISAKMP_FLAG_E
) {
1392 * encrypted, nothing we can do right now.
1393 * we hope to decrypt the packet in the future...
1395 printf(" [encrypted %s]", NPSTR(base
.np
));
1400 CHECKLEN(p
+ 1, base
.np
)
1403 ext
= (struct isakmp_gen
*)(p
+ 1);
1404 isakmp_sub_print(np
, ext
, ep
, phase
, 0, 0, 0);
1409 if (ntohl(base
.len
) != length
) {
1410 printf(" (len mismatch: isakmp %u/ip %u)",
1411 (u_int32_t
)ntohl(base
.len
), length
);
1417 isakmp_rfc3948_print(netdissect_options
*ndo
,
1418 const u_char
*bp
, u_int length
,
1422 ep
= ndo
->ndo_snapend
;
1424 if(length
== 1 && bp
[0]==0xff) {
1425 ND_PRINT((ndo
, "isakmp-nat-keep-alive"));
1434 * see if this is an IKE packet
1436 if(bp
[0]==0 && bp
[1]==0 && bp
[2]==0 && bp
[3]==0) {
1437 ND_PRINT((ndo
, "NONESP-encap: "));
1438 isakmp_print(ndo
, bp
+4, length
-4, bp2
);
1442 /* must be an ESP packet */
1444 int nh
, enh
, padlen
;
1447 ND_PRINT((ndo
, "UDP-encap: "));
1449 advance
= esp_print(ndo
, bp
, length
, bp2
, &enh
, &padlen
);
1454 length
-= advance
+ padlen
;
1457 ip_print_inner(ndo
, bp
, length
, nh
, bp2
);
1462 printf("[|isakmp]");
1468 * c-style: whitesmith