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