1 /* $OpenBSD: print-ike.c,v 1.17 2004/01/15 22:59:42 ho Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 5 * The Regents of the University of California. All rights reserved. 6 * Copyright (c) 2001 H�kan Olsson. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that: (1) source code distributions 10 * retain the above copyright notice and this paragraph in its entirety, (2) 11 * distributions including binary code include the above copyright notice and 12 * this paragraph in its entirety in the documentation or other materials 13 * provided with the distribution, and (3) all advertising materials mentioning 14 * features or use of this software display the following acknowledgement: 15 * ``This product includes software developed by the University of California, 16 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 17 * the University nor the names of its contributors may be used to endorse 18 * or promote products derived from this software without specific prior 19 * written permission. 20 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 21 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 22 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 23 * 24 * Format and print ike (isakmp) packets. 25 * By Tero Kivinen <kivinen@ssh.fi>, Tero Mononen <tmo@ssh.fi>, 26 * Tatu Ylonen <ylo@ssh.fi> and Timo J. Rinne <tri@ssh.fi> 27 * in co-operation with SSH Communications Security, Espoo, Finland 28 */ 29 30 #ifndef lint 31 static const char rcsid[] = 32 "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-ike.c,v 1.17 2004/01/15 22:59:42 ho Exp $ (XXX)"; 33 #endif 34 35 #include <sys/param.h> 36 #include <sys/time.h> 37 #include <sys/socket.h> 38 39 struct mbuf; 40 struct rtentry; 41 #include <net/if.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 44 45 #include <ctype.h> 46 #include <stdio.h> 47 #include <string.h> 48 49 #include "interface.h" 50 #include "addrtoname.h" 51 #include "ike.h" 52 53 struct isakmp_header { 54 u_char init_cookie[8]; 55 u_char resp_cookie[8]; 56 u_char nextpayload; 57 u_char version; 58 u_char exgtype; 59 u_char flags; 60 u_char msgid[4]; 61 u_int32_t length; 62 u_char payloads[0]; 63 }; 64 65 struct notification_payload { 66 u_char next_payload; 67 u_char reserved; 68 u_int16_t payload_length; 69 u_int32_t doi; 70 u_char protocol_id; 71 u_char spi_size; 72 u_int16_t type; 73 u_char data[0]; 74 }; 75 76 static void ike_pl_print(u_char, u_char *, u_char); 77 78 int ike_tab_level = 0; 79 u_char xform_proto; 80 81 static const char *ike[] = IKE_PROTO_INITIALIZER; 82 83 #define SMALL_TABS 4 84 #define SPACES " " 85 const char * 86 ike_tab_offset(void) 87 { 88 const char *p, *endline; 89 static const char line[] = SPACES; 90 91 endline = line + sizeof line - 1; 92 p = endline - SMALL_TABS * (ike_tab_level); 93 94 return (p > line ? p : line); 95 } 96 97 static char * 98 ike_get_cookie (u_char *ic, u_char *rc) 99 { 100 static char cookie_jar[35]; 101 int i; 102 103 for (i = 0; i < 8; i++) 104 snprintf(cookie_jar + i*2, sizeof(cookie_jar) - i*2, 105 "%02x", *(ic + i)); 106 strlcat(cookie_jar, "->", sizeof(cookie_jar)); 107 for (i = 0; i < 8; i++) 108 snprintf(cookie_jar + 18 + i*2, sizeof(cookie_jar) - 18 - i*2, 109 "%02x", *(rc + i)); 110 return cookie_jar; 111 } 112 113 /* 114 * Print isakmp requests 115 */ 116 void 117 ike_print (const u_char *cp, u_int length) 118 { 119 struct isakmp_header *ih; 120 const u_char *ep; 121 u_char *payload; 122 u_char nextpayload; 123 int encrypted; 124 static const char *exgtypes[] = IKE_EXCHANGE_TYPES_INITIALIZER; 125 126 encrypted = 0; 127 128 #ifdef TCHECK 129 #undef TCHECK 130 #endif 131 #define TCHECK(var, l) if ((u_char *)&(var) > ep - l) goto trunc 132 133 ih = (struct isakmp_header *)cp; 134 135 if (length < sizeof (struct isakmp_header)) 136 goto trunc; 137 138 /* 'ep' points to the end of avaible data. */ 139 ep = snapend; 140 141 printf(" isakmp"); 142 143 printf(" v%d.%d", ih->version >> 4, ih->version & 0xf); 144 145 printf(" exchange "); 146 if (ih->exgtype < (sizeof exgtypes/sizeof exgtypes[0])) 147 printf("%s", exgtypes[ih->exgtype]); 148 else 149 printf("%d (unknown)", ih->exgtype); 150 151 if (ih->flags & FLAGS_ENCRYPTION) { 152 printf(" encrypted"); 153 encrypted = 1; 154 } 155 156 if (ih->flags & FLAGS_COMMIT) { 157 printf(" commit"); 158 } 159 160 printf("\n\tcookie: %s", ike_get_cookie (ih->init_cookie, 161 ih->resp_cookie)); 162 163 TCHECK(ih->msgid, sizeof(ih->msgid)); 164 printf(" msgid: %02x%02x%02x%02x", ih->msgid[0], ih->msgid[1], 165 ih->msgid[2], ih->msgid[3]); 166 167 TCHECK(ih->length, sizeof(ih->length)); 168 printf(" len: %d", ntohl(ih->length)); 169 170 if (ih->version > 16) { 171 printf(" new version"); 172 return; 173 } 174 175 payload = ih->payloads; 176 nextpayload = ih->nextpayload; 177 178 /* if encrypted, then open special file for encryption keys */ 179 if (encrypted) { 180 /* decrypt XXX */ 181 return; 182 } 183 184 /* if verbose, print payload data */ 185 if (vflag) 186 ike_pl_print(nextpayload, payload, ISAKMP_DOI); 187 188 return; 189 190 trunc: 191 fputs(" [|isakmp]", stdout); 192 } 193 194 void 195 ike_pl_sa_print (u_char *buf, int len) 196 { 197 u_int32_t situation = ntohl(*(u_int32_t *)(buf + 4)); 198 u_char ike_doi = ntohl((*(u_int32_t *)buf)); 199 printf(" DOI: %d", ike_doi); 200 if (ike_doi == IPSEC_DOI) { 201 printf("(IPSEC) situation: "); 202 if (situation & IKE_SITUATION_IDENTITY_ONLY) 203 printf("IDENTITY_ONLY "); 204 if (situation & IKE_SITUATION_SECRECY) 205 printf("SECRECY "); 206 if (situation & IKE_SITUATION_INTEGRITY) 207 printf("INTEGRITY "); 208 if ((situation & IKE_SITUATION_MASK) == 0) 209 printf("0x%x (unknown)", situation); 210 ike_pl_print (PAYLOAD_PROPOSAL, buf + 8, IPSEC_DOI); 211 } else 212 printf(" situation: (unknown)"); 213 } 214 215 int 216 ike_attribute_print (u_char *buf, u_char doi, int maxlen) 217 { 218 static char *attrs[] = IKE_ATTR_INITIALIZER; 219 static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER; 220 static char *attr_hash[] = IKE_ATTR_HASH_INITIALIZER; 221 static char *attr_auth[] = IKE_ATTR_AUTH_INITIALIZER; 222 static char *attr_gdesc[] = IKE_ATTR_GROUP_DESC_INITIALIZER; 223 static char *attr_gtype[] = IKE_ATTR_GROUP_INITIALIZER; 224 static char *attr_ltype[] = IKE_ATTR_SA_DURATION_INITIALIZER; 225 static char *ipsec_attrs[] = IPSEC_ATTR_INITIALIZER; 226 static char *ipsec_attr_encap[] = IPSEC_ATTR_ENCAP_INITIALIZER; 227 static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER; 228 static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER; 229 230 u_char af = buf[0] >> 7; 231 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 232 u_int16_t len = buf[2] << 8 | buf[3], val; 233 234 if (doi == ISAKMP_DOI) 235 printf("\n\t%sattribute %s = ", ike_tab_offset(), 236 (type < sizeof attrs / sizeof attrs[0] ? 237 attrs[type] : "<unknown>")); 238 else 239 printf("\n\t%sattribute %s = ", ike_tab_offset(), 240 (type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? 241 ipsec_attrs[type] : "<unknown>")); 242 243 if ((af == 1 && maxlen < 4) || (af == 0 && maxlen < (len + 4))) { 244 printf("\n\t%s[|attr]", ike_tab_offset()); 245 return maxlen; 246 } 247 248 if (af == 0) { 249 /* AF=0; print the variable length attribute value */ 250 for (val = 0; val < len; val++) 251 printf("%02x", (char)*(buf + 4 + val)); 252 return len + 4; 253 } 254 255 val = len; /* For AF=1, this field is the "VALUE" */ 256 len = 4; /* and with AF=1, length is always 4 */ 257 258 #define CASE_PRINT(TYPE, var) \ 259 case TYPE : \ 260 if (val < sizeof var / sizeof var [0]) \ 261 printf("%s", var [val]); \ 262 else \ 263 printf("%d (unknown)", val); \ 264 break; 265 266 if (doi == ISAKMP_DOI) 267 switch(type) { 268 CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc); 269 CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash); 270 CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth); 271 CASE_PRINT(IKE_ATTR_GROUP_DESC, attr_gdesc); 272 CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype); 273 CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype); 274 default: 275 printf("%d", val); 276 } 277 else 278 switch(type) { 279 CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype); 280 CASE_PRINT(IPSEC_ATTR_ENCAPSULATION_MODE, 281 ipsec_attr_encap); 282 CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM, 283 ipsec_attr_auth); 284 default: 285 printf("%d", val); 286 } 287 288 #undef CASE_PRINT 289 return len; 290 } 291 292 void 293 ike_pl_transform_print (u_char *buf, int len, u_char doi) 294 { 295 const char *ah[] = IPSEC_AH_INITIALIZER; 296 const char *esp[] = IPSEC_ESP_INITIALIZER; 297 const char *ipcomp[] = IPCOMP_INITIALIZER; 298 u_char *attr = buf + 4; 299 300 printf("\n\t%stransform: %u ID: ", ike_tab_offset(), buf[0]); 301 302 switch (doi) { 303 case ISAKMP_DOI: 304 if (buf[1] < (sizeof ike / sizeof ike[0])) 305 printf("%s", ike[buf[1]]); 306 else 307 printf("%d(unknown)", buf[1]); 308 break; 309 310 default: /* IPSEC_DOI */ 311 switch (xform_proto) { /* from ike_proposal_print */ 312 case PROTO_IPSEC_AH: 313 if (buf[1] < (sizeof ah / sizeof ah[0])) 314 printf("%s", ah[buf[1]]); 315 else 316 printf("%d(unknown)", buf[1]); 317 break; 318 case PROTO_IPSEC_ESP: 319 if (buf[1] < (sizeof esp / sizeof esp[0])) 320 printf("%s", esp[buf[1]]); 321 else 322 printf("%d(unknown)", buf[1]); 323 break; 324 case PROTO_IPCOMP: 325 if (buf[1] < (sizeof ipcomp / sizeof ipcomp[0])) 326 printf("%s", ipcomp[buf[1]]); 327 else 328 printf("%d(unknown)", buf[1]); 329 break; 330 default: 331 printf("%d(unknown)", buf[1]); 332 } 333 break; 334 } 335 336 ike_tab_level++; 337 while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ 338 attr += ike_attribute_print(attr, doi, len - (attr-buf)); 339 ike_tab_level--; 340 } 341 342 void 343 ike_pl_proposal_print (u_char *buf, int len, u_char doi) 344 { 345 u_int8_t i, p_id = buf[1], spisz = buf[2]; 346 347 printf(" proposal: %d proto: %s spisz: %d xforms: %d", 348 buf[0], (p_id < (sizeof ike / sizeof ike[0]) ? ike[p_id] : 349 "(unknown)"), spisz, buf[3]); 350 351 /* We need to store this for upcoming ike_attribute_print call. */ 352 xform_proto = p_id; 353 354 if (spisz) { 355 if (p_id == PROTO_IPCOMP) 356 printf(" CPI: 0x"); 357 else 358 printf(" SPI: 0x"); 359 for (i = 0; i < spisz && (i + 4) < len; i++) 360 printf("%02x", buf[i + 4]); 361 doi = IPSEC_DOI; 362 } else 363 doi = ISAKMP_DOI; 364 365 if ((char)buf[3] > 0) 366 ike_pl_print(PAYLOAD_TRANSFORM, buf + 4 + buf[2], doi); 367 } 368 369 void 370 ike_pl_ke_print (u_char *buf, int len, u_char doi) 371 { 372 if (doi != IPSEC_DOI) 373 return; 374 375 /* XXX ... */ 376 } 377 378 void 379 ipsec_id_print (u_char *buf, int len, u_char doi) 380 { 381 static const char *idtypes[] = IPSEC_ID_TYPE_INITIALIZER; 382 char ntop_buf[INET6_ADDRSTRLEN]; 383 struct in_addr in; 384 u_char *p; 385 386 if (doi != ISAKMP_DOI) 387 return; 388 389 /* Don't print proto+port unless actually used */ 390 if (buf[1] | buf[2] | buf[3]) 391 printf(" proto: %d port: %d", buf[1], (buf[2] << 8) + buf[3]); 392 393 printf(" type: %s = ", buf[0] < (sizeof idtypes/sizeof idtypes[0]) ? 394 idtypes[buf[0]] : "<unknown>"); 395 396 switch (buf[0]) { 397 case IPSEC_ID_IPV4_ADDR: 398 memcpy (&in.s_addr, buf + 4, sizeof in); 399 printf("%s", inet_ntoa (in)); 400 break; 401 case IPSEC_ID_IPV4_ADDR_SUBNET: 402 case IPSEC_ID_IPV4_ADDR_RANGE: 403 memcpy (&in.s_addr, buf + 4, sizeof in); 404 printf("%s%s", inet_ntoa (in), 405 buf[0] == IPSEC_ID_IPV4_ADDR_SUBNET ? "/" : "-"); 406 memcpy (&in.s_addr, buf + 8, sizeof in); 407 printf("%s", inet_ntoa (in)); 408 break; 409 410 case IPSEC_ID_IPV6_ADDR: 411 printf("%s", inet_ntop (AF_INET6, buf + 4, ntop_buf, 412 sizeof ntop_buf)); 413 break; 414 case IPSEC_ID_IPV6_ADDR_SUBNET: 415 case IPSEC_ID_IPV6_ADDR_RANGE: 416 printf("%s%s", inet_ntop (AF_INET6, buf + 4, ntop_buf, 417 sizeof ntop_buf), 418 buf[0] == IPSEC_ID_IPV6_ADDR_SUBNET ? "/" : "-"); 419 printf("%s", inet_ntop (AF_INET6, buf + 4 + sizeof ntop_buf, 420 ntop_buf, sizeof ntop_buf)); 421 422 case IPSEC_ID_FQDN: 423 case IPSEC_ID_USER_FQDN: 424 printf("\""); 425 for(p = buf + 4; (int)(p - buf) < len - 4; p++) 426 printf("%c",(isprint(*p) ? *p : '.')); 427 printf("\""); 428 break; 429 430 case IPSEC_ID_DER_ASN1_DN: 431 case IPSEC_ID_DER_ASN1_GN: 432 case IPSEC_ID_KEY_ID: 433 default: 434 printf("\"(not shown)\""); 435 break; 436 } 437 } 438 439 void 440 ike_pl_notification_print (u_char *buf, int len) 441 { 442 static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER; 443 struct notification_payload *np = (struct notification_payload *)buf; 444 u_int32_t *replay; 445 u_char *attr; 446 447 if (len < sizeof (struct notification_payload)) { 448 printf(" (|len)"); 449 return; 450 } 451 452 np->doi = ntohl (np->doi); 453 np->type = ntohs (np->type); 454 455 if (np->doi != ISAKMP_DOI && np->doi != IPSEC_DOI) { 456 printf(" (unknown DOI)"); 457 return; 458 } 459 460 printf("\n\t%snotification: ", ike_tab_offset()); 461 462 if (np->type > 0 && np->type < (sizeof nftypes / sizeof nftypes[0])) { 463 printf("%s", nftypes[np->type]); 464 return; 465 } 466 switch (np->type) { 467 468 case NOTIFY_IPSEC_RESPONDER_LIFETIME: 469 printf("RESPONDER LIFETIME"); 470 if (np->spi_size == 16) 471 printf("(%s)", ike_get_cookie (&np->data[0], 472 &np->data[8])); 473 else 474 printf("SPI: 0x%08x", np->data[0]<<24 | 475 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 476 attr = &np->data[np->spi_size]; 477 ike_tab_level++; 478 while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ 479 attr += ike_attribute_print(attr, IPSEC_DOI, 480 len - (attr-buf)); 481 ike_tab_level--; 482 break; 483 484 case NOTIFY_IPSEC_REPLAY_STATUS: 485 replay = (u_int32_t *)&np->data[np->spi_size]; 486 printf("REPLAY STATUS [%sabled] ", *replay ? "en" : "dis"); 487 if (np->spi_size == 16) 488 printf("(%s)", ike_get_cookie (&np->data[0], 489 &np->data[8])); 490 else 491 printf("SPI: 0x%08x", np->data[0]<<24 | 492 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 493 break; 494 495 case NOTIFY_IPSEC_INITIAL_CONTACT: 496 printf("INITIAL CONTACT (%s)", ike_get_cookie (&np->data[0], 497 &np->data[8])); 498 break; 499 500 default: 501 printf("%d (unknown)", np->type); 502 break; 503 } 504 } 505 506 void 507 ike_pl_vendor_print (u_char *buf, int len, u_char doi) 508 { 509 u_char *p = buf; 510 511 if (doi != IPSEC_DOI) 512 return; 513 514 printf(" \""); 515 for (p = buf; (int)(p - buf) < len; p++) 516 printf("%c",(isprint(*p) ? *p : '.')); 517 printf("\""); 518 } 519 520 /* IKE mode-config. */ 521 int 522 ike_cfg_attribute_print (u_char *buf, int attr_type, int maxlen) 523 { 524 static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER; 525 char ntop_buf[INET6_ADDRSTRLEN]; 526 struct in_addr in; 527 528 u_char af = buf[0] >> 7; 529 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 530 u_int16_t len = af ? 2 : buf[2] << 8 | buf[3], p; 531 u_char *val = af ? buf + 2 : buf + 4; 532 533 printf("\n\t\%sattribute %s = ", ike_tab_offset(), 534 type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] : 535 "<unknown>"); 536 537 if ((af == 1 && maxlen < 4) || 538 (af == 0 && maxlen < (len + 4))) { 539 printf("\n\t%s[|attr]", ike_tab_offset()); 540 return maxlen; 541 } 542 543 /* XXX The 2nd term is for bug compatibility with PGPnet. */ 544 if (len == 0 || (af && !val[0] && !val[1])) { 545 printf("<none>"); 546 return 4; 547 } 548 549 /* XXX Generally lengths are not checked well below. */ 550 switch (type) { 551 case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS: 552 case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK: 553 case IKE_CFG_ATTR_INTERNAL_IP4_DNS: 554 case IKE_CFG_ATTR_INTERNAL_IP4_NBNS: 555 case IKE_CFG_ATTR_INTERNAL_IP4_DHCP: 556 memcpy (&in.s_addr, val, sizeof in); 557 printf("%s", inet_ntoa (in)); 558 break; 559 560 case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS: 561 case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK: 562 case IKE_CFG_ATTR_INTERNAL_IP6_DNS: 563 case IKE_CFG_ATTR_INTERNAL_IP6_NBNS: 564 case IKE_CFG_ATTR_INTERNAL_IP6_DHCP: 565 printf("%s", inet_ntop (AF_INET6, val, ntop_buf, 566 sizeof ntop_buf)); 567 break; 568 569 case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET: 570 memcpy(&in.s_addr, val, sizeof in); 571 printf("%s/", inet_ntoa (in)); 572 memcpy(&in.s_addr, val + sizeof in, sizeof in); 573 printf("%s", inet_ntoa (in)); 574 break; 575 576 case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET: 577 printf("%s/%u", inet_ntop (AF_INET6, val, ntop_buf, 578 sizeof ntop_buf), val[16]); 579 break; 580 581 case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY: 582 printf("%u seconds", 583 val[0] << 24 | val[1] << 16 | val[2] << 8 | val[3]); 584 break; 585 586 case IKE_CFG_ATTR_APPLICATION_VERSION: 587 for (p = 0; p < len; p++) 588 printf("%c", isprint(val[p]) ? val[p] : '.'); 589 break; 590 591 case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES: 592 printf("<%d attributes>", len / 2); 593 ike_tab_level++; 594 for (p = 0; p < len; p += 2) { 595 type = (val[p] << 8 | val[p + 1]) & 0x7fff; 596 printf("\n\t%s%s", ike_tab_offset(), 597 type < (sizeof attrs/sizeof attrs[0]) ? 598 attrs[type] : "<unknown>"); 599 } 600 ike_tab_level--; 601 break; 602 603 default: 604 break; 605 } 606 return af ? 4 : len + 4; 607 } 608 609 void 610 ike_pl_attribute_print (u_char *buf, int len) 611 { 612 static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER; 613 u_char type, *attr; 614 u_int16_t id; 615 616 type = buf[0]; 617 id = buf[2]<<8 | buf[3]; 618 attr = buf + 4; 619 620 printf(" type: %s Id: %d", 621 type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[type] : 622 "<unknown>", id); 623 624 while ((int)(attr - buf) < len - 4) 625 attr += ike_cfg_attribute_print(attr, type, len - (attr-buf)); 626 } 627 628 void 629 ike_pl_print (u_char type, u_char *buf, u_char doi) 630 { 631 static const char *pltypes[] = IKE_PAYLOAD_TYPES_INITIALIZER; 632 int next_type = buf[0]; 633 int this_len = buf[2]<<8 | buf[3]; 634 635 printf("\n\t%spayload: %s len: %d", ike_tab_offset(), 636 (type < (sizeof pltypes/sizeof pltypes[0]) ? 637 pltypes[type] : "<unknown>"), this_len); 638 639 if ((u_char *)&(buf[0]) > snapend - this_len) 640 goto pltrunc; 641 642 ike_tab_level++; 643 switch (type) { 644 case PAYLOAD_NONE: 645 return; 646 647 case PAYLOAD_SA: 648 ike_pl_sa_print(buf+4, this_len); 649 break; 650 651 case PAYLOAD_PROPOSAL: 652 ike_pl_proposal_print(buf+4, this_len, doi); 653 break; 654 655 case PAYLOAD_TRANSFORM: 656 ike_pl_transform_print(buf+4, this_len, doi); 657 break; 658 659 case PAYLOAD_KE: 660 ike_pl_ke_print(buf+4, this_len, doi); 661 break; 662 663 case PAYLOAD_ID: 664 /* Should only happen with IPsec DOI */ 665 ipsec_id_print(buf+4, this_len, doi); 666 break; 667 668 case PAYLOAD_CERT: 669 case PAYLOAD_CERTREQUEST: 670 case PAYLOAD_HASH: 671 case PAYLOAD_SIG: 672 case PAYLOAD_NONCE: 673 case PAYLOAD_DELETE: 674 break; 675 676 case PAYLOAD_NOTIFICATION: 677 ike_pl_notification_print(buf, this_len); 678 break; 679 680 case PAYLOAD_VENDOR: 681 ike_pl_vendor_print(buf+4, this_len, doi); 682 break; 683 684 case PAYLOAD_ATTRIBUTE: 685 ike_pl_attribute_print(buf+4, this_len); 686 break; 687 688 case PAYLOAD_NAT_D: 689 case PAYLOAD_NAT_OA: 690 break; 691 692 default: 693 break; 694 } 695 ike_tab_level--; 696 697 if (next_type) /* Recurse over next payload */ 698 ike_pl_print(next_type, buf + this_len, doi); 699 700 return; 701 702 pltrunc: 703 if (doi == ISAKMP_DOI) 704 fputs(" [|isakmp]", stdout); 705 else 706 fputs(" [|ipsec]", stdout); 707 } 708