1 /* $OpenBSD: print-ike.c,v 1.15 2002/09/23 04:10:14 millert 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.15 2002/09/23 04:10:14 millert 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 /* Note funny sized packets */ 135 136 if (length < 20) 137 (void)printf(" [len=%d]", length); 138 139 /* 'ep' points to the end of avaible data. */ 140 ep = snapend; 141 142 printf(" isakmp"); 143 144 printf(" v%d.%d", ih->version >> 4, ih->version & 0xf); 145 146 printf(" exchange "); 147 if (ih->exgtype < (sizeof exgtypes/sizeof exgtypes[0])) 148 printf("%s", exgtypes[ih->exgtype]); 149 else 150 printf("%d (unknown)", ih->exgtype); 151 152 if (ih->flags & FLAGS_ENCRYPTION) { 153 printf(" encrypted"); 154 encrypted = 1; 155 } 156 157 if (ih->flags & FLAGS_COMMIT) { 158 printf(" commit"); 159 } 160 161 printf("\n\tcookie: %s", ike_get_cookie (ih->init_cookie, 162 ih->resp_cookie)); 163 164 TCHECK(ih->msgid, sizeof(ih->msgid)); 165 printf(" msgid: %02x%02x%02x%02x", ih->msgid[0], ih->msgid[1], 166 ih->msgid[2], ih->msgid[3]); 167 168 TCHECK(ih->length, sizeof(ih->length)); 169 printf(" len: %d", ntohl(ih->length)); 170 171 if (ih->version > 16) { 172 printf(" new version"); 173 return; 174 } 175 176 payload = ih->payloads; 177 nextpayload = ih->nextpayload; 178 179 /* if encrypted, then open special file for encryption keys */ 180 if (encrypted) { 181 /* decrypt XXX */ 182 return; 183 } 184 185 /* if verbose, print payload data */ 186 if (vflag) 187 ike_pl_print(nextpayload, payload, ISAKMP_DOI); 188 189 return; 190 191 trunc: 192 fputs(" [|isakmp]", stdout); 193 } 194 195 void 196 ike_pl_sa_print (u_char *buf, int len) 197 { 198 u_int32_t situation = ntohl(*(u_int32_t *)(buf + 4)); 199 u_char ike_doi = ntohl((*(u_int32_t *)buf)); 200 printf(" DOI: %d", ike_doi); 201 if (ike_doi == IPSEC_DOI) { 202 printf("(IPSEC) situation: "); 203 if (situation & IKE_SITUATION_IDENTITY_ONLY) 204 printf("IDENTITY_ONLY "); 205 if (situation & IKE_SITUATION_SECRECY) 206 printf("SECRECY "); 207 if (situation & IKE_SITUATION_INTEGRITY) 208 printf("INTEGRITY "); 209 if ((situation & IKE_SITUATION_MASK) == 0) 210 printf("0x%x (unknown)", situation); 211 ike_pl_print (PAYLOAD_PROPOSAL, buf + 8, IPSEC_DOI); 212 } else 213 printf(" situation: (unknown)"); 214 } 215 216 int 217 ike_attribute_print (u_char *buf, u_char doi, int maxlen) 218 { 219 static char *attrs[] = IKE_ATTR_INITIALIZER; 220 static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER; 221 static char *attr_hash[] = IKE_ATTR_HASH_INITIALIZER; 222 static char *attr_auth[] = IKE_ATTR_AUTH_INITIALIZER; 223 static char *attr_gdesc[] = IKE_ATTR_GROUP_DESC_INITIALIZER; 224 static char *attr_gtype[] = IKE_ATTR_GROUP_INITIALIZER; 225 static char *attr_ltype[] = IKE_ATTR_SA_DURATION_INITIALIZER; 226 static char *ipsec_attrs[] = IPSEC_ATTR_INITIALIZER; 227 static char *ipsec_attr_encap[] = IPSEC_ATTR_ENCAP_INITIALIZER; 228 static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER; 229 static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER; 230 231 u_char af = buf[0] >> 7; 232 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 233 u_int16_t len = buf[2] << 8 | buf[3], val; 234 235 if (doi == ISAKMP_DOI) 236 printf("\n\t%sattribute %s = ", ike_tab_offset(), 237 (type < sizeof attrs / sizeof attrs[0] ? 238 attrs[type] : "<unknown>")); 239 else 240 printf("\n\t%sattribute %s = ", ike_tab_offset(), 241 (type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? 242 ipsec_attrs[type] : "<unknown>")); 243 244 if ((af == 1 && maxlen < 4) || (af == 0 && maxlen < (len + 4))) { 245 printf("\n\t%s[|attr]", ike_tab_offset()); 246 return maxlen; 247 } 248 249 if (af == 0) { 250 /* AF=0; print the variable length attribute value */ 251 for (val = 0; val < len; val++) 252 printf("%02x", (char)*(buf + 4 + val)); 253 return len + 4; 254 } 255 256 val = len; /* For AF=1, this field is the "VALUE" */ 257 len = 4; /* and with AF=1, length is always 4 */ 258 259 #define CASE_PRINT(TYPE, var) \ 260 case TYPE : \ 261 if (val < sizeof var / sizeof var [0]) \ 262 printf("%s", var [val]); \ 263 else \ 264 printf("%d (unknown)", val); \ 265 break; 266 267 if (doi == ISAKMP_DOI) 268 switch(type) { 269 CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc); 270 CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash); 271 CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth); 272 CASE_PRINT(IKE_ATTR_GROUP_DESC, attr_gdesc); 273 CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype); 274 CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype); 275 default: 276 printf("%d", val); 277 } 278 else 279 switch(type) { 280 CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype); 281 CASE_PRINT(IPSEC_ATTR_ENCAPSULATION_MODE, 282 ipsec_attr_encap); 283 CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM, 284 ipsec_attr_auth); 285 default: 286 printf("%d", val); 287 } 288 289 #undef CASE_PRINT 290 return len; 291 } 292 293 void 294 ike_pl_transform_print (u_char *buf, int len, u_char doi) 295 { 296 const char *ah[] = IPSEC_AH_INITIALIZER; 297 const char *esp[] = IPSEC_ESP_INITIALIZER; 298 const char *ipcomp[] = IPCOMP_INITIALIZER; 299 u_char *attr = buf + 4; 300 301 printf("\n\t%stransform: %u ID: ", ike_tab_offset(), buf[0]); 302 303 switch (doi) { 304 case ISAKMP_DOI: 305 if (buf[1] < (sizeof ike / sizeof ike[0])) 306 printf("%s", ike[buf[1]]); 307 else 308 printf("%d(unknown)", buf[1]); 309 break; 310 311 default: /* IPSEC_DOI */ 312 switch (xform_proto) { /* from ike_proposal_print */ 313 case PROTO_IPSEC_AH: 314 if (buf[1] < (sizeof ah / sizeof ah[0])) 315 printf("%s", ah[buf[1]]); 316 else 317 printf("%d(unknown)", buf[1]); 318 break; 319 case PROTO_IPSEC_ESP: 320 if (buf[1] < (sizeof esp / sizeof esp[0])) 321 printf("%s", esp[buf[1]]); 322 else 323 printf("%d(unknown)", buf[1]); 324 break; 325 case PROTO_IPCOMP: 326 if (buf[1] < (sizeof ipcomp / sizeof ipcomp[0])) 327 printf("%s", ipcomp[buf[1]]); 328 else 329 printf("%d(unknown)", buf[1]); 330 break; 331 default: 332 printf("%d(unknown)", buf[1]); 333 } 334 break; 335 } 336 337 ike_tab_level++; 338 while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ 339 attr += ike_attribute_print(attr, doi, len - (attr-buf)); 340 ike_tab_level--; 341 } 342 343 void 344 ike_pl_proposal_print (u_char *buf, int len, u_char doi) 345 { 346 u_int8_t i, p_id = buf[1], spisz = buf[2]; 347 348 printf(" proposal: %d proto: %s spisz: %d xforms: %d", 349 buf[0], (p_id < (sizeof ike / sizeof ike[0]) ? ike[p_id] : 350 "(unknown)"), spisz, buf[3]); 351 352 /* We need to store this for upcoming ike_attribute_print call. */ 353 xform_proto = p_id; 354 355 if (spisz) { 356 if (p_id == PROTO_IPCOMP) 357 printf(" CPI: 0x"); 358 else 359 printf(" SPI: 0x"); 360 for (i = 0; i < spisz && (i + 4) < len; i++) 361 printf("%02x", buf[i + 4]); 362 doi = IPSEC_DOI; 363 } else 364 doi = ISAKMP_DOI; 365 366 if ((char)buf[3] > 0) 367 ike_pl_print(PAYLOAD_TRANSFORM, buf + 4 + buf[2], doi); 368 } 369 370 void 371 ike_pl_ke_print (u_char *buf, int len, u_char doi) 372 { 373 if (doi != IPSEC_DOI) 374 return; 375 376 /* XXX ... */ 377 } 378 379 void 380 ipsec_id_print (u_char *buf, int len, u_char doi) 381 { 382 static const char *idtypes[] = IPSEC_ID_TYPE_INITIALIZER; 383 char ntop_buf[INET6_ADDRSTRLEN]; 384 struct in_addr in; 385 u_char *p; 386 387 if (doi != ISAKMP_DOI) 388 return; 389 390 /* Don't print proto+port unless actually used */ 391 if (buf[1] | buf[2] | buf[3]) 392 printf(" proto: %d port: %d", buf[1], (buf[2] << 8) + buf[3]); 393 394 printf(" type: %s = ", buf[0] < (sizeof idtypes/sizeof idtypes[0]) ? 395 idtypes[buf[0]] : "<unknown>"); 396 397 switch (buf[0]) { 398 case IPSEC_ID_IPV4_ADDR: 399 memcpy (&in.s_addr, buf + 4, sizeof in); 400 printf("%s", inet_ntoa (in)); 401 break; 402 case IPSEC_ID_IPV4_ADDR_SUBNET: 403 case IPSEC_ID_IPV4_ADDR_RANGE: 404 memcpy (&in.s_addr, buf + 4, sizeof in); 405 printf("%s%s", inet_ntoa (in), 406 buf[0] == IPSEC_ID_IPV4_ADDR_SUBNET ? "/" : "-"); 407 memcpy (&in.s_addr, buf + 8, sizeof in); 408 printf("%s", inet_ntoa (in)); 409 break; 410 411 case IPSEC_ID_IPV6_ADDR: 412 printf("%s", inet_ntop (AF_INET6, buf + 4, ntop_buf, 413 sizeof ntop_buf)); 414 break; 415 case IPSEC_ID_IPV6_ADDR_SUBNET: 416 case IPSEC_ID_IPV6_ADDR_RANGE: 417 printf("%s%s", inet_ntop (AF_INET6, buf + 4, ntop_buf, 418 sizeof ntop_buf), 419 buf[0] == IPSEC_ID_IPV6_ADDR_SUBNET ? "/" : "-"); 420 printf("%s", inet_ntop (AF_INET6, buf + 4 + sizeof ntop_buf, 421 ntop_buf, sizeof ntop_buf)); 422 423 case IPSEC_ID_FQDN: 424 case IPSEC_ID_USER_FQDN: 425 printf("\""); 426 for(p = buf + 4; (int)(p - buf) < len - 4; p++) 427 printf("%c",(isprint(*p) ? *p : '.')); 428 printf("\""); 429 break; 430 431 case IPSEC_ID_DER_ASN1_DN: 432 case IPSEC_ID_DER_ASN1_GN: 433 case IPSEC_ID_KEY_ID: 434 default: 435 printf("\"(not shown)\""); 436 break; 437 } 438 } 439 440 void 441 ike_pl_notification_print (u_char *buf, int len) 442 { 443 static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER; 444 struct notification_payload *np = (struct notification_payload *)buf; 445 u_int32_t *replay; 446 u_char *attr; 447 448 if (len < sizeof (struct notification_payload)) { 449 printf(" (|len)"); 450 return; 451 } 452 453 np->doi = ntohl (np->doi); 454 np->type = ntohs (np->type); 455 456 if (np->doi != ISAKMP_DOI && np->doi != IPSEC_DOI) { 457 printf(" (unknown DOI)"); 458 return; 459 } 460 461 printf("\n\t%snotification: ", ike_tab_offset()); 462 463 if (np->type > 0 && np->type < (sizeof nftypes / sizeof nftypes[0])) { 464 printf("%s", nftypes[np->type]); 465 return; 466 } 467 switch (np->type) { 468 469 case NOTIFY_IPSEC_RESPONDER_LIFETIME: 470 printf("RESPONDER LIFETIME"); 471 if (np->spi_size == 16) 472 printf("(%s)", ike_get_cookie (&np->data[0], 473 &np->data[8])); 474 else 475 printf("SPI: 0x%08x", np->data[0]<<24 | 476 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 477 attr = &np->data[np->spi_size]; 478 ike_tab_level++; 479 while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ 480 attr += ike_attribute_print(attr, IPSEC_DOI, 481 len - (attr-buf)); 482 ike_tab_level--; 483 break; 484 485 case NOTIFY_IPSEC_REPLAY_STATUS: 486 replay = (u_int32_t *)&np->data[np->spi_size]; 487 printf("REPLAY STATUS [%sabled] ", *replay ? "en" : "dis"); 488 if (np->spi_size == 16) 489 printf("(%s)", ike_get_cookie (&np->data[0], 490 &np->data[8])); 491 else 492 printf("SPI: 0x%08x", np->data[0]<<24 | 493 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 494 break; 495 496 case NOTIFY_IPSEC_INITIAL_CONTACT: 497 printf("INITIAL CONTACT (%s)", ike_get_cookie (&np->data[0], 498 &np->data[8])); 499 break; 500 501 default: 502 printf("%d (unknown)", np->type); 503 break; 504 } 505 } 506 507 void 508 ike_pl_vendor_print (u_char *buf, int len, u_char doi) 509 { 510 u_char *p = buf; 511 512 if (doi != IPSEC_DOI) 513 return; 514 515 printf(" \""); 516 for (p = buf; (int)(p - buf) < len; p++) 517 printf("%c",(isprint(*p) ? *p : '.')); 518 printf("\""); 519 } 520 521 /* IKE mode-config. */ 522 int 523 ike_cfg_attribute_print (u_char *buf, int attr_type, int maxlen) 524 { 525 static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER; 526 char ntop_buf[INET6_ADDRSTRLEN]; 527 struct in_addr in; 528 529 u_char af = buf[0] >> 7; 530 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 531 u_int16_t len = af ? 2 : buf[2] << 8 | buf[3], p; 532 u_char *val = af ? buf + 2 : buf + 4; 533 534 printf("\n\t\%sattribute %s = ", ike_tab_offset(), 535 type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] : 536 "<unknown>"); 537 538 if ((af == 1 && maxlen < 4) || 539 (af == 0 && maxlen < (len + 4))) { 540 printf("\n\t%s[|attr]", ike_tab_offset()); 541 return maxlen; 542 } 543 544 /* XXX The 2nd term is for bug compatibility with PGPnet. */ 545 if (len == 0 || (af && !val[0] && !val[1])) { 546 printf("<none>"); 547 return 4; 548 } 549 550 /* XXX Generally lengths are not checked well below. */ 551 switch (type) { 552 case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS: 553 case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK: 554 case IKE_CFG_ATTR_INTERNAL_IP4_DNS: 555 case IKE_CFG_ATTR_INTERNAL_IP4_NBNS: 556 case IKE_CFG_ATTR_INTERNAL_IP4_DHCP: 557 memcpy (&in.s_addr, val, sizeof in); 558 printf("%s", inet_ntoa (in)); 559 break; 560 561 case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS: 562 case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK: 563 case IKE_CFG_ATTR_INTERNAL_IP6_DNS: 564 case IKE_CFG_ATTR_INTERNAL_IP6_NBNS: 565 case IKE_CFG_ATTR_INTERNAL_IP6_DHCP: 566 printf("%s", inet_ntop (AF_INET6, val, ntop_buf, 567 sizeof ntop_buf)); 568 break; 569 570 case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET: 571 memcpy(&in.s_addr, val, sizeof in); 572 printf("%s/", inet_ntoa (in)); 573 memcpy(&in.s_addr, val + sizeof in, sizeof in); 574 printf("%s", inet_ntoa (in)); 575 break; 576 577 case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET: 578 printf("%s/%u", inet_ntop (AF_INET6, val, ntop_buf, 579 sizeof ntop_buf), val[16]); 580 break; 581 582 case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY: 583 printf("%u seconds", 584 val[0] << 24 | val[1] << 16 | val[2] << 8 | val[3]); 585 break; 586 587 case IKE_CFG_ATTR_APPLICATION_VERSION: 588 for (p = 0; p < len; p++) 589 printf("%c", isprint(val[p]) ? val[p] : '.'); 590 break; 591 592 case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES: 593 printf("<%d attributes>", len / 2); 594 ike_tab_level++; 595 for (p = 0; p < len; p += 2) { 596 type = (val[p] << 8 | val[p + 1]) & 0x7fff; 597 printf("\n\t%s%s", ike_tab_offset(), 598 type < (sizeof attrs/sizeof attrs[0]) ? 599 attrs[type] : "<unknown>"); 600 } 601 ike_tab_level--; 602 break; 603 604 default: 605 break; 606 } 607 return af ? 4 : len + 4; 608 } 609 610 void 611 ike_pl_attribute_print (u_char *buf, int len) 612 { 613 static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER; 614 u_char type, *attr; 615 u_int16_t id; 616 617 type = buf[0]; 618 id = buf[2]<<8 | buf[3]; 619 attr = buf + 4; 620 621 printf(" type: %s Id: %d", 622 type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[type] : 623 "<unknown>", id); 624 625 while ((int)(attr - buf) < len - 4) 626 attr += ike_cfg_attribute_print(attr, type, len - (attr-buf)); 627 } 628 629 void 630 ike_pl_print (u_char type, u_char *buf, u_char doi) 631 { 632 static const char *pltypes[] = IKE_PAYLOAD_TYPES_INITIALIZER; 633 int next_type = buf[0]; 634 int this_len = buf[2]<<8 | buf[3]; 635 636 printf("\n\t%spayload: %s len: %d", ike_tab_offset(), 637 (type < (sizeof pltypes/sizeof pltypes[0]) ? 638 pltypes[type] : "<unknown>"), this_len); 639 640 if ((u_char *)&(buf[0]) > snapend - this_len) 641 goto pltrunc; 642 643 ike_tab_level++; 644 switch (type) { 645 case PAYLOAD_NONE: 646 return; 647 648 case PAYLOAD_SA: 649 ike_pl_sa_print(buf+4, this_len); 650 break; 651 652 case PAYLOAD_PROPOSAL: 653 ike_pl_proposal_print(buf+4, this_len, doi); 654 break; 655 656 case PAYLOAD_TRANSFORM: 657 ike_pl_transform_print(buf+4, this_len, doi); 658 break; 659 660 case PAYLOAD_KE: 661 ike_pl_ke_print(buf+4, this_len, doi); 662 break; 663 664 case PAYLOAD_ID: 665 /* Should only happen with IPsec DOI */ 666 ipsec_id_print(buf+4, this_len, doi); 667 break; 668 669 case PAYLOAD_CERT: 670 case PAYLOAD_CERTREQUEST: 671 case PAYLOAD_HASH: 672 case PAYLOAD_SIG: 673 case PAYLOAD_NONCE: 674 case PAYLOAD_DELETE: 675 break; 676 677 case PAYLOAD_NOTIFICATION: 678 ike_pl_notification_print(buf, this_len); 679 break; 680 681 case PAYLOAD_VENDOR: 682 ike_pl_vendor_print(buf+4, this_len, doi); 683 break; 684 685 case PAYLOAD_ATTRIBUTE: 686 ike_pl_attribute_print(buf+4, this_len); 687 break; 688 689 default: 690 break; 691 } 692 ike_tab_level--; 693 694 if (next_type) /* Recurse over next payload */ 695 ike_pl_print(next_type, buf + this_len, doi); 696 697 return; 698 699 pltrunc: 700 if (doi == ISAKMP_DOI) 701 fputs(" [|isakmp]", stdout); 702 else 703 fputs(" [|ipsec]", stdout); 704 } 705