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.51 2005/04/07 00:28:17 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", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
536 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
537 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
538 { "keylen", 0, { NULL } },
539 { "rounds", 0, { NULL } },
540 { "dictsize", 0, { NULL } },
541 { "privalg", 0, { NULL } },
544 const struct attrmap oakley_t_map[] = {
545 { NULL, 0, { NULL } },
546 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
547 "3des", "cast", "aes", }, },
548 { "hash", 7, { NULL, "md5", "sha1", "tiger",
549 "sha2-256", "sha2-384", "sha2-512", }, },
550 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
551 "rsa enc revised", }, },
552 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155",
554 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
555 { "group prime", 0, { NULL } },
556 { "group gen1", 0, { NULL } },
557 { "group gen2", 0, { NULL } },
558 { "group curve A", 0, { NULL } },
559 { "group curve B", 0, { NULL } },
560 { "lifetype", 3, { NULL, "sec", "kb", }, },
561 { "lifeduration", 0, { NULL } },
562 { "prf", 0, { NULL } },
563 { "keylen", 0, { NULL } },
564 { "field", 0, { NULL } },
565 { "order", 0, { NULL } },
568 static const u_char *
569 isakmp_t_print(const struct isakmp_gen *ext, u_int item_len,
570 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
571 u_int32_t proto, int depth _U_)
573 const struct isakmp_pl_t *p;
574 struct isakmp_pl_t t;
577 const struct attrmap *map;
581 printf("%s:", NPSTR(ISAKMP_NPTYPE_T));
583 p = (struct isakmp_pl_t *)ext;
585 safememcpy(&t, ext, sizeof(t));
589 idstr = STR_OR_ID(t.t_id, isakmp_p_map);
591 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
594 idstr = STR_OR_ID(t.t_id, ah_p_map);
596 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
599 idstr = STR_OR_ID(t.t_id, esp_p_map);
601 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
604 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
606 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
616 printf(" #%d id=%s ", t.t_no, idstr);
618 printf(" #%d id=%d ", t.t_no, t.t_id);
619 cp = (u_char *)(p + 1);
620 ep2 = (u_char *)p + item_len;
621 while (cp < ep && cp < ep2) {
623 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2,
626 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2);
632 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_T));
636 static const u_char *
637 isakmp_ke_print(const struct isakmp_gen *ext, u_int item_len _U_,
638 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
639 u_int32_t proto _U_, int depth _U_)
643 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE));
646 safememcpy(&e, ext, sizeof(e));
647 printf(" key len=%d", ntohs(e.len) - 4);
648 if (2 < vflag && 4 < ntohs(e.len)) {
650 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
653 return (u_char *)ext + ntohs(e.len);
655 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_KE));
659 static const u_char *
660 isakmp_id_print(const struct isakmp_gen *ext, u_int item_len _U_,
661 const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_,
662 u_int32_t proto _U_, int depth _U_)
664 #define USE_IPSECDOI_IN_PHASE1 1
665 const struct isakmp_pl_id *p;
666 struct isakmp_pl_id id;
667 static const char *idtypestr[] = {
668 "IPv4", "IPv4net", "IPv6", "IPv6net",
670 static const char *ipsecidtypestr[] = {
671 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
672 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
678 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID));
680 p = (struct isakmp_pl_id *)ext;
682 safememcpy(&id, ext, sizeof(id));
683 if (sizeof(*p) < item_len) {
684 data = (u_char *)(p + 1);
685 len = item_len - sizeof(*p);
692 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto);
695 #ifndef USE_IPSECDOI_IN_PHASE1
699 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr));
700 printf(" doi_data=%u",
701 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff));
704 #ifdef USE_IPSECDOI_IN_PHASE1
709 const struct ipsecdoi_id *p;
710 struct ipsecdoi_id id;
713 p = (struct ipsecdoi_id *)ext;
715 safememcpy(&id, ext, sizeof(id));
716 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr));
721 pe = getprotobynumber(id.proto_id);
723 printf(" protoid=%s", pe->p_name);
728 /* it DOES NOT mean IPPROTO_IP! */
729 printf(" protoid=%s", "0");
731 printf(" port=%d", ntohs(id.port));
738 case IPSECDOI_ID_IPV4_ADDR:
740 printf(" len=%d [bad: < 4]", len);
742 printf(" len=%d %s", len, ipaddr_string(data));
745 case IPSECDOI_ID_FQDN:
746 case IPSECDOI_ID_USER_FQDN:
749 printf(" len=%d ", len);
750 for (i = 0; i < len; i++)
751 safeputchar(data[i]);
755 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
759 printf(" len=%d [bad: < 8]", len);
761 mask = data + sizeof(struct in_addr);
762 printf(" len=%d %s/%u.%u.%u.%u", len,
764 mask[0], mask[1], mask[2], mask[3]);
770 case IPSECDOI_ID_IPV6_ADDR:
772 printf(" len=%d [bad: < 16]", len);
774 printf(" len=%d %s", len, ip6addr_string(data));
777 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
779 const u_int32_t *mask;
781 printf(" len=%d [bad: < 20]", len);
783 mask = (u_int32_t *)(data + sizeof(struct in6_addr));
785 printf(" len=%d %s/0x%08x%08x%08x%08x", len,
786 ip6addr_string(data),
787 mask[0], mask[1], mask[2], mask[3]);
793 case IPSECDOI_ID_IPV4_ADDR_RANGE:
795 printf(" len=%d [bad: < 8]", len);
797 printf(" len=%d %s-%s", len,
799 ipaddr_string(data + sizeof(struct in_addr)));
804 case IPSECDOI_ID_IPV6_ADDR_RANGE:
806 printf(" len=%d [bad: < 32]", len);
808 printf(" len=%d %s-%s", len,
809 ip6addr_string(data),
810 ip6addr_string(data + sizeof(struct in6_addr)));
815 case IPSECDOI_ID_DER_ASN1_DN:
816 case IPSECDOI_ID_DER_ASN1_GN:
817 case IPSECDOI_ID_KEY_ID:
824 printf(" len=%d", len);
827 if (!rawprint((caddr_t)data, len))
831 return (u_char *)ext + item_len;
833 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_ID));
837 static const u_char *
838 isakmp_cert_print(const struct isakmp_gen *ext, u_int item_len _U_,
839 const u_char *ep _U_, u_int32_t phase _U_,
841 u_int32_t proto0 _U_, int depth _U_)
843 const struct isakmp_pl_cert *p;
844 struct isakmp_pl_cert cert;
845 static const char *certstr[] = {
846 "none", "pkcs7", "pgp", "dns",
847 "x509sign", "x509ke", "kerberos", "crl",
848 "arl", "spki", "x509attr",
851 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT));
853 p = (struct isakmp_pl_cert *)ext;
855 safememcpy(&cert, ext, sizeof(cert));
856 printf(" len=%d", item_len - 4);
857 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
858 if (2 < vflag && 4 < item_len) {
860 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
863 return (u_char *)ext + item_len;
865 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CERT));
869 static const u_char *
870 isakmp_cr_print(const struct isakmp_gen *ext, u_int item_len _U_,
871 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
872 u_int32_t proto0 _U_, int depth _U_)
874 const struct isakmp_pl_cert *p;
875 struct isakmp_pl_cert cert;
876 static const char *certstr[] = {
877 "none", "pkcs7", "pgp", "dns",
878 "x509sign", "x509ke", "kerberos", "crl",
879 "arl", "spki", "x509attr",
882 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR));
884 p = (struct isakmp_pl_cert *)ext;
886 safememcpy(&cert, ext, sizeof(cert));
887 printf(" len=%d", item_len - 4);
888 printf(" type=%s", STR_OR_ID((cert.encode), certstr));
889 if (2 < vflag && 4 < item_len) {
891 if (!rawprint((caddr_t)(ext + 1), item_len - 4))
894 return (u_char *)ext + item_len;
896 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_CR));
900 static const u_char *
901 isakmp_hash_print(const struct isakmp_gen *ext, u_int item_len _U_,
902 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
903 u_int32_t proto _U_, int depth _U_)
907 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH));
910 safememcpy(&e, ext, sizeof(e));
911 printf(" len=%d", ntohs(e.len) - 4);
912 if (2 < vflag && 4 < ntohs(e.len)) {
914 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
917 return (u_char *)ext + ntohs(e.len);
919 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_HASH));
923 static const u_char *
924 isakmp_sig_print(const struct isakmp_gen *ext, u_int item_len _U_,
925 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
926 u_int32_t proto _U_, int depth _U_)
930 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG));
933 safememcpy(&e, ext, sizeof(e));
934 printf(" len=%d", ntohs(e.len) - 4);
935 if (2 < vflag && 4 < ntohs(e.len)) {
937 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
940 return (u_char *)ext + ntohs(e.len);
942 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_SIG));
946 static const u_char *
947 isakmp_nonce_print(const struct isakmp_gen *ext,
949 const u_char *ep _U_,
950 u_int32_t phase _U_, u_int32_t doi _U_,
951 u_int32_t proto _U_, int depth _U_)
955 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE));
958 safememcpy(&e, ext, sizeof(e));
959 printf(" n len=%d", ntohs(e.len) - 4);
960 if (2 < vflag && 4 < ntohs(e.len)) {
962 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
965 return (u_char *)ext + ntohs(e.len);
967 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE));
971 static const u_char *
972 isakmp_n_print(const struct isakmp_gen *ext, u_int item_len,
973 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
974 u_int32_t proto0 _U_, int depth)
976 struct isakmp_pl_n *p, n;
981 static const char *notify_error_str[] = {
982 NULL, "INVALID-PAYLOAD-TYPE",
983 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
984 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
985 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
986 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
987 "INVALID-PROTOCOL-ID", "INVALID-SPI",
988 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
989 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
990 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
991 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
992 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
993 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
994 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
995 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
996 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
997 "UNEQUAL-PAYLOAD-LENGTHS",
999 static const char *ipsec_notify_error_str[] = {
1002 static const char *notify_status_str[] = {
1005 static const char *ipsec_notify_status_str[] = {
1006 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1009 /* NOTE: these macro must be called with x in proper range */
1012 #define NOTIFY_ERROR_STR(x) \
1013 STR_OR_ID((x), notify_error_str)
1016 #define IPSEC_NOTIFY_ERROR_STR(x) \
1017 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1020 #define NOTIFY_STATUS_STR(x) \
1021 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1024 #define IPSEC_NOTIFY_STATUS_STR(x) \
1025 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1027 printf("%s:", NPSTR(ISAKMP_NPTYPE_N));
1029 p = (struct isakmp_pl_n *)ext;
1031 safememcpy(&n, ext, sizeof(n));
1035 printf(" doi=%d", doi);
1036 printf(" proto=%d", proto);
1037 if (ntohs(n.type) < 8192)
1038 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1039 else if (ntohs(n.type) < 16384)
1040 printf(" type=%s", numstr(ntohs(n.type)));
1041 else if (ntohs(n.type) < 24576)
1042 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1044 printf(" type=%s", numstr(ntohs(n.type)));
1047 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1050 return (u_char *)(p + 1) + n.spi_size;
1053 printf(" doi=ipsec");
1054 printf(" proto=%s", PROTOIDSTR(proto));
1055 if (ntohs(n.type) < 8192)
1056 printf(" type=%s", NOTIFY_ERROR_STR(ntohs(n.type)));
1057 else if (ntohs(n.type) < 16384)
1058 printf(" type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)));
1059 else if (ntohs(n.type) < 24576)
1060 printf(" type=%s", NOTIFY_STATUS_STR(ntohs(n.type)));
1061 else if (ntohs(n.type) < 32768)
1062 printf(" type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)));
1064 printf(" type=%s", numstr(ntohs(n.type)));
1067 if (!rawprint((caddr_t)(p + 1), n.spi_size))
1071 cp = (u_char *)(p + 1) + n.spi_size;
1072 ep2 = (u_char *)p + item_len;
1076 switch (ntohs(n.type)) {
1077 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1079 const struct attrmap *map = oakley_t_map;
1080 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1081 while (cp < ep && cp < ep2) {
1082 cp = isakmp_attrmap_print(cp,
1083 (ep < ep2) ? ep : ep2, map, nmap);
1087 case IPSECDOI_NTYPE_REPLAY_STATUS:
1088 printf("replay detection %sabled",
1089 (*(u_int32_t *)cp) ? "en" : "dis");
1091 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
1092 if (isakmp_sub_print(ISAKMP_NPTYPE_SA,
1093 (struct isakmp_gen *)cp, ep, phase, doi, proto,
1099 isakmp_print(gndo, cp,
1100 item_len - sizeof(*p) - n.spi_size,
1105 return (u_char *)ext + item_len;
1107 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_N));
1111 static const u_char *
1112 isakmp_d_print(const struct isakmp_gen *ext, u_int item_len _U_,
1113 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
1114 u_int32_t proto0 _U_, int depth _U_)
1116 const struct isakmp_pl_d *p;
1117 struct isakmp_pl_d d;
1123 printf("%s:", NPSTR(ISAKMP_NPTYPE_D));
1125 p = (struct isakmp_pl_d *)ext;
1127 safememcpy(&d, ext, sizeof(d));
1131 printf(" doi=%u", doi);
1132 printf(" proto=%u", proto);
1134 printf(" doi=ipsec");
1135 printf(" proto=%s", PROTOIDSTR(proto));
1137 printf(" spilen=%u", d.spi_size);
1138 printf(" nspi=%u", ntohs(d.num_spi));
1140 q = (u_int8_t *)(p + 1);
1141 for (i = 0; i < ntohs(d.num_spi); i++) {
1144 if (!rawprint((caddr_t)q, d.spi_size))
1150 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_D));
1154 static const u_char *
1155 isakmp_vid_print(const struct isakmp_gen *ext,
1156 u_int item_len _U_, const u_char *ep _U_,
1157 u_int32_t phase _U_, u_int32_t doi _U_,
1158 u_int32_t proto _U_, int depth _U_)
1160 struct isakmp_gen e;
1162 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID));
1165 safememcpy(&e, ext, sizeof(e));
1166 printf(" len=%d", ntohs(e.len) - 4);
1167 if (2 < vflag && 4 < ntohs(e.len)) {
1169 if (!rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4))
1172 return (u_char *)ext + ntohs(e.len);
1174 printf(" [|%s]", NPSTR(ISAKMP_NPTYPE_VID));
1178 static const u_char *
1179 isakmp_sub0_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1180 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1183 struct isakmp_gen e;
1188 safememcpy(&e, ext, sizeof(e));
1191 * Since we can't have a payload length of less than 4 bytes,
1192 * we need to bail out here if the generic header is nonsensical
1193 * or truncated, otherwise we could loop forever processing
1194 * zero-length items or otherwise misdissect the packet.
1196 item_len = ntohs(e.len);
1202 * XXX - what if item_len is too short, or too long,
1203 * for this payload type?
1205 cp = (*npfunc[np])(ext, item_len, ep, phase, doi, proto, depth);
1207 printf("%s", NPSTR(np));
1213 printf(" [|isakmp]");
1217 static const u_char *
1218 isakmp_sub_print(u_char np, const struct isakmp_gen *ext, const u_char *ep,
1219 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
1223 struct isakmp_gen e;
1225 cp = (const u_char *)ext;
1230 safememcpy(&e, ext, sizeof(e));
1232 TCHECK2(*ext, ntohs(e.len));
1236 for (i = 0; i < depth; i++)
1239 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto, depth);
1244 /* Zero-length subitem */
1249 ext = (struct isakmp_gen *)cp;
1253 printf(" [|%s]", NPSTR(np));
1260 static char buf[20];
1261 snprintf(buf, sizeof(buf), "#%d", x);
1266 * some compiler tries to optimize memcpy(), using the alignment constraint
1267 * on the argument pointer type. by using this function, we try to avoid the
1271 safememcpy(void *p, const void *q, size_t l)
1277 isakmp_print(netdissect_options *ndo,
1278 const u_char *bp, u_int length,
1281 const struct isakmp *p;
1289 p = (const struct isakmp *)bp;
1290 ep = ndo->ndo_snapend;
1292 if ((struct isakmp *)ep < p + 1) {
1293 printf("[|isakmp]");
1297 safememcpy(&base, p, sizeof(base));
1301 major = (base.vers & ISAKMP_VERS_MAJOR)
1302 >> ISAKMP_VERS_MAJOR_SHIFT;
1303 minor = (base.vers & ISAKMP_VERS_MINOR)
1304 >> ISAKMP_VERS_MINOR_SHIFT;
1305 printf(" %d.%d", major, minor);
1310 rawprint((caddr_t)&base.msgid, sizeof(base.msgid));
1315 rawprint((caddr_t)&base.i_ck, sizeof(base.i_ck));
1317 rawprint((caddr_t)&base.r_ck, sizeof(base.r_ck));
1321 phase = (*(u_int32_t *)base.msgid == 0) ? 1 : 2;
1323 printf(" phase %d", phase);
1325 printf(" phase %d/others", phase);
1327 i = cookie_find(&base.i_ck);
1329 if (iszero((u_char *)&base.r_ck, sizeof(base.r_ck))) {
1330 /* the first packet */
1333 cookie_record(&base.i_ck, bp2);
1337 if (bp2 && cookie_isinitiator(i, bp2))
1339 else if (bp2 && cookie_isresponder(i, bp2))
1345 printf(" %s", ETYPESTR(base.etype));
1347 printf("[%s%s]", base.flags & ISAKMP_FLAG_E ? "E" : "",
1348 base.flags & ISAKMP_FLAG_C ? "C" : "");
1352 const struct isakmp_gen *ext;
1355 #define CHECKLEN(p, np) \
1356 if (ep < (u_char *)(p)) { \
1357 printf(" [|%s]", NPSTR(np)); \
1363 /* regardless of phase... */
1364 if (base.flags & ISAKMP_FLAG_E) {
1366 * encrypted, nothing we can do right now.
1367 * we hope to decrypt the packet in the future...
1369 printf(" [encrypted %s]", NPSTR(base.np));
1374 CHECKLEN(p + 1, base.np)
1377 ext = (struct isakmp_gen *)(p + 1);
1378 isakmp_sub_print(np, ext, ep, phase, 0, 0, 0);
1383 if (ntohl(base.len) != length) {
1384 printf(" (len mismatch: isakmp %u/ip %u)",
1385 (u_int32_t)ntohl(base.len), length);
1391 isakmp_rfc3948_print(netdissect_options *ndo,
1392 const u_char *bp, u_int length,
1396 ep = ndo->ndo_snapend;
1398 if(length == 1 && bp[0]==0xff) {
1399 ND_PRINT((ndo, "isakmp-nat-keep-alive"));
1408 * see if this is an IKE packet
1410 if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
1411 ND_PRINT((ndo, "NONESP-encap: "));
1412 isakmp_print(ndo, bp+4, length-4, bp2);
1416 /* must be an ESP packet */
1418 int nh, enh, padlen;
1421 ND_PRINT((ndo, "UDP-encap: "));
1423 advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
1428 length -= advance + padlen;
1431 ip_print_inner(ndo, bp, length, nh, bp2);
1436 printf("[|isakmp]");
1442 * c-style: whitesmith