print-isakmp.c revision 190207
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 32static const char rcsid[] _U_ = 33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.56 2007-08-29 12:31:00 mcr Exp $ (LBL)"; 34#endif 35 36#define NETDISSECT_REWORKED 37#ifdef HAVE_CONFIG_H 38#include "config.h" 39#endif 40 41#include <tcpdump-stdinc.h> 42 43#include <string.h> 44 45#include <stdio.h> 46 47#include "isakmp.h" 48#include "ipsec_doi.h" 49#include "oakley.h" 50#include "interface.h" 51#include "addrtoname.h" 52#include "extract.h" /* must come after interface.h */ 53 54#include "ip.h" 55#ifdef INET6 56#include "ip6.h" 57#endif 58 59#ifndef HAVE_SOCKADDR_STORAGE 60#define sockaddr_storage sockaddr 61#endif 62 63#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \ 64 netdissect_options *ndo, u_char tpay, \ 65 const struct isakmp_gen *ext, \ 66 u_int item_len, \ 67 const u_char *end_pointer, \ 68 u_int32_t phase,\ 69 u_int32_t doi0, \ 70 u_int32_t proto0, int depth) 71 72DECLARE_PRINTER(v1_sa); 73DECLARE_PRINTER(v1_p); 74DECLARE_PRINTER(v1_t); 75DECLARE_PRINTER(v1_ke); 76DECLARE_PRINTER(v1_id); 77DECLARE_PRINTER(v1_cert); 78DECLARE_PRINTER(v1_cr); 79DECLARE_PRINTER(v1_sig); 80DECLARE_PRINTER(v1_hash); 81DECLARE_PRINTER(v1_nonce); 82DECLARE_PRINTER(v1_n); 83DECLARE_PRINTER(v1_d); 84DECLARE_PRINTER(v1_vid); 85 86DECLARE_PRINTER(v2_sa); 87DECLARE_PRINTER(v2_ke); 88DECLARE_PRINTER(v2_ID); 89DECLARE_PRINTER(v2_cert); 90DECLARE_PRINTER(v2_cr); 91DECLARE_PRINTER(v2_auth); 92DECLARE_PRINTER(v2_nonce); 93DECLARE_PRINTER(v2_n); 94DECLARE_PRINTER(v2_d); 95DECLARE_PRINTER(v2_vid); 96DECLARE_PRINTER(v2_TS); 97DECLARE_PRINTER(v2_e); 98DECLARE_PRINTER(v2_cp); 99DECLARE_PRINTER(v2_eap); 100 101static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, 102 const u_char *, u_int32_t, u_int32_t, u_int32_t, int); 103static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, 104 const u_char *, u_int32_t, u_int32_t, u_int32_t, int); 105 106static const u_char *ikev2_sub_print(netdissect_options *ndo, 107 u_char np, const struct isakmp_gen *ext, 108 const u_char *ep, u_int32_t phase, 109 u_int32_t doi, u_int32_t proto, 110 int depth); 111 112 113static char *numstr(int); 114static void safememcpy(void *, const void *, size_t); 115 116static void 117ikev1_print(netdissect_options *ndo, 118 const u_char *bp, u_int length, 119 const u_char *bp2, struct isakmp *base); 120 121#define MAXINITIATORS 20 122int ninitiator = 0; 123struct { 124 cookie_t initiator; 125 struct sockaddr_storage iaddr; 126 struct sockaddr_storage raddr; 127} cookiecache[MAXINITIATORS]; 128 129/* protocol id */ 130static const char *protoidstr[] = { 131 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", 132}; 133 134/* isakmp->np */ 135static const char *npstr[] = { 136 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */ 137 "sig", "nonce", "n", "d", "vid", /* 9 - 13 */ 138 "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */ 139 "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */ 140 "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */ 141 "pay29", "pay30", "pay31", "pay32", /* 29- 32 */ 142 "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */ 143 "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */ 144 "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */ 145 "v2eap", /* 48 */ 146 147}; 148 149/* isakmp->np */ 150static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, 151 const struct isakmp_gen *ext, 152 u_int item_len, 153 const u_char *end_pointer, 154 u_int32_t phase, 155 u_int32_t doi0, 156 u_int32_t proto0, int depth) = { 157 NULL, 158 ikev1_sa_print, 159 ikev1_p_print, 160 ikev1_t_print, 161 ikev1_ke_print, 162 ikev1_id_print, 163 ikev1_cert_print, 164 ikev1_cr_print, 165 ikev1_hash_print, 166 ikev1_sig_print, 167 ikev1_nonce_print, 168 ikev1_n_print, 169 ikev1_d_print, 170 ikev1_vid_print, /* 13 */ 171 NULL, NULL, NULL, NULL, NULL, /* 14- 18 */ 172 NULL, NULL, NULL, NULL, NULL, /* 19- 23 */ 173 NULL, NULL, NULL, NULL, NULL, /* 24- 28 */ 174 NULL, NULL, NULL, NULL, /* 29- 32 */ 175 ikev2_sa_print, /* 33 */ 176 ikev2_ke_print, /* 34 */ 177 ikev2_ID_print, /* 35 */ 178 ikev2_ID_print, /* 36 */ 179 ikev2_cert_print, /* 37 */ 180 ikev2_cr_print, /* 38 */ 181 ikev2_auth_print, /* 39 */ 182 ikev2_nonce_print, /* 40 */ 183 ikev2_n_print, /* 41 */ 184 ikev2_d_print, /* 42 */ 185 ikev2_vid_print, /* 43 */ 186 ikev2_TS_print, /* 44 */ 187 ikev2_TS_print, /* 45 */ 188 ikev2_e_print, /* 46 */ 189 ikev2_cp_print, /* 47 */ 190 ikev2_eap_print, /* 48 */ 191}; 192 193/* isakmp->etype */ 194static const char *etypestr[] = { 195/* IKEv1 exchange types */ 196 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */ 197 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */ 198 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */ 199 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */ 200 "oakley-quick", "oakley-newgroup", /* 32-33 */ 201/* IKEv2 exchange types */ 202 "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */ 203}; 204 205#define STR_OR_ID(x, tab) \ 206 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 207#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) 208#define NPSTR(x) STR_OR_ID(x, npstr) 209#define ETYPESTR(x) STR_OR_ID(x, etypestr) 210 211#define CHECKLEN(p, np) \ 212 if (ep < (u_char *)(p)) { \ 213 ND_PRINT((ndo," [|%s]", NPSTR(np))); \ 214 goto done; \ 215 } 216 217 218#define NPFUNC(x) \ 219 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ 220 ? npfunc[(x)] : NULL) 221 222static int 223iszero(u_char *p, size_t l) 224{ 225 while (l--) { 226 if (*p++) 227 return 0; 228 } 229 return 1; 230} 231 232/* find cookie from initiator cache */ 233static int 234cookie_find(cookie_t *in) 235{ 236 int i; 237 238 for (i = 0; i < MAXINITIATORS; i++) { 239 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) 240 return i; 241 } 242 243 return -1; 244} 245 246/* record initiator */ 247static void 248cookie_record(cookie_t *in, const u_char *bp2) 249{ 250 int i; 251 struct ip *ip; 252 struct sockaddr_in *sin; 253#ifdef INET6 254 struct ip6_hdr *ip6; 255 struct sockaddr_in6 *sin6; 256#endif 257 258 i = cookie_find(in); 259 if (0 <= i) { 260 ninitiator = (i + 1) % MAXINITIATORS; 261 return; 262 } 263 264 ip = (struct ip *)bp2; 265 switch (IP_V(ip)) { 266 case 4: 267 memset(&cookiecache[ninitiator].iaddr, 0, 268 sizeof(cookiecache[ninitiator].iaddr)); 269 memset(&cookiecache[ninitiator].raddr, 0, 270 sizeof(cookiecache[ninitiator].raddr)); 271 272 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; 273#ifdef HAVE_SOCKADDR_SA_LEN 274 sin->sin_len = sizeof(struct sockaddr_in); 275#endif 276 sin->sin_family = AF_INET; 277 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 278 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; 279#ifdef HAVE_SOCKADDR_SA_LEN 280 sin->sin_len = sizeof(struct sockaddr_in); 281#endif 282 sin->sin_family = AF_INET; 283 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); 284 break; 285#ifdef INET6 286 case 6: 287 memset(&cookiecache[ninitiator].iaddr, 0, 288 sizeof(cookiecache[ninitiator].iaddr)); 289 memset(&cookiecache[ninitiator].raddr, 0, 290 sizeof(cookiecache[ninitiator].raddr)); 291 292 ip6 = (struct ip6_hdr *)bp2; 293 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; 294#ifdef HAVE_SOCKADDR_SA_LEN 295 sin6->sin6_len = sizeof(struct sockaddr_in6); 296#endif 297 sin6->sin6_family = AF_INET6; 298 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 299 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; 300#ifdef HAVE_SOCKADDR_SA_LEN 301 sin6->sin6_len = sizeof(struct sockaddr_in6); 302#endif 303 sin6->sin6_family = AF_INET6; 304 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 305 break; 306#endif 307 default: 308 return; 309 } 310 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); 311 ninitiator = (ninitiator + 1) % MAXINITIATORS; 312} 313 314#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) 315#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) 316static int 317cookie_sidecheck(int i, const u_char *bp2, int initiator) 318{ 319 struct sockaddr_storage ss; 320 struct sockaddr *sa; 321 struct ip *ip; 322 struct sockaddr_in *sin; 323#ifdef INET6 324 struct ip6_hdr *ip6; 325 struct sockaddr_in6 *sin6; 326#endif 327 int salen; 328 329 memset(&ss, 0, sizeof(ss)); 330 ip = (struct ip *)bp2; 331 switch (IP_V(ip)) { 332 case 4: 333 sin = (struct sockaddr_in *)&ss; 334#ifdef HAVE_SOCKADDR_SA_LEN 335 sin->sin_len = sizeof(struct sockaddr_in); 336#endif 337 sin->sin_family = AF_INET; 338 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 339 break; 340#ifdef INET6 341 case 6: 342 ip6 = (struct ip6_hdr *)bp2; 343 sin6 = (struct sockaddr_in6 *)&ss; 344#ifdef HAVE_SOCKADDR_SA_LEN 345 sin6->sin6_len = sizeof(struct sockaddr_in6); 346#endif 347 sin6->sin6_family = AF_INET6; 348 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 349 break; 350#endif 351 default: 352 return 0; 353 } 354 355 sa = (struct sockaddr *)&ss; 356 if (initiator) { 357 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) 358 return 0; 359#ifdef HAVE_SOCKADDR_SA_LEN 360 salen = sa->sa_len; 361#else 362#ifdef INET6 363 if (sa->sa_family == AF_INET6) 364 salen = sizeof(struct sockaddr_in6); 365 else 366 salen = sizeof(struct sockaddr); 367#else 368 salen = sizeof(struct sockaddr); 369#endif 370#endif 371 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) 372 return 1; 373 } else { 374 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) 375 return 0; 376#ifdef HAVE_SOCKADDR_SA_LEN 377 salen = sa->sa_len; 378#else 379#ifdef INET6 380 if (sa->sa_family == AF_INET6) 381 salen = sizeof(struct sockaddr_in6); 382 else 383 salen = sizeof(struct sockaddr); 384#else 385 salen = sizeof(struct sockaddr); 386#endif 387#endif 388 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) 389 return 1; 390 } 391 return 0; 392} 393 394static int 395rawprint(netdissect_options *ndo, caddr_t loc, size_t len) 396{ 397 static u_char *p; 398 size_t i; 399 400 ND_TCHECK2(*loc, len); 401 402 p = (u_char *)loc; 403 for (i = 0; i < len; i++) 404 ND_PRINT((ndo,"%02x", p[i] & 0xff)); 405 return 1; 406trunc: 407 return 0; 408} 409 410/* 411 * returns false if we run out of data buffer 412 */ 413static int ike_show_somedata(struct netdissect_options *ndo, 414 const u_char *cp, const u_char *ep) 415{ 416 /* there is too much data, just show some of it */ 417 const u_char *end = ep - 20; 418 int elen = 20; 419 int len = ep - cp; 420 if(len > 10) { 421 len = 10; 422 } 423 424 /* really shouldn't happen because of above */ 425 if(end < cp + len) { 426 end = cp+len; 427 elen = ep - end; 428 } 429 430 ND_PRINT((ndo," data=(")); 431 if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc; 432 ND_PRINT((ndo, "...")); 433 if(elen) { 434 if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc; 435 } 436 ND_PRINT((ndo,")")); 437 return 1; 438 439trunc: 440 return 0; 441} 442 443struct attrmap { 444 const char *type; 445 u_int nvalue; 446 const char *value[30]; /*XXX*/ 447}; 448 449static const u_char * 450ikev1_attrmap_print(netdissect_options *ndo, 451 const u_char *p, const u_char *ep, 452 const struct attrmap *map, size_t nmap) 453{ 454 u_int16_t *q; 455 int totlen; 456 u_int32_t t, v; 457 458 q = (u_int16_t *)p; 459 if (p[0] & 0x80) 460 totlen = 4; 461 else 462 totlen = 4 + EXTRACT_16BITS(&q[1]); 463 if (ep < p + totlen) { 464 ND_PRINT((ndo,"[|attr]")); 465 return ep + 1; 466 } 467 468 ND_PRINT((ndo,"(")); 469 t = EXTRACT_16BITS(&q[0]) & 0x7fff; 470 if (map && t < nmap && map[t].type) 471 ND_PRINT((ndo,"type=%s ", map[t].type)); 472 else 473 ND_PRINT((ndo,"type=#%d ", t)); 474 if (p[0] & 0x80) { 475 ND_PRINT((ndo,"value=")); 476 v = EXTRACT_16BITS(&q[1]); 477 if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) 478 ND_PRINT((ndo,"%s", map[t].value[v])); 479 else 480 rawprint(ndo, (caddr_t)&q[1], 2); 481 } else { 482 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); 483 rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1])); 484 } 485 ND_PRINT((ndo,")")); 486 return p + totlen; 487} 488 489static const u_char * 490ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) 491{ 492 u_int16_t *q; 493 int totlen; 494 u_int32_t t; 495 496 q = (u_int16_t *)p; 497 if (p[0] & 0x80) 498 totlen = 4; 499 else 500 totlen = 4 + EXTRACT_16BITS(&q[1]); 501 if (ep < p + totlen) { 502 ND_PRINT((ndo,"[|attr]")); 503 return ep + 1; 504 } 505 506 ND_PRINT((ndo,"(")); 507 t = EXTRACT_16BITS(&q[0]) & 0x7fff; 508 ND_PRINT((ndo,"type=#%d ", t)); 509 if (p[0] & 0x80) { 510 ND_PRINT((ndo,"value=")); 511 t = q[1]; 512 rawprint(ndo, (caddr_t)&q[1], 2); 513 } else { 514 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); 515 rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1])); 516 } 517 ND_PRINT((ndo,")")); 518 return p + totlen; 519} 520 521static const u_char * 522ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, 523 const struct isakmp_gen *ext, 524 u_int item_len _U_, 525 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, 526 u_int32_t proto0, int depth) 527{ 528 const struct ikev1_pl_sa *p; 529 struct ikev1_pl_sa sa; 530 const u_int32_t *q; 531 u_int32_t doi, sit, ident; 532 const u_char *cp, *np; 533 int t; 534 535 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); 536 537 p = (struct ikev1_pl_sa *)ext; 538 ND_TCHECK(*p); 539 safememcpy(&sa, ext, sizeof(sa)); 540 doi = ntohl(sa.doi); 541 sit = ntohl(sa.sit); 542 if (doi != 1) { 543 ND_PRINT((ndo," doi=%d", doi)); 544 ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit))); 545 return (u_char *)(p + 1); 546 } 547 548 ND_PRINT((ndo," doi=ipsec")); 549 q = (u_int32_t *)&sa.sit; 550 ND_PRINT((ndo," situation=")); 551 t = 0; 552 if (sit & 0x01) { 553 ND_PRINT((ndo,"identity")); 554 t++; 555 } 556 if (sit & 0x02) { 557 ND_PRINT((ndo,"%ssecrecy", t ? "+" : "")); 558 t++; 559 } 560 if (sit & 0x04) 561 ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); 562 563 np = (u_char *)ext + sizeof(sa); 564 if (sit != 0x01) { 565 ND_TCHECK2(*(ext + 1), sizeof(ident)); 566 safememcpy(&ident, ext + 1, sizeof(ident)); 567 ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident))); 568 np += sizeof(ident); 569 } 570 571 ext = (struct isakmp_gen *)np; 572 ND_TCHECK(*ext); 573 574 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, 575 depth); 576 577 return cp; 578trunc: 579 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA))); 580 return NULL; 581} 582 583static const u_char * 584ikev1_p_print(netdissect_options *ndo, u_char tpay _U_, 585 const struct isakmp_gen *ext, u_int item_len _U_, 586 const u_char *ep, u_int32_t phase, u_int32_t doi0, 587 u_int32_t proto0 _U_, int depth) 588{ 589 const struct ikev1_pl_p *p; 590 struct ikev1_pl_p prop; 591 const u_char *cp; 592 593 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); 594 595 p = (struct ikev1_pl_p *)ext; 596 ND_TCHECK(*p); 597 safememcpy(&prop, ext, sizeof(prop)); 598 ND_PRINT((ndo," #%d protoid=%s transform=%d", 599 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); 600 if (prop.spi_size) { 601 ND_PRINT((ndo," spi=")); 602 if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) 603 goto trunc; 604 } 605 606 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 607 ND_TCHECK(*ext); 608 609 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 610 prop.prot_id, depth); 611 612 return cp; 613trunc: 614 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); 615 return NULL; 616} 617 618static const char *ikev1_p_map[] = { 619 NULL, "ike", 620}; 621 622static const char *ikev2_t_type_map[]={ 623 NULL, "encr", "prf", "integ", "dh", "esn" 624}; 625 626static const char *ah_p_map[] = { 627 NULL, "(reserved)", "md5", "sha", "1des", 628 "sha2-256", "sha2-384", "sha2-512", 629}; 630 631static const char *prf_p_map[] = { 632 NULL, "hmac-md5", "hmac-sha", "hmac-tiger", 633 "aes128_xcbc" 634}; 635 636static const char *integ_p_map[] = { 637 NULL, "hmac-md5", "hmac-sha", "dec-mac", 638 "kpdk-md5", "aes-xcbc" 639}; 640 641static const char *esn_p_map[] = { 642 "no-esn", "esn" 643}; 644 645static const char *dh_p_map[] = { 646 NULL, "modp768", 647 "modp1024", /* group 2 */ 648 "EC2N 2^155", /* group 3 */ 649 "EC2N 2^185", /* group 4 */ 650 "modp1536", /* group 5 */ 651 "iana-grp06", "iana-grp07", /* reserved */ 652 "iana-grp08", "iana-grp09", 653 "iana-grp10", "iana-grp11", 654 "iana-grp12", "iana-grp13", 655 "modp2048", /* group 14 */ 656 "modp3072", /* group 15 */ 657 "modp4096", /* group 16 */ 658 "modp6144", /* group 17 */ 659 "modp8192", /* group 18 */ 660}; 661 662static const char *esp_p_map[] = { 663 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", 664 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" 665}; 666 667static const char *ipcomp_p_map[] = { 668 NULL, "oui", "deflate", "lzs", 669}; 670 671const struct attrmap ipsec_t_map[] = { 672 { NULL, 0, { NULL } }, 673 { "lifetype", 3, { NULL, "sec", "kb", }, }, 674 { "life", 0, { NULL } }, 675 { "group desc", 18, { NULL, "modp768", 676 "modp1024", /* group 2 */ 677 "EC2N 2^155", /* group 3 */ 678 "EC2N 2^185", /* group 4 */ 679 "modp1536", /* group 5 */ 680 "iana-grp06", "iana-grp07", /* reserved */ 681 "iana-grp08", "iana-grp09", 682 "iana-grp10", "iana-grp11", 683 "iana-grp12", "iana-grp13", 684 "modp2048", /* group 14 */ 685 "modp3072", /* group 15 */ 686 "modp4096", /* group 16 */ 687 "modp6144", /* group 17 */ 688 "modp8192", /* group 18 */ 689 }, }, 690 { "enc mode", 3, { NULL, "tunnel", "transport", }, }, 691 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, 692 { "keylen", 0, { NULL } }, 693 { "rounds", 0, { NULL } }, 694 { "dictsize", 0, { NULL } }, 695 { "privalg", 0, { NULL } }, 696}; 697 698const struct attrmap encr_t_map[] = { 699 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ 700 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */ 701 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */ 702 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */ 703 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */ 704 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/ 705 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/ 706 { "keylen", 14, { NULL }}, 707}; 708 709const struct attrmap oakley_t_map[] = { 710 { NULL, 0, { NULL } }, 711 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", 712 "3des", "cast", "aes", }, }, 713 { "hash", 7, { NULL, "md5", "sha1", "tiger", 714 "sha2-256", "sha2-384", "sha2-512", }, }, 715 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", 716 "rsa enc revised", }, }, 717 { "group desc", 18, { NULL, "modp768", 718 "modp1024", /* group 2 */ 719 "EC2N 2^155", /* group 3 */ 720 "EC2N 2^185", /* group 4 */ 721 "modp1536", /* group 5 */ 722 "iana-grp06", "iana-grp07", /* reserved */ 723 "iana-grp08", "iana-grp09", 724 "iana-grp10", "iana-grp11", 725 "iana-grp12", "iana-grp13", 726 "modp2048", /* group 14 */ 727 "modp3072", /* group 15 */ 728 "modp4096", /* group 16 */ 729 "modp6144", /* group 17 */ 730 "modp8192", /* group 18 */ 731 }, }, 732 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, 733 { "group prime", 0, { NULL } }, 734 { "group gen1", 0, { NULL } }, 735 { "group gen2", 0, { NULL } }, 736 { "group curve A", 0, { NULL } }, 737 { "group curve B", 0, { NULL } }, 738 { "lifetype", 3, { NULL, "sec", "kb", }, }, 739 { "lifeduration", 0, { NULL } }, 740 { "prf", 0, { NULL } }, 741 { "keylen", 0, { NULL } }, 742 { "field", 0, { NULL } }, 743 { "order", 0, { NULL } }, 744}; 745 746static const u_char * 747ikev1_t_print(netdissect_options *ndo, u_char tpay _U_, 748 const struct isakmp_gen *ext, u_int item_len, 749 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, 750 u_int32_t proto, int depth _U_) 751{ 752 const struct ikev1_pl_t *p; 753 struct ikev1_pl_t t; 754 const u_char *cp; 755 const char *idstr; 756 const struct attrmap *map; 757 size_t nmap; 758 const u_char *ep2; 759 760 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); 761 762 p = (struct ikev1_pl_t *)ext; 763 ND_TCHECK(*p); 764 safememcpy(&t, ext, sizeof(t)); 765 766 switch (proto) { 767 case 1: 768 idstr = STR_OR_ID(t.t_id, ikev1_p_map); 769 map = oakley_t_map; 770 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 771 break; 772 case 2: 773 idstr = STR_OR_ID(t.t_id, ah_p_map); 774 map = ipsec_t_map; 775 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 776 break; 777 case 3: 778 idstr = STR_OR_ID(t.t_id, esp_p_map); 779 map = ipsec_t_map; 780 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 781 break; 782 case 4: 783 idstr = STR_OR_ID(t.t_id, ipcomp_p_map); 784 map = ipsec_t_map; 785 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 786 break; 787 default: 788 idstr = NULL; 789 map = NULL; 790 nmap = 0; 791 break; 792 } 793 794 if (idstr) 795 ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); 796 else 797 ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); 798 cp = (u_char *)(p + 1); 799 ep2 = (u_char *)p + item_len; 800 while (cp < ep && cp < ep2) { 801 if (map && nmap) { 802 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, 803 map, nmap); 804 } else 805 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); 806 } 807 if (ep < ep2) 808 ND_PRINT((ndo,"...")); 809 return cp; 810trunc: 811 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); 812 return NULL; 813} 814 815static const u_char * 816ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, 817 const struct isakmp_gen *ext, u_int item_len _U_, 818 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 819 u_int32_t proto _U_, int depth _U_) 820{ 821 struct isakmp_gen e; 822 823 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE))); 824 825 ND_TCHECK(*ext); 826 safememcpy(&e, ext, sizeof(e)); 827 ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); 828 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 829 ND_PRINT((ndo," ")); 830 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 831 goto trunc; 832 } 833 return (u_char *)ext + ntohs(e.len); 834trunc: 835 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); 836 return NULL; 837} 838 839static const u_char * 840ikev1_id_print(netdissect_options *ndo, u_char tpay _U_, 841 const struct isakmp_gen *ext, u_int item_len _U_, 842 const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, 843 u_int32_t proto _U_, int depth _U_) 844{ 845#define USE_IPSECDOI_IN_PHASE1 1 846 const struct ikev1_pl_id *p; 847 struct ikev1_pl_id id; 848 static const char *idtypestr[] = { 849 "IPv4", "IPv4net", "IPv6", "IPv6net", 850 }; 851 static const char *ipsecidtypestr[] = { 852 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", 853 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", 854 "keyid", 855 }; 856 int len; 857 const u_char *data; 858 859 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); 860 861 p = (struct ikev1_pl_id *)ext; 862 ND_TCHECK(*p); 863 safememcpy(&id, ext, sizeof(id)); 864 if (sizeof(*p) < item_len) { 865 data = (u_char *)(p + 1); 866 len = item_len - sizeof(*p); 867 } else { 868 data = NULL; 869 len = 0; 870 } 871 872#if 0 /*debug*/ 873 ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto)); 874#endif 875 switch (phase) { 876#ifndef USE_IPSECDOI_IN_PHASE1 877 case 1: 878#endif 879 default: 880 ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr))); 881 ND_PRINT((ndo," doi_data=%u", 882 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff))); 883 break; 884 885#ifdef USE_IPSECDOI_IN_PHASE1 886 case 1: 887#endif 888 case 2: 889 { 890 const struct ipsecdoi_id *p; 891 struct ipsecdoi_id id; 892 struct protoent *pe; 893 894 p = (struct ipsecdoi_id *)ext; 895 ND_TCHECK(*p); 896 safememcpy(&id, ext, sizeof(id)); 897 ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr))); 898 if (id.proto_id) { 899#ifndef WIN32 900 setprotoent(1); 901#endif /* WIN32 */ 902 pe = getprotobynumber(id.proto_id); 903 if (pe) 904 ND_PRINT((ndo," protoid=%s", pe->p_name)); 905#ifndef WIN32 906 endprotoent(); 907#endif /* WIN32 */ 908 } else { 909 /* it DOES NOT mean IPPROTO_IP! */ 910 ND_PRINT((ndo," protoid=%s", "0")); 911 } 912 ND_PRINT((ndo," port=%d", ntohs(id.port))); 913 if (!len) 914 break; 915 if (data == NULL) 916 goto trunc; 917 ND_TCHECK2(*data, len); 918 switch (id.type) { 919 case IPSECDOI_ID_IPV4_ADDR: 920 if (len < 4) 921 ND_PRINT((ndo," len=%d [bad: < 4]", len)); 922 else 923 ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data))); 924 len = 0; 925 break; 926 case IPSECDOI_ID_FQDN: 927 case IPSECDOI_ID_USER_FQDN: 928 { 929 int i; 930 ND_PRINT((ndo," len=%d ", len)); 931 for (i = 0; i < len; i++) 932 safeputchar(data[i]); 933 len = 0; 934 break; 935 } 936 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 937 { 938 const u_char *mask; 939 if (len < 8) 940 ND_PRINT((ndo," len=%d [bad: < 8]", len)); 941 else { 942 mask = data + sizeof(struct in_addr); 943 ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len, 944 ipaddr_string(data), 945 mask[0], mask[1], mask[2], mask[3])); 946 } 947 len = 0; 948 break; 949 } 950#ifdef INET6 951 case IPSECDOI_ID_IPV6_ADDR: 952 if (len < 16) 953 ND_PRINT((ndo," len=%d [bad: < 16]", len)); 954 else 955 ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data))); 956 len = 0; 957 break; 958 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 959 { 960 const u_int32_t *mask; 961 if (len < 20) 962 ND_PRINT((ndo," len=%d [bad: < 20]", len)); 963 else { 964 mask = (u_int32_t *)(data + sizeof(struct in6_addr)); 965 /*XXX*/ 966 ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len, 967 ip6addr_string(data), 968 mask[0], mask[1], mask[2], mask[3])); 969 } 970 len = 0; 971 break; 972 } 973#endif /*INET6*/ 974 case IPSECDOI_ID_IPV4_ADDR_RANGE: 975 if (len < 8) 976 ND_PRINT((ndo," len=%d [bad: < 8]", len)); 977 else { 978 ND_PRINT((ndo," len=%d %s-%s", len, 979 ipaddr_string(data), 980 ipaddr_string(data + sizeof(struct in_addr)))); 981 } 982 len = 0; 983 break; 984#ifdef INET6 985 case IPSECDOI_ID_IPV6_ADDR_RANGE: 986 if (len < 32) 987 ND_PRINT((ndo," len=%d [bad: < 32]", len)); 988 else { 989 ND_PRINT((ndo," len=%d %s-%s", len, 990 ip6addr_string(data), 991 ip6addr_string(data + sizeof(struct in6_addr)))); 992 } 993 len = 0; 994 break; 995#endif /*INET6*/ 996 case IPSECDOI_ID_DER_ASN1_DN: 997 case IPSECDOI_ID_DER_ASN1_GN: 998 case IPSECDOI_ID_KEY_ID: 999 break; 1000 } 1001 break; 1002 } 1003 } 1004 if (data && len) { 1005 ND_PRINT((ndo," len=%d", len)); 1006 if (2 < ndo->ndo_vflag) { 1007 ND_PRINT((ndo," ")); 1008 if (!rawprint(ndo, (caddr_t)data, len)) 1009 goto trunc; 1010 } 1011 } 1012 return (u_char *)ext + item_len; 1013trunc: 1014 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); 1015 return NULL; 1016} 1017 1018static const u_char * 1019ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, 1020 const struct isakmp_gen *ext, u_int item_len _U_, 1021 const u_char *ep _U_, u_int32_t phase _U_, 1022 u_int32_t doi0 _U_, 1023 u_int32_t proto0 _U_, int depth _U_) 1024{ 1025 const struct ikev1_pl_cert *p; 1026 struct ikev1_pl_cert cert; 1027 static const char *certstr[] = { 1028 "none", "pkcs7", "pgp", "dns", 1029 "x509sign", "x509ke", "kerberos", "crl", 1030 "arl", "spki", "x509attr", 1031 }; 1032 1033 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); 1034 1035 p = (struct ikev1_pl_cert *)ext; 1036 ND_TCHECK(*p); 1037 safememcpy(&cert, ext, sizeof(cert)); 1038 ND_PRINT((ndo," len=%d", item_len - 4)); 1039 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); 1040 if (2 < ndo->ndo_vflag && 4 < item_len) { 1041 ND_PRINT((ndo," ")); 1042 if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) 1043 goto trunc; 1044 } 1045 return (u_char *)ext + item_len; 1046trunc: 1047 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); 1048 return NULL; 1049} 1050 1051static const u_char * 1052ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, 1053 const struct isakmp_gen *ext, u_int item_len _U_, 1054 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, 1055 u_int32_t proto0 _U_, int depth _U_) 1056{ 1057 const struct ikev1_pl_cert *p; 1058 struct ikev1_pl_cert cert; 1059 static const char *certstr[] = { 1060 "none", "pkcs7", "pgp", "dns", 1061 "x509sign", "x509ke", "kerberos", "crl", 1062 "arl", "spki", "x509attr", 1063 }; 1064 1065 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); 1066 1067 p = (struct ikev1_pl_cert *)ext; 1068 ND_TCHECK(*p); 1069 safememcpy(&cert, ext, sizeof(cert)); 1070 ND_PRINT((ndo," len=%d", item_len - 4)); 1071 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); 1072 if (2 < ndo->ndo_vflag && 4 < item_len) { 1073 ND_PRINT((ndo," ")); 1074 if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) 1075 goto trunc; 1076 } 1077 return (u_char *)ext + item_len; 1078trunc: 1079 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); 1080 return NULL; 1081} 1082 1083static const u_char * 1084ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, 1085 const struct isakmp_gen *ext, u_int item_len _U_, 1086 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 1087 u_int32_t proto _U_, int depth _U_) 1088{ 1089 struct isakmp_gen e; 1090 1091 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH))); 1092 1093 ND_TCHECK(*ext); 1094 safememcpy(&e, ext, sizeof(e)); 1095 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1096 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1097 ND_PRINT((ndo," ")); 1098 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1099 goto trunc; 1100 } 1101 return (u_char *)ext + ntohs(e.len); 1102trunc: 1103 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); 1104 return NULL; 1105} 1106 1107static const u_char * 1108ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, 1109 const struct isakmp_gen *ext, u_int item_len _U_, 1110 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 1111 u_int32_t proto _U_, int depth _U_) 1112{ 1113 struct isakmp_gen e; 1114 1115 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG))); 1116 1117 ND_TCHECK(*ext); 1118 safememcpy(&e, ext, sizeof(e)); 1119 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1120 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1121 ND_PRINT((ndo," ")); 1122 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1123 goto trunc; 1124 } 1125 return (u_char *)ext + ntohs(e.len); 1126trunc: 1127 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); 1128 return NULL; 1129} 1130 1131static const u_char * 1132ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, 1133 const struct isakmp_gen *ext, 1134 u_int item_len _U_, 1135 const u_char *ep _U_, 1136 u_int32_t phase _U_, u_int32_t doi _U_, 1137 u_int32_t proto _U_, int depth _U_) 1138{ 1139 struct isakmp_gen e; 1140 1141 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE))); 1142 1143 ND_TCHECK(*ext); 1144 safememcpy(&e, ext, sizeof(e)); 1145 ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); 1146 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1147 ND_PRINT((ndo," ")); 1148 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1149 goto trunc; 1150 } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1151 ND_PRINT((ndo," ")); 1152 if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep)) 1153 goto trunc; 1154 } 1155 return (u_char *)ext + ntohs(e.len); 1156trunc: 1157 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); 1158 return NULL; 1159} 1160 1161static const u_char * 1162ikev1_n_print(netdissect_options *ndo, u_char tpay _U_, 1163 const struct isakmp_gen *ext, u_int item_len, 1164 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, 1165 u_int32_t proto0 _U_, int depth) 1166{ 1167 struct ikev1_pl_n *p, n; 1168 const u_char *cp; 1169 u_char *ep2; 1170 u_int32_t doi; 1171 u_int32_t proto; 1172 static const char *notify_error_str[] = { 1173 NULL, "INVALID-PAYLOAD-TYPE", 1174 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", 1175 "INVALID-COOKIE", "INVALID-MAJOR-VERSION", 1176 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", 1177 "INVALID-FLAGS", "INVALID-MESSAGE-ID", 1178 "INVALID-PROTOCOL-ID", "INVALID-SPI", 1179 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", 1180 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", 1181 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", 1182 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", 1183 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", 1184 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", 1185 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", 1186 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", 1187 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", 1188 "UNEQUAL-PAYLOAD-LENGTHS", 1189 }; 1190 static const char *ipsec_notify_error_str[] = { 1191 "RESERVED", 1192 }; 1193 static const char *notify_status_str[] = { 1194 "CONNECTED", 1195 }; 1196 static const char *ipsec_notify_status_str[] = { 1197 "RESPONDER-LIFETIME", "REPLAY-STATUS", 1198 "INITIAL-CONTACT", 1199 }; 1200/* NOTE: these macro must be called with x in proper range */ 1201 1202/* 0 - 8191 */ 1203#define NOTIFY_ERROR_STR(x) \ 1204 STR_OR_ID((x), notify_error_str) 1205 1206/* 8192 - 16383 */ 1207#define IPSEC_NOTIFY_ERROR_STR(x) \ 1208 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str) 1209 1210/* 16384 - 24575 */ 1211#define NOTIFY_STATUS_STR(x) \ 1212 STR_OR_ID((u_int)((x) - 16384), notify_status_str) 1213 1214/* 24576 - 32767 */ 1215#define IPSEC_NOTIFY_STATUS_STR(x) \ 1216 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str) 1217 1218 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); 1219 1220 p = (struct ikev1_pl_n *)ext; 1221 ND_TCHECK(*p); 1222 safememcpy(&n, ext, sizeof(n)); 1223 doi = ntohl(n.doi); 1224 proto = n.prot_id; 1225 if (doi != 1) { 1226 ND_PRINT((ndo," doi=%d", doi)); 1227 ND_PRINT((ndo," proto=%d", proto)); 1228 if (ntohs(n.type) < 8192) 1229 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); 1230 else if (ntohs(n.type) < 16384) 1231 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 1232 else if (ntohs(n.type) < 24576) 1233 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); 1234 else 1235 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 1236 if (n.spi_size) { 1237 ND_PRINT((ndo," spi=")); 1238 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1239 goto trunc; 1240 } 1241 return (u_char *)(p + 1) + n.spi_size; 1242 } 1243 1244 ND_PRINT((ndo," doi=ipsec")); 1245 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); 1246 if (ntohs(n.type) < 8192) 1247 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); 1248 else if (ntohs(n.type) < 16384) 1249 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)))); 1250 else if (ntohs(n.type) < 24576) 1251 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); 1252 else if (ntohs(n.type) < 32768) 1253 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)))); 1254 else 1255 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 1256 if (n.spi_size) { 1257 ND_PRINT((ndo," spi=")); 1258 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1259 goto trunc; 1260 } 1261 1262 cp = (u_char *)(p + 1) + n.spi_size; 1263 ep2 = (u_char *)p + item_len; 1264 1265 if (cp < ep) { 1266 ND_PRINT((ndo," orig=(")); 1267 switch (ntohs(n.type)) { 1268 case IPSECDOI_NTYPE_RESPONDER_LIFETIME: 1269 { 1270 const struct attrmap *map = oakley_t_map; 1271 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 1272 while (cp < ep && cp < ep2) { 1273 cp = ikev1_attrmap_print(ndo, cp, 1274 (ep < ep2) ? ep : ep2, map, nmap); 1275 } 1276 break; 1277 } 1278 case IPSECDOI_NTYPE_REPLAY_STATUS: 1279 ND_PRINT((ndo,"replay detection %sabled", 1280 (*(u_int32_t *)cp) ? "en" : "dis")); 1281 break; 1282 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: 1283 if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, 1284 (struct isakmp_gen *)cp, ep, phase, doi, proto, 1285 depth) == NULL) 1286 return NULL; 1287 break; 1288 default: 1289 /* NULL is dummy */ 1290 isakmp_print(ndo, cp, 1291 item_len - sizeof(*p) - n.spi_size, 1292 NULL); 1293 } 1294 ND_PRINT((ndo,")")); 1295 } 1296 return (u_char *)ext + item_len; 1297trunc: 1298 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); 1299 return NULL; 1300} 1301 1302static const u_char * 1303ikev1_d_print(netdissect_options *ndo, u_char tpay _U_, 1304 const struct isakmp_gen *ext, u_int item_len _U_, 1305 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, 1306 u_int32_t proto0 _U_, int depth _U_) 1307{ 1308 const struct ikev1_pl_d *p; 1309 struct ikev1_pl_d d; 1310 const u_int8_t *q; 1311 u_int32_t doi; 1312 u_int32_t proto; 1313 int i; 1314 1315 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); 1316 1317 p = (struct ikev1_pl_d *)ext; 1318 ND_TCHECK(*p); 1319 safememcpy(&d, ext, sizeof(d)); 1320 doi = ntohl(d.doi); 1321 proto = d.prot_id; 1322 if (doi != 1) { 1323 ND_PRINT((ndo," doi=%u", doi)); 1324 ND_PRINT((ndo," proto=%u", proto)); 1325 } else { 1326 ND_PRINT((ndo," doi=ipsec")); 1327 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); 1328 } 1329 ND_PRINT((ndo," spilen=%u", d.spi_size)); 1330 ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); 1331 ND_PRINT((ndo," spi=")); 1332 q = (u_int8_t *)(p + 1); 1333 for (i = 0; i < ntohs(d.num_spi); i++) { 1334 if (i != 0) 1335 ND_PRINT((ndo,",")); 1336 if (!rawprint(ndo, (caddr_t)q, d.spi_size)) 1337 goto trunc; 1338 q += d.spi_size; 1339 } 1340 return q; 1341trunc: 1342 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D))); 1343 return NULL; 1344} 1345 1346static const u_char * 1347ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, 1348 const struct isakmp_gen *ext, 1349 u_int item_len _U_, const u_char *ep _U_, 1350 u_int32_t phase _U_, u_int32_t doi _U_, 1351 u_int32_t proto _U_, int depth _U_) 1352{ 1353 struct isakmp_gen e; 1354 1355 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID))); 1356 1357 ND_TCHECK(*ext); 1358 safememcpy(&e, ext, sizeof(e)); 1359 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1360 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1361 ND_PRINT((ndo," ")); 1362 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1363 goto trunc; 1364 } 1365 return (u_char *)ext + ntohs(e.len); 1366trunc: 1367 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); 1368 return NULL; 1369} 1370 1371/************************************************************/ 1372/* */ 1373/* IKE v2 - rfc4306 - dissector */ 1374/* */ 1375/************************************************************/ 1376 1377static void 1378ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical) 1379{ 1380 ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : "")); 1381} 1382 1383static const u_char * 1384ikev2_gen_print(netdissect_options *ndo, u_char tpay, 1385 const struct isakmp_gen *ext) 1386{ 1387 struct isakmp_gen e; 1388 1389 ND_TCHECK(*ext); 1390 safememcpy(&e, ext, sizeof(e)); 1391 ikev2_pay_print(ndo, NPSTR(tpay), e.critical); 1392 1393 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1394 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1395 ND_PRINT((ndo," ")); 1396 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1397 goto trunc; 1398 } 1399 return (u_char *)ext + ntohs(e.len); 1400trunc: 1401 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1402 return NULL; 1403} 1404 1405static const u_char * 1406ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, 1407 const struct isakmp_gen *ext, u_int item_len, 1408 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, 1409 u_int32_t proto _U_, int depth _U_) 1410{ 1411 const struct ikev2_t *p; 1412 struct ikev2_t t; 1413 u_int16_t t_id; 1414 const u_char *cp; 1415 const char *idstr; 1416 const struct attrmap *map; 1417 size_t nmap; 1418 const u_char *ep2; 1419 1420 p = (struct ikev2_t *)ext; 1421 ND_TCHECK(*p); 1422 safememcpy(&t, ext, sizeof(t)); 1423 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical); 1424 1425 t_id = ntohs(t.t_id); 1426 1427 map = NULL; 1428 nmap = 0; 1429 1430 switch (t.t_type) { 1431 case IV2_T_ENCR: 1432 idstr = STR_OR_ID(t_id, esp_p_map); 1433 map = encr_t_map; 1434 nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]); 1435 break; 1436 1437 case IV2_T_PRF: 1438 idstr = STR_OR_ID(t_id, prf_p_map); 1439 break; 1440 1441 case IV2_T_INTEG: 1442 idstr = STR_OR_ID(t_id, integ_p_map); 1443 break; 1444 1445 case IV2_T_DH: 1446 idstr = STR_OR_ID(t_id, dh_p_map); 1447 break; 1448 1449 case IV2_T_ESN: 1450 idstr = STR_OR_ID(t_id, esn_p_map); 1451 break; 1452 1453 default: 1454 idstr = NULL; 1455 break; 1456 } 1457 1458 if (idstr) 1459 ND_PRINT((ndo," #%u type=%s id=%s ", pcount, 1460 STR_OR_ID(t.t_type, ikev2_t_type_map), 1461 idstr)); 1462 else 1463 ND_PRINT((ndo," #%u type=%s id=%u ", pcount, 1464 STR_OR_ID(t.t_type, ikev2_t_type_map), 1465 t.t_id)); 1466 cp = (u_char *)(p + 1); 1467 ep2 = (u_char *)p + item_len; 1468 while (cp < ep && cp < ep2) { 1469 if (map && nmap) { 1470 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, 1471 map, nmap); 1472 } else 1473 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); 1474 } 1475 if (ep < ep2) 1476 ND_PRINT((ndo,"...")); 1477 return cp; 1478trunc: 1479 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); 1480 return NULL; 1481} 1482 1483static const u_char * 1484ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, 1485 const struct isakmp_gen *ext, u_int item_len _U_, 1486 const u_char *ep, u_int32_t phase, u_int32_t doi0, 1487 u_int32_t proto0 _U_, int depth) 1488{ 1489 const struct ikev2_p *p; 1490 struct ikev2_p prop; 1491 const u_char *cp; 1492 1493 p = (struct ikev2_p *)ext; 1494 ND_TCHECK(*p); 1495 safememcpy(&prop, ext, sizeof(prop)); 1496 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); 1497 1498 ND_PRINT((ndo," #%u protoid=%s transform=%d", 1499 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); 1500 if (prop.spi_size) { 1501 ND_PRINT((ndo," spi=")); 1502 if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) 1503 goto trunc; 1504 } 1505 1506 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 1507 ND_TCHECK(*ext); 1508 1509 cp = ikev2_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 1510 prop.prot_id, depth); 1511 1512 return cp; 1513trunc: 1514 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); 1515 return NULL; 1516} 1517 1518static const u_char * 1519ikev2_sa_print(netdissect_options *ndo, u_char tpay, 1520 const struct isakmp_gen *ext1, 1521 u_int item_len _U_, const u_char *ep _U_, 1522 u_int32_t phase _U_, u_int32_t doi _U_, 1523 u_int32_t proto _U_, int depth _U_) 1524{ 1525 struct isakmp_gen e; 1526 int osa_len, sa_len; 1527 1528 ND_TCHECK(*ext1); 1529 safememcpy(&e, ext1, sizeof(e)); 1530 ikev2_pay_print(ndo, "sa", e.critical); 1531 1532 osa_len= ntohs(e.len); 1533 sa_len = osa_len - 4; 1534 ND_PRINT((ndo," len=%d", sa_len)); 1535 1536 ikev2_sub_print(ndo, ISAKMP_NPTYPE_P, 1537 ext1+1, ep, 1538 0, 0, 0, depth); 1539 1540 return (u_char *)ext1 + osa_len; 1541trunc: 1542 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1543 return NULL; 1544} 1545 1546static const u_char * 1547ikev2_ke_print(netdissect_options *ndo, u_char tpay, 1548 const struct isakmp_gen *ext, 1549 u_int item_len _U_, const u_char *ep _U_, 1550 u_int32_t phase _U_, u_int32_t doi _U_, 1551 u_int32_t proto _U_, int depth _U_) 1552{ 1553 struct ikev2_ke ke; 1554 struct ikev2_ke *k; 1555 1556 k = (struct ikev2_ke *)ext; 1557 ND_TCHECK(*ext); 1558 safememcpy(&ke, ext, sizeof(ke)); 1559 ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); 1560 1561 ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8, 1562 STR_OR_ID(ntohs(ke.ke_group), dh_p_map))); 1563 1564 if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { 1565 ND_PRINT((ndo," ")); 1566 if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8)) 1567 goto trunc; 1568 } 1569 return (u_char *)ext + ntohs(ke.h.len); 1570trunc: 1571 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1572 return NULL; 1573} 1574 1575static const u_char * 1576ikev2_ID_print(netdissect_options *ndo, u_char tpay, 1577 const struct isakmp_gen *ext, 1578 u_int item_len _U_, const u_char *ep _U_, 1579 u_int32_t phase _U_, u_int32_t doi _U_, 1580 u_int32_t proto _U_, int depth _U_) 1581{ 1582 return ikev2_gen_print(ndo, tpay, ext); 1583} 1584 1585static const u_char * 1586ikev2_cert_print(netdissect_options *ndo, u_char tpay, 1587 const struct isakmp_gen *ext, 1588 u_int item_len _U_, const u_char *ep _U_, 1589 u_int32_t phase _U_, u_int32_t doi _U_, 1590 u_int32_t proto _U_, int depth _U_) 1591{ 1592 return ikev2_gen_print(ndo, tpay, ext); 1593} 1594 1595static const u_char * 1596ikev2_cr_print(netdissect_options *ndo, u_char tpay, 1597 const struct isakmp_gen *ext, 1598 u_int item_len _U_, const u_char *ep _U_, 1599 u_int32_t phase _U_, u_int32_t doi _U_, 1600 u_int32_t proto _U_, int depth _U_) 1601{ 1602 return ikev2_gen_print(ndo, tpay, ext); 1603} 1604 1605static const u_char * 1606ikev2_auth_print(netdissect_options *ndo, u_char tpay, 1607 const struct isakmp_gen *ext, 1608 u_int item_len _U_, const u_char *ep _U_, 1609 u_int32_t phase _U_, u_int32_t doi _U_, 1610 u_int32_t proto _U_, int depth _U_) 1611{ 1612 struct ikev2_auth e; 1613 const char *v2_auth[]={ "invalid", "rsasig", 1614 "shared-secret", "dsssig" }; 1615 1616 ND_TCHECK(*ext); 1617 safememcpy(&e, ext, sizeof(e)); 1618 ikev2_pay_print(ndo, NPSTR(tpay), e.h.critical); 1619 1620 ND_PRINT((ndo," len=%d method=%s", ntohs(e.h.len) - 4, 1621 STR_OR_ID(e.auth_method, v2_auth))); 1622 1623 if (1 < ndo->ndo_vflag && 4 < ntohs(e.h.len)) { 1624 ND_PRINT((ndo," authdata=(")); 1625 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.h.len) - 4)) 1626 goto trunc; 1627 ND_PRINT((ndo,") ")); 1628 } else if(ndo->ndo_vflag && 4 < ntohs(e.h.len)) { 1629 if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; 1630 } 1631 1632 return (u_char *)ext + ntohs(e.h.len); 1633trunc: 1634 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1635 return NULL; 1636} 1637 1638static const u_char * 1639ikev2_nonce_print(netdissect_options *ndo, u_char tpay, 1640 const struct isakmp_gen *ext, 1641 u_int item_len _U_, const u_char *ep _U_, 1642 u_int32_t phase _U_, u_int32_t doi _U_, 1643 u_int32_t proto _U_, int depth _U_) 1644{ 1645 struct isakmp_gen e; 1646 1647 ND_TCHECK(*ext); 1648 safememcpy(&e, ext, sizeof(e)); 1649 ikev2_pay_print(ndo, "nonce", e.critical); 1650 1651 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1652 if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1653 ND_PRINT((ndo," nonce=(")); 1654 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1655 goto trunc; 1656 ND_PRINT((ndo,") ")); 1657 } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { 1658 if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; 1659 } 1660 1661 return (u_char *)ext + ntohs(e.len); 1662trunc: 1663 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1664 return NULL; 1665} 1666 1667/* notify payloads */ 1668static const u_char * 1669ikev2_n_print(netdissect_options *ndo, u_char tpay _U_, 1670 const struct isakmp_gen *ext, 1671 u_int item_len _U_, const u_char *ep _U_, 1672 u_int32_t phase _U_, u_int32_t doi _U_, 1673 u_int32_t proto _U_, int depth _U_) 1674{ 1675 struct ikev2_n *p, n; 1676 const u_char *cp; 1677 u_char *ep2; 1678 u_char showspi, showdata, showsomedata; 1679 const char *notify_name; 1680 u_int32_t type; 1681 1682 p = (struct ikev2_n *)ext; 1683 ND_TCHECK(*p); 1684 safememcpy(&n, ext, sizeof(n)); 1685 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); 1686 1687 showspi = 1; 1688 showdata = 0; 1689 showsomedata=0; 1690 notify_name=NULL; 1691 1692 ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id))); 1693 1694 type = ntohs(n.type); 1695 1696 /* notify space is annoying sparse */ 1697 switch(type) { 1698 case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD: 1699 notify_name = "unsupported_critical_payload"; 1700 showspi = 0; 1701 break; 1702 1703 case IV2_NOTIFY_INVALID_IKE_SPI: 1704 notify_name = "invalid_ike_spi"; 1705 showspi = 1; 1706 break; 1707 1708 case IV2_NOTIFY_INVALID_MAJOR_VERSION: 1709 notify_name = "invalid_major_version"; 1710 showspi = 0; 1711 break; 1712 1713 case IV2_NOTIFY_INVALID_SYNTAX: 1714 notify_name = "invalid_syntax"; 1715 showspi = 1; 1716 break; 1717 1718 case IV2_NOTIFY_INVALID_MESSAGE_ID: 1719 notify_name = "invalid_message_id"; 1720 showspi = 1; 1721 break; 1722 1723 case IV2_NOTIFY_INVALID_SPI: 1724 notify_name = "invalid_spi"; 1725 showspi = 1; 1726 break; 1727 1728 case IV2_NOTIFY_NO_PROPOSAL_CHOSEN: 1729 notify_name = "no_protocol_chosen"; 1730 showspi = 1; 1731 break; 1732 1733 case IV2_NOTIFY_INVALID_KE_PAYLOAD: 1734 notify_name = "invalid_ke_payload"; 1735 showspi = 1; 1736 break; 1737 1738 case IV2_NOTIFY_AUTHENTICATION_FAILED: 1739 notify_name = "authentication_failed"; 1740 showspi = 1; 1741 break; 1742 1743 case IV2_NOTIFY_SINGLE_PAIR_REQUIRED: 1744 notify_name = "single_pair_required"; 1745 showspi = 1; 1746 break; 1747 1748 case IV2_NOTIFY_NO_ADDITIONAL_SAS: 1749 notify_name = "no_additional_sas"; 1750 showspi = 0; 1751 break; 1752 1753 case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE: 1754 notify_name = "internal_address_failure"; 1755 showspi = 0; 1756 break; 1757 1758 case IV2_NOTIFY_FAILED_CP_REQUIRED: 1759 notify_name = "failed:cp_required"; 1760 showspi = 0; 1761 break; 1762 1763 case IV2_NOTIFY_INVALID_SELECTORS: 1764 notify_name = "invalid_selectors"; 1765 showspi = 0; 1766 break; 1767 1768 case IV2_NOTIFY_INITIAL_CONTACT: 1769 notify_name = "initial_contact"; 1770 showspi = 0; 1771 break; 1772 1773 case IV2_NOTIFY_SET_WINDOW_SIZE: 1774 notify_name = "set_window_size"; 1775 showspi = 0; 1776 break; 1777 1778 case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE: 1779 notify_name = "additional_ts_possible"; 1780 showspi = 0; 1781 break; 1782 1783 case IV2_NOTIFY_IPCOMP_SUPPORTED: 1784 notify_name = "ipcomp_supported"; 1785 showspi = 0; 1786 break; 1787 1788 case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP: 1789 notify_name = "nat_detection_source_ip"; 1790 showspi = 1; 1791 break; 1792 1793 case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP: 1794 notify_name = "nat_detection_destination_ip"; 1795 showspi = 1; 1796 break; 1797 1798 case IV2_NOTIFY_COOKIE: 1799 notify_name = "cookie"; 1800 showspi = 1; 1801 showsomedata= 1; 1802 showdata= 0; 1803 break; 1804 1805 case IV2_NOTIFY_USE_TRANSPORT_MODE: 1806 notify_name = "use_transport_mode"; 1807 showspi = 0; 1808 break; 1809 1810 case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED: 1811 notify_name = "http_cert_lookup_supported"; 1812 showspi = 0; 1813 break; 1814 1815 case IV2_NOTIFY_REKEY_SA: 1816 notify_name = "rekey_sa"; 1817 showspi = 1; 1818 break; 1819 1820 case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED: 1821 notify_name = "tfc_padding_not_supported"; 1822 showspi = 0; 1823 break; 1824 1825 case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO: 1826 notify_name = "non_first_fragment_also"; 1827 showspi = 0; 1828 break; 1829 1830 default: 1831 if (type < 8192) { 1832 notify_name="error"; 1833 } else if(type < 16384) { 1834 notify_name="private-error"; 1835 } else if(type < 40960) { 1836 notify_name="status"; 1837 } else { 1838 notify_name="private-status"; 1839 } 1840 } 1841 1842 if(notify_name) { 1843 ND_PRINT((ndo," type=%u(%s)", type, notify_name)); 1844 } 1845 1846 1847 if (showspi && n.spi_size) { 1848 ND_PRINT((ndo," spi=")); 1849 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1850 goto trunc; 1851 } 1852 1853 cp = (u_char *)(p + 1) + n.spi_size; 1854 ep2 = (u_char *)p + item_len; 1855 1856 if(3 < ndo->ndo_vflag) { 1857 showdata = 1; 1858 } 1859 1860 if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { 1861 ND_PRINT((ndo," data=(")); 1862 if (!rawprint(ndo, (caddr_t)(cp), ep - cp)) 1863 goto trunc; 1864 1865 ND_PRINT((ndo,")")); 1866 1867 } else if(showsomedata && cp < ep) { 1868 if(!ike_show_somedata(ndo, cp, ep)) goto trunc; 1869 } 1870 1871 return (u_char *)ext + item_len; 1872trunc: 1873 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); 1874 return NULL; 1875} 1876 1877static const u_char * 1878ikev2_d_print(netdissect_options *ndo, u_char tpay, 1879 const struct isakmp_gen *ext, 1880 u_int item_len _U_, const u_char *ep _U_, 1881 u_int32_t phase _U_, u_int32_t doi _U_, 1882 u_int32_t proto _U_, int depth _U_) 1883{ 1884 return ikev2_gen_print(ndo, tpay, ext); 1885} 1886 1887static const u_char * 1888ikev2_vid_print(netdissect_options *ndo, u_char tpay, 1889 const struct isakmp_gen *ext, 1890 u_int item_len _U_, const u_char *ep _U_, 1891 u_int32_t phase _U_, u_int32_t doi _U_, 1892 u_int32_t proto _U_, int depth _U_) 1893{ 1894 struct isakmp_gen e; 1895 const u_char *vid; 1896 int i, len; 1897 1898 ND_TCHECK(*ext); 1899 safememcpy(&e, ext, sizeof(e)); 1900 ikev2_pay_print(ndo, NPSTR(tpay), e.critical); 1901 ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4)); 1902 1903 vid = (const u_char *)(ext+1); 1904 len = ntohs(e.len) - 4; 1905 ND_TCHECK2(*vid, len); 1906 for(i=0; i<len; i++) { 1907 if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i])); 1908 else ND_PRINT((ndo, ".", vid[i])); 1909 } 1910 if (2 < ndo->ndo_vflag && 4 < len) { 1911 ND_PRINT((ndo," ")); 1912 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1913 goto trunc; 1914 } 1915 return (u_char *)ext + ntohs(e.len); 1916trunc: 1917 ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1918 return NULL; 1919} 1920 1921static const u_char * 1922ikev2_TS_print(netdissect_options *ndo, u_char tpay, 1923 const struct isakmp_gen *ext, 1924 u_int item_len _U_, const u_char *ep _U_, 1925 u_int32_t phase _U_, u_int32_t doi _U_, 1926 u_int32_t proto _U_, int depth _U_) 1927{ 1928 return ikev2_gen_print(ndo, tpay, ext); 1929} 1930 1931static const u_char * 1932ikev2_e_print(netdissect_options *ndo, u_char tpay, 1933 const struct isakmp_gen *ext, 1934 u_int item_len _U_, const u_char *ep _U_, 1935 u_int32_t phase _U_, u_int32_t doi _U_, 1936 u_int32_t proto _U_, int depth _U_) 1937{ 1938 return ikev2_gen_print(ndo, tpay, ext); 1939} 1940 1941static const u_char * 1942ikev2_cp_print(netdissect_options *ndo, u_char tpay, 1943 const struct isakmp_gen *ext, 1944 u_int item_len _U_, const u_char *ep _U_, 1945 u_int32_t phase _U_, u_int32_t doi _U_, 1946 u_int32_t proto _U_, int depth _U_) 1947{ 1948 return ikev2_gen_print(ndo, tpay, ext); 1949} 1950 1951static const u_char * 1952ikev2_eap_print(netdissect_options *ndo, u_char tpay, 1953 const struct isakmp_gen *ext, 1954 u_int item_len _U_, const u_char *ep _U_, 1955 u_int32_t phase _U_, u_int32_t doi _U_, 1956 u_int32_t proto _U_, int depth _U_) 1957{ 1958 return ikev2_gen_print(ndo, tpay, ext); 1959} 1960 1961static const u_char * 1962ike_sub0_print(netdissect_options *ndo, 1963 u_char np, const struct isakmp_gen *ext, const u_char *ep, 1964 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 1965{ 1966 const u_char *cp; 1967 struct isakmp_gen e; 1968 u_int item_len; 1969 1970 cp = (u_char *)ext; 1971 ND_TCHECK(*ext); 1972 safememcpy(&e, ext, sizeof(e)); 1973 1974 /* 1975 * Since we can't have a payload length of less than 4 bytes, 1976 * we need to bail out here if the generic header is nonsensical 1977 * or truncated, otherwise we could loop forever processing 1978 * zero-length items or otherwise misdissect the packet. 1979 */ 1980 item_len = ntohs(e.len); 1981 if (item_len <= 4) 1982 return NULL; 1983 1984 if (NPFUNC(np)) { 1985 /* 1986 * XXX - what if item_len is too short, or too long, 1987 * for this payload type? 1988 */ 1989 cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); 1990 } else { 1991 ND_PRINT((ndo,"%s", NPSTR(np))); 1992 cp += item_len; 1993 } 1994 1995 return cp; 1996trunc: 1997 ND_PRINT((ndo," [|isakmp]")); 1998 return NULL; 1999} 2000 2001static const u_char * 2002ikev1_sub_print(netdissect_options *ndo, 2003 u_char np, const struct isakmp_gen *ext, const u_char *ep, 2004 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2005{ 2006 const u_char *cp; 2007 int i; 2008 struct isakmp_gen e; 2009 2010 cp = (const u_char *)ext; 2011 2012 while (np) { 2013 ND_TCHECK(*ext); 2014 2015 safememcpy(&e, ext, sizeof(e)); 2016 2017 ND_TCHECK2(*ext, ntohs(e.len)); 2018 2019 depth++; 2020 ND_PRINT((ndo,"\n")); 2021 for (i = 0; i < depth; i++) 2022 ND_PRINT((ndo," ")); 2023 ND_PRINT((ndo,"(")); 2024 cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth); 2025 ND_PRINT((ndo,")")); 2026 depth--; 2027 2028 if (cp == NULL) { 2029 /* Zero-length subitem */ 2030 return NULL; 2031 } 2032 2033 np = e.np; 2034 ext = (struct isakmp_gen *)cp; 2035 } 2036 return cp; 2037trunc: 2038 ND_PRINT((ndo," [|%s]", NPSTR(np))); 2039 return NULL; 2040} 2041 2042static char * 2043numstr(int x) 2044{ 2045 static char buf[20]; 2046 snprintf(buf, sizeof(buf), "#%d", x); 2047 return buf; 2048} 2049 2050/* 2051 * some compiler tries to optimize memcpy(), using the alignment constraint 2052 * on the argument pointer type. by using this function, we try to avoid the 2053 * optimization. 2054 */ 2055static void 2056safememcpy(void *p, const void *q, size_t l) 2057{ 2058 memcpy(p, q, l); 2059} 2060 2061void 2062ikev1_print(netdissect_options *ndo, 2063 const u_char *bp, u_int length, 2064 const u_char *bp2, struct isakmp *base) 2065{ 2066 const struct isakmp *p; 2067 const u_char *ep; 2068 u_char np; 2069 int i; 2070 int phase; 2071 2072 p = (const struct isakmp *)bp; 2073 ep = ndo->ndo_snapend; 2074 2075 phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; 2076 if (phase == 1) 2077 ND_PRINT((ndo," phase %d", phase)); 2078 else 2079 ND_PRINT((ndo," phase %d/others", phase)); 2080 2081 i = cookie_find(&base->i_ck); 2082 if (i < 0) { 2083 if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { 2084 /* the first packet */ 2085 ND_PRINT((ndo," I")); 2086 if (bp2) 2087 cookie_record(&base->i_ck, bp2); 2088 } else 2089 ND_PRINT((ndo," ?")); 2090 } else { 2091 if (bp2 && cookie_isinitiator(i, bp2)) 2092 ND_PRINT((ndo," I")); 2093 else if (bp2 && cookie_isresponder(i, bp2)) 2094 ND_PRINT((ndo," R")); 2095 else 2096 ND_PRINT((ndo," ?")); 2097 } 2098 2099 ND_PRINT((ndo," %s", ETYPESTR(base->etype))); 2100 if (base->flags) { 2101 ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", 2102 base->flags & ISAKMP_FLAG_C ? "C" : "")); 2103 } 2104 2105 if (ndo->ndo_vflag) { 2106 const struct isakmp_gen *ext; 2107 int nparen; 2108 2109 ND_PRINT((ndo,":")); 2110 2111 /* regardless of phase... */ 2112 if (base->flags & ISAKMP_FLAG_E) { 2113 /* 2114 * encrypted, nothing we can do right now. 2115 * we hope to decrypt the packet in the future... 2116 */ 2117 ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np))); 2118 goto done; 2119 } 2120 2121 nparen = 0; 2122 CHECKLEN(p + 1, base->np); 2123 np = base->np; 2124 ext = (struct isakmp_gen *)(p + 1); 2125 ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); 2126 } 2127 2128done: 2129 if (ndo->ndo_vflag) { 2130 if (ntohl(base->len) != length) { 2131 ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)", 2132 (u_int32_t)ntohl(base->len), length)); 2133 } 2134 } 2135} 2136 2137static const u_char * 2138ikev2_sub0_print(netdissect_options *ndo, u_char np, int pcount, 2139 const struct isakmp_gen *ext, const u_char *ep, 2140 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2141{ 2142 const u_char *cp; 2143 struct isakmp_gen e; 2144 u_int item_len; 2145 2146 cp = (u_char *)ext; 2147 ND_TCHECK(*ext); 2148 safememcpy(&e, ext, sizeof(e)); 2149 2150 /* 2151 * Since we can't have a payload length of less than 4 bytes, 2152 * we need to bail out here if the generic header is nonsensical 2153 * or truncated, otherwise we could loop forever processing 2154 * zero-length items or otherwise misdissect the packet. 2155 */ 2156 item_len = ntohs(e.len); 2157 if (item_len <= 4) 2158 return NULL; 2159 2160 if(np == ISAKMP_NPTYPE_P) { 2161 cp = ikev2_p_print(ndo, np, pcount, ext, item_len, 2162 ep, phase, doi, proto, depth); 2163 } else if(np == ISAKMP_NPTYPE_T) { 2164 cp = ikev2_t_print(ndo, np, pcount, ext, item_len, 2165 ep, phase, doi, proto, depth); 2166 } else if (NPFUNC(np)) { 2167 /* 2168 * XXX - what if item_len is too short, or too long, 2169 * for this payload type? 2170 */ 2171 cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len, 2172 ep, phase, doi, proto, depth); 2173 } else { 2174 ND_PRINT((ndo,"%s", NPSTR(np))); 2175 cp += item_len; 2176 } 2177 2178 return cp; 2179trunc: 2180 ND_PRINT((ndo," [|isakmp]")); 2181 return NULL; 2182} 2183 2184static const u_char * 2185ikev2_sub_print(netdissect_options *ndo, 2186 u_char np, const struct isakmp_gen *ext, const u_char *ep, 2187 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2188{ 2189 const u_char *cp; 2190 int i; 2191 int pcount; 2192 struct isakmp_gen e; 2193 2194 cp = (const u_char *)ext; 2195 pcount = 0; 2196 while (np) { 2197 pcount++; 2198 ND_TCHECK(*ext); 2199 2200 safememcpy(&e, ext, sizeof(e)); 2201 2202 ND_TCHECK2(*ext, ntohs(e.len)); 2203 2204 depth++; 2205 ND_PRINT((ndo,"\n")); 2206 for (i = 0; i < depth; i++) 2207 ND_PRINT((ndo," ")); 2208 ND_PRINT((ndo,"(")); 2209 cp = ikev2_sub0_print(ndo, np, pcount, 2210 ext, ep, phase, doi, proto, depth); 2211 ND_PRINT((ndo,")")); 2212 depth--; 2213 2214 if (cp == NULL) { 2215 /* Zero-length subitem */ 2216 return NULL; 2217 } 2218 2219 np = e.np; 2220 ext = (struct isakmp_gen *)cp; 2221 } 2222 return cp; 2223trunc: 2224 ND_PRINT((ndo," [|%s]", NPSTR(np))); 2225 return NULL; 2226} 2227 2228static void 2229ikev2_print(netdissect_options *ndo, 2230 const u_char *bp, u_int length, 2231 const u_char *bp2 _U_, struct isakmp *base) 2232{ 2233 const struct isakmp *p; 2234 const u_char *ep; 2235 u_char np; 2236 int phase; 2237 2238 p = (const struct isakmp *)bp; 2239 ep = ndo->ndo_snapend; 2240 2241 phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; 2242 if (phase == 1) 2243 ND_PRINT((ndo, " parent_sa")); 2244 else 2245 ND_PRINT((ndo, " child_sa ")); 2246 2247 ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); 2248 if (base->flags) { 2249 ND_PRINT((ndo, "[%s%s]", 2250 base->flags & ISAKMP_FLAG_I ? "I" : "", 2251 base->flags & ISAKMP_FLAG_V ? "V" : "", 2252 base->flags & ISAKMP_FLAG_R ? "R" : "")); 2253 } 2254 2255 if (ndo->ndo_vflag) { 2256 const struct isakmp_gen *ext; 2257 int nparen; 2258 2259 ND_PRINT((ndo, ":")); 2260 2261 /* regardless of phase... */ 2262 if (base->flags & ISAKMP_FLAG_E) { 2263 /* 2264 * encrypted, nothing we can do right now. 2265 * we hope to decrypt the packet in the future... 2266 */ 2267 ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np))); 2268 goto done; 2269 } 2270 2271 nparen = 0; 2272 CHECKLEN(p + 1, base->np) 2273 2274 np = base->np; 2275 ext = (struct isakmp_gen *)(p + 1); 2276 ikev2_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); 2277 } 2278 2279done: 2280 if (ndo->ndo_vflag) { 2281 if (ntohl(base->len) != length) { 2282 ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)", 2283 (u_int32_t)ntohl(base->len), length)); 2284 } 2285 } 2286} 2287 2288void 2289isakmp_print(netdissect_options *ndo, 2290 const u_char *bp, u_int length, 2291 const u_char *bp2) 2292{ 2293 const struct isakmp *p; 2294 struct isakmp base; 2295 const u_char *ep; 2296 int major, minor; 2297 2298 p = (const struct isakmp *)bp; 2299 ep = ndo->ndo_snapend; 2300 2301 if ((struct isakmp *)ep < p + 1) { 2302 ND_PRINT((ndo,"[|isakmp]")); 2303 return; 2304 } 2305 2306 safememcpy(&base, p, sizeof(base)); 2307 2308 ND_PRINT((ndo,"isakmp")); 2309 major = (base.vers & ISAKMP_VERS_MAJOR) 2310 >> ISAKMP_VERS_MAJOR_SHIFT; 2311 minor = (base.vers & ISAKMP_VERS_MINOR) 2312 >> ISAKMP_VERS_MINOR_SHIFT; 2313 2314 if (ndo->ndo_vflag) { 2315 ND_PRINT((ndo," %d.%d", major, minor)); 2316 } 2317 2318 if (ndo->ndo_vflag) { 2319 ND_PRINT((ndo," msgid ")); 2320 rawprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); 2321 } 2322 2323 if (1 < ndo->ndo_vflag) { 2324 ND_PRINT((ndo," cookie ")); 2325 rawprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); 2326 ND_PRINT((ndo,"->")); 2327 rawprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); 2328 } 2329 ND_PRINT((ndo,":")); 2330 2331 switch(major) { 2332 case IKEv1_MAJOR_VERSION: 2333 ikev1_print(ndo, bp, length, bp2, &base); 2334 break; 2335 2336 case IKEv2_MAJOR_VERSION: 2337 ikev2_print(ndo, bp, length, bp2, &base); 2338 break; 2339 } 2340} 2341 2342void 2343isakmp_rfc3948_print(netdissect_options *ndo, 2344 const u_char *bp, u_int length, 2345 const u_char *bp2) 2346{ 2347 const u_char *ep; 2348 ep = ndo->ndo_snapend; 2349 2350 if(length == 1 && bp[0]==0xff) { 2351 ND_PRINT((ndo, "isakmp-nat-keep-alive")); 2352 return; 2353 } 2354 2355 if(length < 4) { 2356 goto trunc; 2357 } 2358 2359 /* 2360 * see if this is an IKE packet 2361 */ 2362 if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { 2363 ND_PRINT((ndo, "NONESP-encap: ")); 2364 isakmp_print(ndo, bp+4, length-4, bp2); 2365 return; 2366 } 2367 2368 /* must be an ESP packet */ 2369 { 2370 int nh, enh, padlen; 2371 int advance; 2372 2373 ND_PRINT((ndo, "UDP-encap: ")); 2374 2375 advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); 2376 if(advance <= 0) 2377 return; 2378 2379 bp += advance; 2380 length -= advance + padlen; 2381 nh = enh & 0xff; 2382 2383 ip_print_inner(ndo, bp, length, nh, bp2); 2384 return; 2385 } 2386 2387trunc: 2388 ND_PRINT((ndo,"[|isakmp]")); 2389 return; 2390} 2391 2392/* 2393 * Local Variables: 2394 * c-style: whitesmith 2395 * c-basic-offset: 8 2396 * End: 2397 */ 2398 2399 2400 2401 2402