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