1 /* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 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. 16 * 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 27 * SUCH DAMAGE. 28 * 29 */ 30 31 #ifndef lint 32 static const char rcsid[] = 33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.8.2.1 2000/01/14 19:19:56 mcr Exp $ (LBL)"; 34 #endif 35 36 #ifdef HAVE_CONFIG_H 37 #include "config.h" 38 #endif 39 40 #include <string.h> 41 #include <ctype.h> 42 #include <sys/param.h> 43 #include <sys/time.h> 44 #include <sys/socket.h> 45 46 #if __STDC__ 47 struct mbuf; 48 struct rtentry; 49 #endif 50 #include <net/if.h> 51 52 #include <netinet/in.h> 53 #include <netinet/if_ether.h> 54 #include <netinet/in_systm.h> 55 #include <netinet/ip.h> 56 #include <netinet/ip_var.h> 57 #include <netinet/udp.h> 58 #include <netinet/udp_var.h> 59 #include <netinet/tcp.h> 60 61 #ifdef INET6 62 #include <netinet/ip6.h> 63 #endif 64 65 #include <stdio.h> 66 #include <netdb.h> 67 68 #include "isakmp.h" 69 #include "ipsec_doi.h" 70 #include "oakley.h" 71 #include "interface.h" 72 #include "addrtoname.h" 73 #include "extract.h" /* must come after interface.h */ 74 75 #ifndef HAVE_SOCKADDR_STORAGE 76 #define sockaddr_storage sockaddr 77 #endif 78 79 static u_char *isakmp_sa_print __P((struct isakmp_gen *, u_char *, u_int32_t, 80 u_int32_t, u_int32_t)); 81 static u_char *isakmp_p_print __P((struct isakmp_gen *, u_char *, u_int32_t, 82 u_int32_t, u_int32_t)); 83 static u_char *isakmp_t_print __P((struct isakmp_gen *, u_char *, u_int32_t, 84 u_int32_t, u_int32_t)); 85 static u_char *isakmp_ke_print __P((struct isakmp_gen *, u_char *, u_int32_t, 86 u_int32_t, u_int32_t)); 87 static u_char *isakmp_id_print __P((struct isakmp_gen *, u_char *, u_int32_t, 88 u_int32_t, u_int32_t)); 89 static u_char *isakmp_hash_print __P((struct isakmp_gen *, u_char *, 90 u_int32_t, u_int32_t, u_int32_t)); 91 static u_char *isakmp_nonce_print __P((struct isakmp_gen *, u_char *, 92 u_int32_t, u_int32_t, u_int32_t)); 93 static u_char *isakmp_n_print __P((struct isakmp_gen *, u_char *, u_int32_t, 94 u_int32_t, u_int32_t)); 95 static u_char *isakmp_d_print __P((struct isakmp_gen *, u_char *, u_int32_t, 96 u_int32_t, u_int32_t)); 97 static u_char *isakmp_vid_print __P((struct isakmp_gen *, u_char *, u_int32_t, 98 u_int32_t, u_int32_t)); 99 static u_char *isakmp_sub0_print __P((u_char, struct isakmp_gen *, u_char *, 100 u_int32_t, u_int32_t, u_int32_t)); 101 static u_char *isakmp_sub_print __P((u_char, struct isakmp_gen *, u_char *, 102 u_int32_t, u_int32_t, u_int32_t)); 103 static char *numstr __P((int)); 104 105 #define MAXINITIATORS 20 106 int ninitiator = 0; 107 struct { 108 cookie_t initiator; 109 struct sockaddr_storage iaddr; 110 struct sockaddr_storage raddr; 111 } cookiecache[MAXINITIATORS]; 112 113 /* protocol id */ 114 static char *protoidstr[] = { 115 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", 116 }; 117 118 /* isakmp->np */ 119 static char *npstr[] = { 120 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", 121 "sig", "nonce", "n", "d", "vid" 122 }; 123 124 /* isakmp->np */ 125 static u_char *(*npfunc[]) __P((struct isakmp_gen *, u_char *, u_int32_t, 126 u_int32_t, u_int32_t)) = { 127 NULL, 128 isakmp_sa_print, 129 isakmp_p_print, 130 isakmp_t_print, 131 isakmp_ke_print, 132 isakmp_id_print, 133 NULL, 134 NULL, 135 isakmp_hash_print, 136 NULL, 137 isakmp_nonce_print, 138 isakmp_n_print, 139 isakmp_d_print, 140 isakmp_vid_print, 141 }; 142 143 /* isakmp->etype */ 144 static char *etypestr[] = { 145 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, 146 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 147 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 148 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 149 "oakley-quick", "oakley-newgroup", 150 }; 151 152 #define STR_OR_ID(x, tab) \ 153 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 154 #define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) 155 #define NPSTR(x) STR_OR_ID(x, npstr) 156 #define ETYPESTR(x) STR_OR_ID(x, etypestr) 157 158 #define NPFUNC(x) \ 159 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ 160 ? npfunc[(x)] : NULL) 161 162 static int 163 iszero(u_char *p, size_t l) 164 { 165 while (l--) { 166 if (*p++) 167 return 0; 168 } 169 return 1; 170 } 171 172 /* find cookie from initiator cache */ 173 static int 174 cookie_find(cookie_t *in) 175 { 176 int i; 177 178 for (i = 0; i < MAXINITIATORS; i++) { 179 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) 180 return i; 181 } 182 183 return -1; 184 } 185 186 /* record initiator */ 187 static void 188 cookie_record(cookie_t *in, const u_char *bp2) 189 { 190 int i; 191 struct ip *ip; 192 struct sockaddr_in *sin; 193 #ifdef INET6 194 struct ip6_hdr *ip6; 195 struct sockaddr_in6 *sin6; 196 #endif 197 198 i = cookie_find(in); 199 if (0 <= i) { 200 ninitiator = (i + 1) % MAXINITIATORS; 201 return; 202 } 203 204 ip = (struct ip *)bp2; 205 switch (ip->ip_v) { 206 case 4: 207 memset(&cookiecache[ninitiator].iaddr, 0, 208 sizeof(cookiecache[ninitiator].iaddr)); 209 memset(&cookiecache[ninitiator].raddr, 0, 210 sizeof(cookiecache[ninitiator].raddr)); 211 212 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; 213 #ifdef HAVE_SOCKADDR_SA_LEN 214 sin->sin_len = sizeof(struct sockaddr_in); 215 #endif 216 sin->sin_family = AF_INET; 217 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 218 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; 219 #ifdef HAVE_SOCKADDR_SA_LEN 220 sin->sin_len = sizeof(struct sockaddr_in); 221 #endif 222 sin->sin_family = AF_INET; 223 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); 224 break; 225 #ifdef INET6 226 case 6: 227 memset(&cookiecache[ninitiator].iaddr, 0, 228 sizeof(cookiecache[ninitiator].iaddr)); 229 memset(&cookiecache[ninitiator].raddr, 0, 230 sizeof(cookiecache[ninitiator].raddr)); 231 232 ip6 = (struct ip6_hdr *)bp2; 233 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; 234 #ifdef HAVE_SOCKADDR_SA_LEN 235 sin6->sin6_len = sizeof(struct sockaddr_in6); 236 #endif 237 sin6->sin6_family = AF_INET6; 238 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 239 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; 240 #ifdef HAVE_SOCKADDR_SA_LEN 241 sin6->sin6_len = sizeof(struct sockaddr_in6); 242 #endif 243 sin6->sin6_family = AF_INET6; 244 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 245 break; 246 #endif 247 default: 248 return; 249 } 250 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); 251 ninitiator = (ninitiator + 1) % MAXINITIATORS; 252 } 253 254 #define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) 255 #define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) 256 static int 257 cookie_sidecheck(int i, const u_char *bp2, int initiator) 258 { 259 struct sockaddr_storage ss; 260 struct sockaddr *sa; 261 struct ip *ip; 262 struct sockaddr_in *sin; 263 #ifdef INET6 264 struct ip6_hdr *ip6; 265 struct sockaddr_in6 *sin6; 266 #endif 267 int salen; 268 269 memset(&ss, 0, sizeof(ss)); 270 ip = (struct ip *)bp2; 271 switch (ip->ip_v) { 272 case 4: 273 sin = (struct sockaddr_in *)&ss; 274 #ifdef HAVE_SOCKADDR_SA_LEN 275 sin->sin_len = sizeof(struct sockaddr_in); 276 #endif 277 sin->sin_family = AF_INET; 278 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 279 break; 280 #ifdef INET6 281 case 6: 282 ip6 = (struct ip6_hdr *)bp2; 283 sin6 = (struct sockaddr_in6 *)&ss; 284 #ifdef HAVE_SOCKADDR_SA_LEN 285 sin6->sin6_len = sizeof(struct sockaddr_in6); 286 #endif 287 sin6->sin6_family = AF_INET6; 288 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 289 break; 290 #endif 291 default: 292 return 0; 293 } 294 295 sa = (struct sockaddr *)&ss; 296 if (initiator) { 297 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) 298 return 0; 299 #ifdef HAVE_SOCKADDR_SA_LEN 300 salen = sa->sa_len; 301 #else 302 #ifdef INET6 303 if (sa->sa_family == AF_INET6) 304 salen = sizeof(struct sockaddr_in6); 305 else 306 salen = sizeof(struct sockaddr); 307 #else 308 salen = sizeof(struct sockaddr); 309 #endif 310 #endif 311 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) 312 return 1; 313 } else { 314 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) 315 return 0; 316 #ifdef HAVE_SOCKADDR_SA_LEN 317 salen = sa->sa_len; 318 #else 319 #ifdef INET6 320 if (sa->sa_family == AF_INET6) 321 salen = sizeof(struct sockaddr_in6); 322 else 323 salen = sizeof(struct sockaddr); 324 #else 325 salen = sizeof(struct sockaddr); 326 #endif 327 #endif 328 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) 329 return 1; 330 } 331 return 0; 332 } 333 334 static void 335 rawprint(caddr_t loc, size_t len) 336 { 337 static u_char *p; 338 int i; 339 340 p = (u_char *)loc; 341 for (i = 0; i < len; i++) 342 printf("%02x", p[i] & 0xff); 343 } 344 345 struct attrmap { 346 char *type; 347 int nvalue; 348 char *value[30]; /*XXX*/ 349 }; 350 351 static u_char * 352 isakmp_attrmap_print(u_char *p, u_char *ep, struct attrmap *map, size_t nmap) 353 { 354 u_short *q; 355 int totlen; 356 u_int32_t t, v; 357 358 q = (u_short *)p; 359 if (p[0] & 0x80) 360 totlen = 4; 361 else 362 totlen = 4 + ntohs(q[1]); 363 if (ep < p + totlen) { 364 printf("[|attr]"); 365 return ep + 1; 366 } 367 368 printf("("); 369 t = ntohs(q[0]) & 0x7fff; 370 if (map && t < nmap && map[t].type) 371 printf("type=%s ", map[t].type); 372 else 373 printf("type=#%d ", t); 374 if (p[0] & 0x80) { 375 printf("value="); 376 v = ntohs(q[1]); 377 if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) 378 printf("%s", map[t].value[v]); 379 else 380 rawprint((caddr_t)&q[1], 2); 381 } else { 382 printf("len=%d value=", ntohs(q[1])); 383 rawprint((caddr_t)&p[4], ntohs(q[1])); 384 } 385 printf(")"); 386 return p + totlen; 387 } 388 389 static u_char * 390 isakmp_attr_print(u_char *p, u_char *ep) 391 { 392 u_short *q; 393 int totlen; 394 u_int32_t t; 395 396 q = (u_short *)p; 397 if (p[0] & 0x80) 398 totlen = 4; 399 else 400 totlen = 4 + ntohs(q[1]); 401 if (ep < p + totlen) { 402 printf("[|attr]"); 403 return ep + 1; 404 } 405 406 printf("("); 407 t = ntohs(q[0]) & 0x7fff; 408 printf("type=#%d ", t); 409 if (p[0] & 0x80) { 410 printf("value="); 411 t = q[1]; 412 rawprint((caddr_t)&q[1], 2); 413 } else { 414 printf("len=%d value=", ntohs(q[1])); 415 rawprint((caddr_t)&p[2], ntohs(q[1])); 416 } 417 printf(")"); 418 return p + totlen; 419 } 420 421 static u_char * 422 isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 423 u_int32_t doi0, u_int32_t proto0) 424 { 425 struct isakmp_pl_sa *p; 426 u_int32_t *q; 427 u_int32_t doi; 428 u_int32_t sit; 429 u_char *cp; 430 int t; 431 432 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); 433 434 p = (struct isakmp_pl_sa *)ext; 435 doi = ntohl(p->doi); 436 if (doi != 1) { 437 printf(" doi=%d", doi); 438 printf(" situation=%u", (u_int32_t)ntohl(p->sit)); 439 return (u_char *)(p + 1); 440 } 441 442 printf(" doi=ipsec"); 443 q = (u_int32_t *)&p->sit; 444 printf(" situation="); 445 t = 0; 446 if (ntohl(*q) & 0x01) { 447 printf("identity"); 448 t++; 449 } 450 if (ntohl(*q) & 0x02) { 451 printf("%ssecrecy", t ? "+" : ""); 452 t++; 453 } 454 if (ntohl(*q) & 0x04) 455 printf("%sintegrity", t ? "+" : ""); 456 sit = htonl(*q++); 457 458 if (sit != 0x01) 459 printf(" ident=%u", (u_int32_t)ntohl(*q++)); 460 461 ext = (struct isakmp_gen *)q; 462 463 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); 464 465 return cp; 466 } 467 468 static u_char * 469 isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 470 u_int32_t doi0, u_int32_t proto0) 471 { 472 struct isakmp_pl_p *p; 473 u_char *cp; 474 475 printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); 476 477 p = (struct isakmp_pl_p *)ext; 478 printf(" #%d protoid=%s transform=%d", 479 p->p_no, PROTOIDSTR(p->prot_id), p->num_t); 480 if (p->spi_size) { 481 printf(" spi="); 482 rawprint((caddr_t)(p + 1), p->spi_size); 483 } 484 485 ext = (struct isakmp_gen *)((u_char *)(p + 1) + p->spi_size); 486 487 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 488 p->prot_id); 489 490 return cp; 491 } 492 493 static char *isakmp_p_map[] = { 494 NULL, "ike", 495 }; 496 497 static char *ah_p_map[] = { 498 NULL, "md5", "sha", "1des", 499 }; 500 501 static char *esp_p_map[] = { 502 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", 503 "blowfish", "3idea", "1des-iv32", "rc4", "null" 504 }; 505 506 static char *ipcomp_p_map[] = { 507 NULL, "oui", "deflate", "lzs", 508 }; 509 510 struct attrmap ipsec_t_map[] = { 511 { NULL, 0, }, 512 { "lifetype", 3, { NULL, "sec", "kb", }, }, 513 { "life", 0, }, 514 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 515 "EC2N 2^185", }, }, 516 { "enc mode", 3, { NULL, "tunnel", "transport", }, }, 517 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, 518 { "keylen", 0, }, 519 { "rounds", 0, }, 520 { "dictsize", 0, }, 521 { "privalg", 0, }, 522 }; 523 524 struct attrmap oakley_t_map[] = { 525 { NULL, 0 }, 526 { "enc", 7, { NULL, "1des", "idea", "blowfish", "rc5", 527 "3des", "cast"}, }, 528 { "hash", 4, { NULL, "md5", "sha1", "tiger", }, }, 529 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", 530 "rsa enc revised", }, }, 531 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 532 "EC2N 2^185", }, }, 533 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, 534 { "group prime", 0, }, 535 { "group gen1", 0, }, 536 { "group gen2", 0, }, 537 { "group curve A", 0, }, 538 { "group curve B", 0, }, 539 { "lifetype", 3, { NULL, "sec", "kb", }, }, 540 { "lifeduration", 0, }, 541 { "prf", 0, }, 542 { "keylen", 0, }, 543 { "field", 0, }, 544 { "order", 0, }, 545 }; 546 547 static u_char * 548 isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 549 u_int32_t doi, u_int32_t proto) 550 { 551 struct isakmp_pl_t *p; 552 u_char *cp; 553 char *idstr; 554 struct attrmap *map; 555 size_t nmap; 556 u_char *ep2; 557 558 printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); 559 560 p = (struct isakmp_pl_t *)ext; 561 562 switch (proto) { 563 case 1: 564 idstr = STR_OR_ID(p->t_id, isakmp_p_map); 565 map = oakley_t_map; 566 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 567 break; 568 case 2: 569 idstr = STR_OR_ID(p->t_id, ah_p_map); 570 map = ipsec_t_map; 571 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 572 break; 573 case 3: 574 idstr = STR_OR_ID(p->t_id, esp_p_map); 575 map = ipsec_t_map; 576 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 577 break; 578 case 4: 579 idstr = STR_OR_ID(p->t_id, ipcomp_p_map); 580 map = ipsec_t_map; 581 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 582 break; 583 default: 584 idstr = NULL; 585 map = NULL; 586 nmap = 0; 587 break; 588 } 589 590 if (idstr) 591 printf(" #%d id=%s ", p->t_no, idstr); 592 else 593 printf(" #%d id=%d ", p->t_no, p->t_id); 594 cp = (u_char *)(p + 1); 595 ep2 = (u_char *)p + ntohs(ext->len); 596 while (cp < ep && cp < ep2) { 597 if (map && nmap) { 598 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2, 599 map, nmap); 600 } else 601 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2); 602 } 603 if (ep < ep2) 604 printf("..."); 605 return cp; 606 } 607 608 static u_char * 609 isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 610 u_int32_t doi, u_int32_t proto) 611 { 612 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); 613 614 printf(" key len=%d", ntohs(ext->len) - 4); 615 if (2 < vflag && 4 < ntohs(ext->len)) { 616 printf(" "); 617 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4); 618 } 619 return (u_char *)ext + ntohs(ext->len); 620 } 621 622 static u_char * 623 isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 624 u_int32_t doi, u_int32_t proto) 625 { 626 #define USE_IPSECDOI_IN_PHASE1 1 627 struct isakmp_pl_id *p; 628 static char *idtypestr[] = { 629 "IPv4", "IPv4net", "IPv6", "IPv6net", 630 }; 631 static char *ipsecidtypestr[] = { 632 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", 633 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", 634 "keyid", 635 }; 636 int len; 637 u_char *data; 638 639 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); 640 641 p = (struct isakmp_pl_id *)ext; 642 if (sizeof(*p) < ext->len) 643 data = (u_char *)(p + 1); 644 else 645 data = NULL; 646 len = ntohs(ext->len) - sizeof(*p); 647 648 #if 0 /*debug*/ 649 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); 650 #endif 651 switch (phase) { 652 #ifndef USE_IPSECDOI_IN_PHASE1 653 case 1: 654 #endif 655 default: 656 printf(" idtype=%s", STR_OR_ID(p->d.id_type, idtypestr)); 657 printf(" doi_data=%u", 658 (u_int32_t)(ntohl(p->d.doi_data) & 0xffffff)); 659 break; 660 661 #ifdef USE_IPSECDOI_IN_PHASE1 662 case 1: 663 #endif 664 case 2: 665 { 666 struct ipsecdoi_id *p; 667 struct protoent *pe; 668 669 p = (struct ipsecdoi_id *)ext; 670 printf(" idtype=%s", STR_OR_ID(p->type, ipsecidtypestr)); 671 setprotoent(1); 672 pe = getprotobynumber(p->proto_id); 673 if (pe) 674 printf(" protoid=%s", pe->p_name); 675 else 676 printf(" protoid=%s", PROTOIDSTR(p->proto_id)); 677 endprotoent(); 678 printf(" port=%d", ntohs(p->port)); 679 if (!len) 680 break; 681 switch (p->type) { 682 case IPSECDOI_ID_IPV4_ADDR: 683 printf(" len=%d %s", len, ipaddr_string(data)); 684 len = 0; 685 break; 686 case IPSECDOI_ID_FQDN: 687 case IPSECDOI_ID_USER_FQDN: 688 { 689 int i; 690 printf(" len=%d ", len); 691 for (i = 0; i < len; i++) { 692 if (isprint(data[i])) 693 printf("%c", data[i]); 694 else 695 printf("\\%03o", data[i]); 696 } 697 len = 0; 698 break; 699 } 700 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 701 { 702 u_char *mask; 703 mask = data + sizeof(struct in_addr); 704 printf(" len=%d %s/%u.%u.%u.%u", len, 705 ipaddr_string(data), 706 mask[0], mask[1], mask[2], mask[3]); 707 len = 0; 708 break; 709 } 710 #ifdef INET6 711 case IPSECDOI_ID_IPV6_ADDR: 712 printf(" len=%d %s", len, ip6addr_string(data)); 713 len = 0; 714 break; 715 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 716 { 717 u_int32_t *mask; 718 mask = (u_int32_t *)(data + sizeof(struct in6_addr)); 719 /*XXX*/ 720 printf(" len=%d %s/0x%08x%08x%08x%08x", len, 721 ip6addr_string(data), 722 mask[0], mask[1], mask[2], mask[3]); 723 len = 0; 724 break; 725 } 726 #endif /*INET6*/ 727 case IPSECDOI_ID_IPV4_ADDR_RANGE: 728 printf(" len=%d %s-%s", len, ipaddr_string(data), 729 ipaddr_string(data + sizeof(struct in_addr))); 730 len = 0; 731 break; 732 #ifdef INET6 733 case IPSECDOI_ID_IPV6_ADDR_RANGE: 734 printf(" len=%d %s-%s", len, ip6addr_string(data), 735 ip6addr_string(data + sizeof(struct in6_addr))); 736 len = 0; 737 break; 738 #endif /*INET6*/ 739 case IPSECDOI_ID_DER_ASN1_DN: 740 case IPSECDOI_ID_DER_ASN1_GN: 741 case IPSECDOI_ID_KEY_ID: 742 break; 743 } 744 break; 745 } 746 } 747 if (data && len) { 748 len -= sizeof(*p); 749 printf(" len=%d", len); 750 if (2 < vflag) { 751 printf(" "); 752 rawprint((caddr_t)data, len); 753 } 754 } 755 return (u_char *)ext + ntohs(ext->len); 756 } 757 758 static u_char * 759 isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 760 u_int32_t doi, u_int32_t proto) 761 { 762 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); 763 764 printf(" len=%d", ntohs(ext->len) - 4); 765 if (2 < vflag && 4 < ntohs(ext->len)) { 766 printf(" "); 767 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4); 768 } 769 return (u_char *)ext + ntohs(ext->len); 770 } 771 772 static u_char * 773 isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 774 u_int32_t doi, u_int32_t proto) 775 { 776 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); 777 778 printf(" n len=%d", ntohs(ext->len) - 4); 779 if (2 < vflag && 4 < ntohs(ext->len)) { 780 printf(" "); 781 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4); 782 } 783 return (u_char *)ext + ntohs(ext->len); 784 } 785 786 static u_char * 787 isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 788 u_int32_t doi0, u_int32_t proto0) 789 { 790 struct isakmp_pl_n *p; 791 u_char *cp; 792 u_char *ep2; 793 u_int32_t doi; 794 u_int32_t proto; 795 static char *notifystr[] = { 796 NULL, "INVALID-PAYLOAD-TYPE", 797 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", 798 "INVALID-COOKIE", "INVALID-MAJOR-VERSION", 799 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", 800 "INVALID-FLAGS", "INVALID-MESSAGE-ID", 801 "INVALID-PROTOCOL-ID", "INVALID-SPI", 802 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", 803 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", 804 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", 805 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", 806 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", 807 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", 808 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", 809 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", 810 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", 811 "UNEQUAL-PAYLOAD-LENGTHS", 812 }; 813 static char *ipsecnotifystr[] = { 814 "RESPONDER-LIFETIME", "REPLAY-STATUS", 815 "INITIAL-CONTACT", 816 }; 817 /* NOTE: these macro must be called with x in proper range */ 818 #define NOTIFYSTR(x) \ 819 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr)) 820 #define IPSECNOTIFYSTR(x) \ 821 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr)) 822 823 printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); 824 825 p = (struct isakmp_pl_n *)ext; 826 doi = ntohl(p->doi); 827 proto = p->prot_id; 828 if (doi != 1) { 829 printf(" doi=%d", doi); 830 printf(" proto=%d", proto); 831 printf(" type=%s", NOTIFYSTR(ntohs(p->type))); 832 if (p->spi_size) { 833 printf(" spi="); 834 rawprint((caddr_t)(p + 1), p->spi_size); 835 } 836 return (u_char *)(p + 1) + p->spi_size; 837 } 838 839 printf(" doi=ipsec"); 840 printf(" proto=%s", PROTOIDSTR(proto)); 841 if (ntohs(p->type) < 8192) 842 printf(" type=%s", NOTIFYSTR(ntohs(p->type))); 843 else if (ntohs(p->type) < 16384) 844 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p->type))); 845 else if (ntohs(p->type) < 24576) 846 printf(" type=%s", NOTIFYSTR(ntohs(p->type))); 847 else if (ntohs(p->type) < 40960) 848 printf(" type=%s", IPSECNOTIFYSTR(ntohs(p->type))); 849 else 850 printf(" type=%s", NOTIFYSTR(ntohs(p->type))); 851 if (p->spi_size) { 852 printf(" spi="); 853 rawprint((caddr_t)(p + 1), p->spi_size); 854 } 855 856 cp = (u_char *)(p + 1) + p->spi_size; 857 ep2 = (u_char *)p + ntohs(ext->len); 858 859 if (cp < ep) { 860 printf(" orig=("); 861 switch (ntohs(p->type)) { 862 case IPSECDOI_NTYPE_RESPONDER_LIFETIME: 863 { 864 struct attrmap *map = oakley_t_map; 865 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 866 while (cp < ep && cp < ep2) { 867 cp = isakmp_attrmap_print(cp, 868 (ep < ep2) ? ep : ep2, map, nmap); 869 } 870 break; 871 } 872 case IPSECDOI_NTYPE_REPLAY_STATUS: 873 printf("replay detection %sabled", 874 (*(u_int32_t *)cp) ? "en" : "dis"); 875 break; 876 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: 877 isakmp_sub_print(ISAKMP_NPTYPE_SA, 878 (struct isakmp_gen *)cp, ep, phase, doi, proto); 879 break; 880 default: 881 /* NULL is dummy */ 882 isakmp_print(cp, 883 ntohs(ext->len) - sizeof(*p) - p->spi_size, 884 NULL); 885 } 886 printf(")"); 887 } 888 return (u_char *)ext + ntohs(ext->len); 889 } 890 891 static u_char * 892 isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 893 u_int32_t doi0, u_int32_t proto0) 894 { 895 struct isakmp_pl_d *p; 896 u_int8_t *q; 897 u_int32_t doi; 898 u_int32_t proto; 899 int i; 900 901 printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); 902 903 p = (struct isakmp_pl_d *)ext; 904 doi = ntohl(p->doi); 905 proto = p->prot_id; 906 if (doi != 1) { 907 printf(" doi=%u", doi); 908 printf(" proto=%u", proto); 909 } else { 910 printf(" doi=ipsec"); 911 printf(" proto=%s", PROTOIDSTR(proto)); 912 } 913 printf(" spilen=%u", p->spi_size); 914 printf(" nspi=%u", ntohs(p->num_spi)); 915 printf(" spi="); 916 q = (u_int8_t *)(p + 1); 917 for (i = 0; i < ntohs(p->num_spi); i++) { 918 if (i != 0) 919 printf(","); 920 rawprint((caddr_t)q, p->spi_size); 921 q += p->spi_size; 922 } 923 return q; 924 } 925 926 static u_char * 927 isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 928 u_int32_t doi, u_int32_t proto) 929 { 930 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); 931 932 printf(" len=%d", ntohs(ext->len) - 4); 933 if (2 < vflag && 4 < ntohs(ext->len)) { 934 printf(" "); 935 rawprint((caddr_t)(ext + 1), ntohs(ext->len) - 4); 936 } 937 return (u_char *)ext + ntohs(ext->len); 938 } 939 940 static u_char * 941 isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep, 942 u_int32_t phase, u_int32_t doi, u_int32_t proto) 943 { 944 u_char *cp; 945 946 cp = (u_char *)ext; 947 948 if (NPFUNC(np)) 949 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); 950 else { 951 printf("%s", NPSTR(np)); 952 cp += ntohs(ext->len); 953 } 954 return cp; 955 } 956 957 static u_char * 958 isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep, 959 u_int32_t phase, u_int32_t doi, u_int32_t proto) 960 { 961 u_char *cp; 962 static int depth = 0; 963 int i; 964 965 cp = (u_char *)ext; 966 967 while (np) { 968 if (ep < (u_char *)ext + ntohs(ext->len)) { 969 printf(" [|%s]", NPSTR(np)); 970 cp = ep + 1; 971 break; 972 } 973 depth++; 974 printf("\n"); 975 for (i = 0; i < depth; i++) 976 printf(" "); 977 printf("("); 978 cp = isakmp_sub0_print(np, ext, ep, phase, doi, proto); 979 printf(")"); 980 depth--; 981 982 np = ext->np; 983 ext = (struct isakmp_gen *)cp; 984 } 985 return cp; 986 } 987 988 static char * 989 numstr(int x) 990 { 991 static char buf[20]; 992 sprintf(buf, "#%d", x); 993 return buf; 994 } 995 996 void 997 isakmp_print(const u_char *bp, u_int length, const u_char *bp2) 998 { 999 struct isakmp *base; 1000 u_char *ep; 1001 u_char np; 1002 int i; 1003 int phase; 1004 int major, minor; 1005 1006 base = (struct isakmp *)bp; 1007 ep = (u_char *)snapend; 1008 1009 if ((struct isakmp *)ep < base + 1) { 1010 printf("[|isakmp]"); 1011 return; 1012 } 1013 1014 printf("isakmp"); 1015 if (vflag) { 1016 major = (base->vers & ISAKMP_VERS_MAJOR) 1017 >> ISAKMP_VERS_MAJOR_SHIFT; 1018 minor = (base->vers & ISAKMP_VERS_MINOR) 1019 >> ISAKMP_VERS_MINOR_SHIFT; 1020 printf(" %d.%d", major, minor); 1021 } 1022 1023 if (vflag) { 1024 printf(" msgid "); 1025 rawprint((caddr_t)&base->msgid, sizeof(base->msgid)); 1026 } 1027 1028 if (1 < vflag) { 1029 printf(" cookie "); 1030 rawprint((caddr_t)&base->i_ck, sizeof(base->i_ck)); 1031 printf("->"); 1032 rawprint((caddr_t)&base->r_ck, sizeof(base->r_ck)); 1033 } 1034 printf(":"); 1035 1036 phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; 1037 if (phase == 1) 1038 printf(" phase %d", phase); 1039 else 1040 printf(" phase %d/others", phase); 1041 1042 i = cookie_find(&base->i_ck); 1043 if (i < 0) { 1044 if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { 1045 /* the first packet */ 1046 printf(" I"); 1047 if (bp2) 1048 cookie_record(&base->i_ck, bp2); 1049 } else 1050 printf(" ?"); 1051 } else { 1052 if (bp2 && cookie_isinitiator(i, bp2)) 1053 printf(" I"); 1054 else if (bp2 && cookie_isresponder(i, bp2)) 1055 printf(" R"); 1056 else 1057 printf(" ?"); 1058 } 1059 1060 printf(" %s", ETYPESTR(base->etype)); 1061 if (base->flags) { 1062 printf("[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", 1063 base->flags & ISAKMP_FLAG_C ? "C" : ""); 1064 } 1065 printf(":"); 1066 1067 { 1068 struct isakmp_gen *ext; 1069 int nparen; 1070 1071 #define CHECKLEN(p, np) \ 1072 if (ep < (u_char *)(p)) { \ 1073 printf(" [|%s]", NPSTR(np)); \ 1074 goto done; \ 1075 } 1076 1077 /* regardless of phase... */ 1078 if (base->flags & ISAKMP_FLAG_E) { 1079 /* 1080 * encrypted, nothing we can do right now. 1081 * we hope to decrypt the packet in the future... 1082 */ 1083 printf(" [|%s]", NPSTR(base->np)); 1084 goto done; 1085 } 1086 1087 nparen = 0; 1088 CHECKLEN(base + 1, base->np) 1089 1090 np = base->np; 1091 ext = (struct isakmp_gen *)(base + 1); 1092 isakmp_sub_print(np, ext, ep, phase, 0, 0); 1093 } 1094 1095 done: 1096 if (vflag) { 1097 if (ntohl(base->len) != length) { 1098 printf(" (len mismatch: isakmp %u/ip %d)", 1099 (u_int32_t)ntohl(base->len), length); 1100 } 1101 } 1102 } 1103