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