1 /* $OpenBSD: print-ike.c,v 1.29 2006/08/24 12:13:16 hshoexer 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.29 2006/08/24 12:13:16 hshoexer 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_int8_t init_cookie[8]; 55 u_int8_t resp_cookie[8]; 56 u_int8_t next_payload; 57 u_int8_t version; 58 u_int8_t exgtype; 59 u_int8_t flags; 60 u_int8_t msgid[4]; 61 u_int32_t length; 62 u_int8_t payloads[0]; 63 }; 64 65 struct sa_payload { 66 u_int8_t next_payload; 67 u_int8_t reserved; 68 u_int16_t payload_length; 69 u_int32_t doi; 70 u_int8_t situation[0]; 71 }; 72 73 struct proposal_payload { 74 u_int8_t next_payload; 75 u_int8_t reserved; 76 u_int16_t payload_length; 77 u_int8_t nprop; 78 u_int8_t proto; 79 u_int8_t spi_size; 80 u_int8_t nspis; 81 u_int8_t spi[0]; 82 }; 83 84 struct transform_payload { 85 u_int8_t next_payload; 86 u_int8_t reserved; 87 u_int16_t payload_length; 88 u_int8_t ntrans; 89 u_int8_t transform; 90 u_int16_t reserved2; 91 u_int8_t attribute[0]; 92 }; 93 94 struct ke_payload { 95 u_int8_t next_payload; 96 u_int8_t reserved; 97 u_int16_t payload_length; 98 u_int8_t data[0]; 99 }; 100 101 struct id_payload { 102 u_int8_t next_payload; 103 u_int8_t reserved; 104 u_int16_t payload_length; 105 u_int8_t type; 106 u_int8_t id_data[3]; 107 u_int8_t data[0]; 108 }; 109 110 struct notification_payload { 111 u_int8_t next_payload; 112 u_int8_t reserved; 113 u_int16_t payload_length; 114 u_int32_t doi; 115 u_int8_t protocol_id; 116 u_int8_t spi_size; 117 u_int16_t type; 118 u_int8_t data[0]; 119 }; 120 121 struct delete_payload { 122 u_int8_t next_payload; 123 u_int8_t reserved; 124 u_int16_t payload_length; 125 u_int32_t doi; 126 u_int8_t proto; 127 u_int8_t spi_size; 128 u_int16_t nspis; 129 u_int8_t spi[0]; 130 }; 131 132 struct vendor_payload { 133 u_int8_t next_payload; 134 u_int8_t reserved; 135 u_int16_t payload_length; 136 u_int8_t vid[0]; 137 }; 138 139 struct attribute_payload { 140 u_int8_t next_payload; 141 u_int8_t reserved; 142 u_int16_t payload_length; 143 u_int8_t type; 144 u_int8_t reserved2; 145 u_int16_t id; 146 }; 147 148 static void ike_pl_print(u_int8_t, u_int8_t *, u_int8_t); 149 150 int ike_tab_level = 0; 151 u_int8_t xform_proto; 152 153 static const char *ike[] = IKE_PROTO_INITIALIZER; 154 155 #define SMALL_TABS 4 156 #define SPACES " " 157 const char * 158 ike_tab_offset(void) 159 { 160 const char *p, *endline; 161 static const char line[] = SPACES; 162 163 endline = line + sizeof line - 1; 164 p = endline - SMALL_TABS * (ike_tab_level); 165 166 return (p > line ? p : line); 167 } 168 169 static char * 170 ike_get_cookie (u_int8_t *ic, u_int8_t *rc) 171 { 172 static char cookie_jar[35]; 173 int i; 174 175 for (i = 0; i < 8; i++) 176 snprintf(cookie_jar + i*2, sizeof(cookie_jar) - i*2, 177 "%02x", *(ic + i)); 178 strlcat(cookie_jar, "->", sizeof(cookie_jar)); 179 for (i = 0; i < 8; i++) 180 snprintf(cookie_jar + 18 + i*2, sizeof(cookie_jar) - 18 - i*2, 181 "%02x", *(rc + i)); 182 return cookie_jar; 183 } 184 185 /* 186 * Print isakmp requests 187 */ 188 void 189 ike_print (const u_int8_t *cp, u_int length) 190 { 191 struct isakmp_header *ih; 192 const u_int8_t *ep; 193 u_int8_t *payload, next_payload; 194 int encrypted; 195 static const char *exgtypes[] = IKE_EXCHANGE_TYPES_INITIALIZER; 196 197 encrypted = 0; 198 199 #ifdef TCHECK 200 #undef TCHECK 201 #endif 202 #define TCHECK(var, l) if ((u_int8_t *)&(var) > ep - l) goto trunc 203 204 ih = (struct isakmp_header *)cp; 205 206 if (length < sizeof (struct isakmp_header)) 207 goto trunc; 208 209 /* 'ep' points to the end of avaible data. */ 210 ep = snapend; 211 212 printf(" isakmp"); 213 214 printf(" v%d.%d", ih->version >> 4, ih->version & 0xf); 215 216 printf(" exchange "); 217 if (ih->exgtype < (sizeof exgtypes/sizeof exgtypes[0])) 218 printf("%s", exgtypes[ih->exgtype]); 219 else 220 printf("%d (unknown)", ih->exgtype); 221 222 if (ih->flags & FLAGS_ENCRYPTION) { 223 printf(" encrypted"); 224 encrypted = 1; 225 } 226 227 if (ih->flags & FLAGS_COMMIT) { 228 printf(" commit"); 229 } 230 231 printf("\n\tcookie: %s", ike_get_cookie (ih->init_cookie, 232 ih->resp_cookie)); 233 234 TCHECK(ih->msgid, sizeof(ih->msgid)); 235 printf(" msgid: %02x%02x%02x%02x", ih->msgid[0], ih->msgid[1], 236 ih->msgid[2], ih->msgid[3]); 237 238 TCHECK(ih->length, sizeof(ih->length)); 239 printf(" len: %d", ntohl(ih->length)); 240 241 if (ih->version > 16) { 242 printf(" new version"); 243 return; 244 } 245 246 payload = ih->payloads; 247 next_payload = ih->next_payload; 248 249 /* if encrypted, then open special file for encryption keys */ 250 if (encrypted) { 251 /* decrypt XXX */ 252 return; 253 } 254 255 /* if verbose, print payload data */ 256 if (vflag) 257 ike_pl_print(next_payload, payload, ISAKMP_DOI); 258 259 return; 260 261 trunc: 262 fputs(" [|isakmp]", stdout); 263 } 264 265 void 266 ike_pl_sa_print (u_int8_t *buf, int len) 267 { 268 struct sa_payload *sp = (struct sa_payload *)buf; 269 u_int32_t sit_ipsec; 270 271 if (len < sizeof(struct sa_payload)) { 272 printf(" [|payload]"); 273 return; 274 } 275 276 sp->doi = ntohl(sp->doi); 277 printf(" DOI: %d", sp->doi); 278 279 if (sp->doi == IPSEC_DOI) { 280 if ((sp->situation + sizeof(u_int32_t)) > (buf + len)) { 281 printf(" [|payload]"); 282 return; 283 } 284 printf("(IPSEC) situation: "); 285 sit_ipsec = ntohl(*(u_int32_t *)sp->situation); 286 if (sit_ipsec & IKE_SITUATION_IDENTITY_ONLY) 287 printf("IDENTITY_ONLY "); 288 if (sit_ipsec & IKE_SITUATION_SECRECY) 289 printf("SECRECY "); 290 if (sit_ipsec & IKE_SITUATION_INTEGRITY) 291 printf("INTEGRITY "); 292 if ((sit_ipsec & IKE_SITUATION_MASK) == 0) 293 printf("0x%x (unknown)", sit_ipsec); 294 ike_pl_print (PAYLOAD_PROPOSAL, buf + 295 sizeof(struct sa_payload) + sizeof(u_int32_t), IPSEC_DOI); 296 } else 297 printf(" situation: (unknown)"); 298 } 299 300 int 301 ike_attribute_print (u_int8_t *buf, u_int8_t doi, int maxlen) 302 { 303 static char *attrs[] = IKE_ATTR_INITIALIZER; 304 static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER; 305 static char *attr_hash[] = IKE_ATTR_HASH_INITIALIZER; 306 static char *attr_auth[] = IKE_ATTR_AUTH_INITIALIZER; 307 static char *attr_gdesc[] = IKE_ATTR_GROUP_DESC_INITIALIZER; 308 static char *attr_gtype[] = IKE_ATTR_GROUP_INITIALIZER; 309 static char *attr_ltype[] = IKE_ATTR_SA_DURATION_INITIALIZER; 310 static char *ipsec_attrs[] = IPSEC_ATTR_INITIALIZER; 311 static char *ipsec_attr_encap[] = IPSEC_ATTR_ENCAP_INITIALIZER; 312 static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER; 313 static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER; 314 315 u_int8_t af = buf[0] >> 7; 316 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 317 u_int16_t len = buf[2] << 8 | buf[3], val; 318 319 if (doi == ISAKMP_DOI) 320 printf("\n\t%sattribute %s = ", ike_tab_offset(), 321 (type < sizeof attrs / sizeof attrs[0] ? 322 attrs[type] : "<unknown>")); 323 else 324 printf("\n\t%sattribute %s = ", ike_tab_offset(), 325 (type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? 326 ipsec_attrs[type] : "<unknown>")); 327 328 if ((af == 1 && maxlen < 4) || (af == 0 && maxlen < (len + 4))) { 329 printf("\n\t%s[|attr]", ike_tab_offset()); 330 return maxlen; 331 } 332 333 if (af == 0) { 334 /* AF=0; print the variable length attribute value */ 335 for (val = 0; val < len; val++) 336 printf("%02x", *(buf + 4 + val)); 337 return len + 4; 338 } 339 340 val = len; /* For AF=1, this field is the "VALUE" */ 341 len = 4; /* and with AF=1, length is always 4 */ 342 343 #define CASE_PRINT(TYPE, var) \ 344 case TYPE : \ 345 if (val < sizeof var / sizeof var [0]) \ 346 printf("%s", var [val]); \ 347 else \ 348 printf("%d (unknown)", val); \ 349 break; 350 351 if (doi == ISAKMP_DOI) 352 switch(type) { 353 CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc); 354 CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash); 355 CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth); 356 CASE_PRINT(IKE_ATTR_GROUP_DESC, attr_gdesc); 357 CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype); 358 CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype); 359 default: 360 printf("%d", val); 361 } 362 else 363 switch(type) { 364 CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype); 365 CASE_PRINT(IPSEC_ATTR_ENCAPSULATION_MODE, 366 ipsec_attr_encap); 367 CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM, 368 ipsec_attr_auth); 369 default: 370 printf("%d", val); 371 } 372 373 #undef CASE_PRINT 374 return len; 375 } 376 377 void 378 ike_pl_transform_print (u_int8_t *buf, int len, u_int8_t doi) 379 { 380 struct transform_payload *tp = (struct transform_payload *)buf; 381 const char *ah[] = IPSEC_AH_INITIALIZER; 382 const char *esp[] = IPSEC_ESP_INITIALIZER; 383 const char *ipcomp[] = IPCOMP_INITIALIZER; 384 u_int8_t *attr = tp->attribute; 385 386 if (len < sizeof(struct transform_payload)) { 387 printf(" [|payload]"); 388 return; 389 } 390 391 printf("\n\t%stransform: %u ID: ", ike_tab_offset(), tp->ntrans); 392 393 switch (doi) { 394 case ISAKMP_DOI: 395 if (tp->transform < (sizeof ike / sizeof ike[0])) 396 printf("%s", ike[tp->transform]); 397 else 398 printf("%d(unknown)", tp->transform); 399 break; 400 401 default: /* IPSEC_DOI */ 402 switch (xform_proto) { /* from ike_proposal_print */ 403 case PROTO_IPSEC_AH: 404 if (tp->transform < (sizeof ah / sizeof ah[0])) 405 printf("%s", ah[tp->transform]); 406 else 407 printf("%d(unknown)", tp->transform); 408 break; 409 case PROTO_IPSEC_ESP: 410 if (tp->transform < (sizeof esp / sizeof esp[0])) 411 printf("%s", esp[tp->transform]); 412 else 413 printf("%d(unknown)", tp->transform); 414 break; 415 case PROTO_IPCOMP: 416 if (tp->transform < (sizeof ipcomp / sizeof ipcomp[0])) 417 printf("%s", ipcomp[tp->transform]); 418 else 419 printf("%d(unknown)", tp->transform); 420 break; 421 default: 422 printf("%d(unknown)", tp->transform); 423 } 424 break; 425 } 426 427 ike_tab_level++; 428 while ((int)(attr - buf) < len) /* Skip last 'NONE' attr */ 429 attr += ike_attribute_print(attr, doi, len - (attr - buf)); 430 ike_tab_level--; 431 } 432 433 void 434 ike_pl_proposal_print (u_int8_t *buf, int len, u_int8_t doi) 435 { 436 struct proposal_payload *pp = (struct proposal_payload *)buf; 437 int i; 438 439 if (len < sizeof(struct proposal_payload)) { 440 printf(" [|payload]"); 441 return; 442 } 443 444 printf(" proposal: %d proto: %s spisz: %d xforms: %d", 445 pp->nprop, (pp->proto < (sizeof ike / sizeof ike[0]) ? 446 ike[pp->proto] : "(unknown)"), pp->spi_size, pp->nspis); 447 448 xform_proto = pp->proto; 449 450 if (pp->spi_size) { 451 if ((pp->spi + pp->spi_size) > (buf + len)) { 452 printf(" [|payload]"); 453 return; 454 } 455 if (pp->proto == PROTO_IPCOMP) 456 printf(" CPI: 0x"); 457 else 458 printf(" SPI: 0x"); 459 for (i = 0; i < pp->spi_size; i++) 460 printf("%02x", pp->spi[i]); 461 } 462 463 /* Reset to sane value. */ 464 if (pp->proto == PROTO_ISAKMP) 465 doi = ISAKMP_DOI; 466 else 467 doi = IPSEC_DOI; 468 469 if (pp->nspis > 0) 470 ike_pl_print(PAYLOAD_TRANSFORM, pp->spi + pp->spi_size, doi); 471 } 472 473 void 474 ike_pl_ke_print (u_int8_t *buf, int len, u_int8_t doi) 475 { 476 if (len < sizeof(struct ke_payload)) { 477 printf(" [|payload]"); 478 return; 479 } 480 481 if (doi != IPSEC_DOI) 482 return; 483 484 /* XXX ... */ 485 } 486 487 void 488 ipsec_id_print (u_int8_t *buf, int len, u_int8_t doi) 489 { 490 struct id_payload *ip = (struct id_payload *)buf; 491 static const char *idtypes[] = IPSEC_ID_TYPE_INITIALIZER; 492 char ntop_buf[INET6_ADDRSTRLEN]; 493 struct in_addr in; 494 u_int8_t *p; 495 496 if (len < sizeof (struct id_payload)) { 497 printf(" [|payload]"); 498 return; 499 } 500 501 if (doi != ISAKMP_DOI) 502 return; 503 504 /* Don't print proto+port unless actually used */ 505 if (ip->id_data[0] | ip->id_data[1] | ip->id_data[2]) 506 printf(" proto: %d port: %d", ip->id_data[0], 507 (ip->id_data[1] << 8) + ip->id_data[2]); 508 509 printf(" type: %s = ", ip->type < (sizeof idtypes/sizeof idtypes[0]) ? 510 idtypes[ip->type] : "<unknown>"); 511 512 switch (ip->type) { 513 case IPSEC_ID_IPV4_ADDR: 514 if ((ip->data + sizeof in) > (buf + len)) { 515 printf(" [|payload]"); 516 return; 517 } 518 memcpy (&in.s_addr, ip->data, sizeof in); 519 printf("%s", inet_ntoa (in)); 520 break; 521 522 case IPSEC_ID_IPV4_ADDR_SUBNET: 523 case IPSEC_ID_IPV4_ADDR_RANGE: 524 if ((ip->data + 2 * (sizeof in)) > (buf + len)) { 525 printf(" [|payload]"); 526 return; 527 } 528 memcpy (&in.s_addr, ip->data, sizeof in); 529 printf("%s%s", inet_ntoa (in), 530 ip->type == IPSEC_ID_IPV4_ADDR_SUBNET ? "/" : "-"); 531 memcpy (&in.s_addr, ip->data + sizeof in, sizeof in); 532 printf("%s", inet_ntoa (in)); 533 break; 534 535 case IPSEC_ID_IPV6_ADDR: 536 if ((ip->data + sizeof ntop_buf) > (buf + len)) { 537 printf(" [|payload]"); 538 return; 539 } 540 printf("%s", inet_ntop (AF_INET6, ip->data, ntop_buf, 541 sizeof ntop_buf)); 542 break; 543 544 case IPSEC_ID_IPV6_ADDR_SUBNET: 545 case IPSEC_ID_IPV6_ADDR_RANGE: 546 if ((ip->data + 2 * sizeof ntop_buf) > (buf + len)) { 547 printf(" [|payload]"); 548 return; 549 } 550 printf("%s%s", inet_ntop (AF_INET6, ip->data, ntop_buf, 551 sizeof ntop_buf), 552 ip->type == IPSEC_ID_IPV6_ADDR_SUBNET ? "/" : "-"); 553 printf("%s", inet_ntop (AF_INET6, ip->data + sizeof ntop_buf, 554 ntop_buf, sizeof ntop_buf)); 555 break; 556 557 case IPSEC_ID_FQDN: 558 case IPSEC_ID_USER_FQDN: 559 printf("\""); 560 for (p = ip->data; (int)(p - buf) < len; p++) 561 printf("%c",(isprint(*p) ? *p : '.')); 562 printf("\""); 563 break; 564 565 case IPSEC_ID_DER_ASN1_DN: 566 case IPSEC_ID_DER_ASN1_GN: 567 case IPSEC_ID_KEY_ID: 568 default: 569 printf("\"(not shown)\""); 570 break; 571 } 572 } 573 574 void 575 ike_pl_delete_print (u_int8_t *buf, int len) 576 { 577 struct delete_payload *dp = (struct delete_payload *)buf; 578 u_int16_t s; 579 u_int8_t *data; 580 581 if (len < sizeof (struct delete_payload)) { 582 printf(" [|payload]"); 583 return; 584 } 585 586 dp->doi = ntohl(dp->doi); 587 dp->nspis = ntohs(dp->nspis); 588 589 if (dp->doi != ISAKMP_DOI && dp->doi != IPSEC_DOI) { 590 printf(" (unknown DOI)"); 591 return; 592 } 593 594 printf(" DOI: %u(%s) proto: %s nspis: %u", dp->doi, 595 dp->doi == ISAKMP_DOI ? "ISAKMP" : "IPSEC", 596 dp->proto < (sizeof ike / sizeof ike[0]) ? ike[dp->proto] : 597 "(unknown)", dp->nspis); 598 599 if ((dp->spi + dp->nspis * dp->spi_size) > (buf + len)) { 600 printf(" [|payload]"); 601 return; 602 } 603 604 for (s = 0; s < dp->nspis; s++) { 605 data = dp->spi + s * dp->spi_size; 606 if (dp->spi_size == 16) 607 printf("\n\t%scookie: %s", ike_tab_offset(), 608 ike_get_cookie(&data[0], &data[8])); 609 else 610 printf("\n\t%sSPI: 0x%08x", ike_tab_offset(), 611 data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3]); 612 } 613 } 614 615 void 616 ike_pl_notification_print (u_int8_t *buf, int len) 617 { 618 static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER; 619 struct notification_payload *np = (struct notification_payload *)buf; 620 u_int32_t *replay, *seq; 621 u_int8_t *attr; 622 623 if (len < sizeof (struct notification_payload)) { 624 printf(" [|payload]"); 625 return; 626 } 627 628 np->doi = ntohl (np->doi); 629 np->type = ntohs (np->type); 630 631 if (np->doi != ISAKMP_DOI && np->doi != IPSEC_DOI) { 632 printf(" (unknown DOI)"); 633 return; 634 } 635 636 printf("\n\t%snotification: ", ike_tab_offset()); 637 638 if (np->type > 0 && np->type < (sizeof nftypes / sizeof nftypes[0])) { 639 printf("%s", nftypes[np->type]); 640 return; 641 } 642 switch (np->type) { 643 644 case NOTIFY_IPSEC_RESPONDER_LIFETIME: 645 printf("RESPONDER LIFETIME "); 646 if (np->spi_size == 16) 647 printf("(%s)", ike_get_cookie (&np->data[0], 648 &np->data[8])); 649 else 650 printf("SPI: 0x%08x", np->data[0]<<24 | 651 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 652 attr = &np->data[np->spi_size]; 653 ike_tab_level++; 654 while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ 655 attr += ike_attribute_print(attr, IPSEC_DOI, 656 len - (attr-buf)); 657 ike_tab_level--; 658 break; 659 660 case NOTIFY_IPSEC_REPLAY_STATUS: 661 replay = (u_int32_t *)&np->data[np->spi_size]; 662 printf("REPLAY STATUS [%sabled] ", *replay ? "en" : "dis"); 663 if (np->spi_size == 16) 664 printf("(%s)", ike_get_cookie (&np->data[0], 665 &np->data[8])); 666 else 667 printf("SPI: 0x%08x", np->data[0]<<24 | 668 np->data[1]<<16 | np->data[2]<<8 | np->data[3]); 669 break; 670 671 case NOTIFY_IPSEC_INITIAL_CONTACT: 672 printf("INITIAL CONTACT (%s)", ike_get_cookie (&np->data[0], 673 &np->data[8])); 674 break; 675 676 case NOTIFY_STATUS_DPD_R_U_THERE: 677 case NOTIFY_STATUS_DPD_R_U_THERE_ACK: 678 printf("STATUS_DPD_R_U_THERE%s ", 679 np->type == NOTIFY_STATUS_DPD_R_U_THERE ? "" : "_ACK"); 680 if (np->spi_size != 16 || 681 len < sizeof(struct notification_payload) + 682 sizeof(u_int32_t)) 683 printf("[bad notify]"); 684 else { 685 seq = (u_int32_t *)&np->data[np->spi_size]; 686 printf("seq %u", ntohl(*seq)); 687 } 688 break; 689 690 691 default: 692 printf("%d (unknown)", np->type); 693 break; 694 } 695 } 696 697 void 698 ike_pl_vendor_print (u_int8_t *buf, int len, u_int8_t doi) 699 { 700 struct vendor_payload *vp = (struct vendor_payload *)buf; 701 u_int8_t *p; 702 int i; 703 704 if (len < sizeof(struct vendor_payload)) { 705 printf(" [|payload]"); 706 return; 707 } 708 709 for (i = 0; i < sizeof vendor_ids / sizeof vendor_ids[0]; i ++) 710 if (memcmp(vp->vid, vendor_ids[i].vid, 711 vendor_ids[i].len) == 0) { 712 printf (" (supports %s)", vendor_ids[i].name); 713 return; 714 } 715 716 if (doi != IPSEC_DOI) 717 return; 718 719 printf(" \""); 720 for (p = vp->vid; (int)(p - buf) < len; p++) 721 printf("%c", (isprint(*p) ? *p : '.')); 722 printf("\""); 723 } 724 725 /* IKE mode-config. */ 726 int 727 ike_cfg_attribute_print (u_int8_t *buf, int attr_type, int maxlen) 728 { 729 static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER; 730 char ntop_buf[INET6_ADDRSTRLEN]; 731 struct in_addr in; 732 733 u_int8_t af = buf[0] >> 7; 734 u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; 735 u_int16_t len = af ? 2 : buf[2] << 8 | buf[3], p; 736 u_int8_t *val = af ? buf + 2 : buf + 4; 737 738 printf("\n\t%sattribute %s = ", ike_tab_offset(), 739 type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] : 740 "<unknown>"); 741 742 if ((af == 1 && maxlen < 4) || 743 (af == 0 && maxlen < (len + 4))) { 744 printf("\n\t%s[|attr]", ike_tab_offset()); 745 return maxlen; 746 } 747 748 /* XXX The 2nd term is for bug compatibility with PGPnet. */ 749 if (len == 0 || (af && !val[0] && !val[1])) { 750 printf("<none>"); 751 return 4; 752 } 753 754 /* XXX Generally lengths are not checked well below. */ 755 switch (type) { 756 case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS: 757 case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK: 758 case IKE_CFG_ATTR_INTERNAL_IP4_DNS: 759 case IKE_CFG_ATTR_INTERNAL_IP4_NBNS: 760 case IKE_CFG_ATTR_INTERNAL_IP4_DHCP: 761 memcpy (&in.s_addr, val, sizeof in); 762 printf("%s", inet_ntoa (in)); 763 break; 764 765 case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS: 766 case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK: 767 case IKE_CFG_ATTR_INTERNAL_IP6_DNS: 768 case IKE_CFG_ATTR_INTERNAL_IP6_NBNS: 769 case IKE_CFG_ATTR_INTERNAL_IP6_DHCP: 770 printf("%s", inet_ntop (AF_INET6, val, ntop_buf, 771 sizeof ntop_buf)); 772 break; 773 774 case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET: 775 memcpy(&in.s_addr, val, sizeof in); 776 printf("%s/", inet_ntoa (in)); 777 memcpy(&in.s_addr, val + sizeof in, sizeof in); 778 printf("%s", inet_ntoa (in)); 779 break; 780 781 case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET: 782 printf("%s/%u", inet_ntop (AF_INET6, val, ntop_buf, 783 sizeof ntop_buf), val[16]); 784 break; 785 786 case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY: 787 printf("%u seconds", 788 val[0] << 24 | val[1] << 16 | val[2] << 8 | val[3]); 789 break; 790 791 case IKE_CFG_ATTR_APPLICATION_VERSION: 792 for (p = 0; p < len; p++) 793 printf("%c", isprint(val[p]) ? val[p] : '.'); 794 break; 795 796 case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES: 797 printf("<%d attributes>", len / 2); 798 ike_tab_level++; 799 for (p = 0; p < len; p += 2) { 800 type = (val[p] << 8 | val[p + 1]) & 0x7fff; 801 printf("\n\t%s%s", ike_tab_offset(), 802 type < (sizeof attrs/sizeof attrs[0]) ? 803 attrs[type] : "<unknown>"); 804 } 805 ike_tab_level--; 806 break; 807 808 default: 809 break; 810 } 811 return af ? 4 : len + 4; 812 } 813 814 void 815 ike_pl_attribute_print (u_int8_t *buf, int len) 816 { 817 struct attribute_payload *ap = (struct attribute_payload *)buf; 818 static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER; 819 u_int8_t *attr = buf + sizeof(struct attribute_payload); 820 821 if (len < sizeof(struct attribute_payload)) { 822 printf(" [|payload]"); 823 return; 824 } 825 826 printf(" type: %s Id: %d", 827 ap->type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[ap->type] : 828 "<unknown>", ap->id); 829 830 while ((int)(attr - buf) < len) 831 attr += ike_cfg_attribute_print(attr, ap->type, 832 len - (attr - buf)); 833 } 834 835 void 836 ike_pl_print (u_int8_t type, u_int8_t *buf, u_int8_t doi) 837 { 838 static const char *pltypes[] = IKE_PAYLOAD_TYPES_INITIALIZER; 839 static const char *plprivtypes[] = 840 IKE_PRIVATE_PAYLOAD_TYPES_INITIALIZER; 841 u_int8_t next_type; 842 u_int16_t this_len; 843 844 if (&buf[4] > snapend) { 845 goto pltrunc; 846 } 847 848 next_type = buf[0]; 849 this_len = buf[2]<<8 | buf[3]; 850 851 if (type < PAYLOAD_PRIVATE_MIN || type >= PAYLOAD_PRIVATE_MAX) 852 printf("\n\t%spayload: %s len: %hu", ike_tab_offset(), 853 (type < (sizeof pltypes/sizeof pltypes[0]) ? 854 pltypes[type] : "<unknown>"), this_len); 855 else 856 printf("\n\t%spayload: %s len: %hu", ike_tab_offset(), 857 plprivtypes[type - PAYLOAD_PRIVATE_MIN], this_len); 858 859 if ((type < PAYLOAD_RESERVED_MIN && 860 this_len < min_payload_lengths[type]) || this_len == 0) 861 goto pltrunc; 862 863 if ((type > PAYLOAD_PRIVATE_MIN && type < PAYLOAD_PRIVATE_MAX && 864 this_len < min_priv_payload_lengths[type - PAYLOAD_PRIVATE_MIN]) || 865 this_len == 0) 866 goto pltrunc; 867 868 if (buf + this_len > snapend) 869 goto pltrunc; 870 871 ike_tab_level++; 872 switch (type) { 873 case PAYLOAD_NONE: 874 return; 875 876 case PAYLOAD_SA: 877 ike_pl_sa_print(buf, this_len); 878 break; 879 880 case PAYLOAD_PROPOSAL: 881 ike_pl_proposal_print(buf, this_len, doi); 882 break; 883 884 case PAYLOAD_TRANSFORM: 885 ike_pl_transform_print(buf, this_len, doi); 886 break; 887 888 case PAYLOAD_KE: 889 ike_pl_ke_print(buf, this_len, doi); 890 break; 891 892 case PAYLOAD_ID: 893 /* Should only happen with IPsec DOI */ 894 ipsec_id_print(buf, this_len, doi); 895 break; 896 897 case PAYLOAD_CERT: 898 case PAYLOAD_CERTREQUEST: 899 case PAYLOAD_HASH: 900 case PAYLOAD_SIG: 901 case PAYLOAD_NONCE: 902 break; 903 904 case PAYLOAD_DELETE: 905 ike_pl_delete_print(buf, this_len); 906 break; 907 908 case PAYLOAD_NOTIFICATION: 909 ike_pl_notification_print(buf, this_len); 910 break; 911 912 case PAYLOAD_VENDOR: 913 ike_pl_vendor_print(buf, this_len, doi); 914 break; 915 916 case PAYLOAD_ATTRIBUTE: 917 ike_pl_attribute_print(buf, this_len); 918 break; 919 920 case PAYLOAD_SAK: 921 case PAYLOAD_SAT: 922 case PAYLOAD_KD: 923 case PAYLOAD_SEQ: 924 case PAYLOAD_POP: 925 case PAYLOAD_NAT_D: 926 case PAYLOAD_NAT_OA: 927 case PAYLOAD_NAT_D_DRAFT: 928 case PAYLOAD_NAT_OA_DRAFT: 929 break; 930 931 default: 932 break; 933 } 934 ike_tab_level--; 935 936 if (next_type) /* Recurse over next payload */ 937 ike_pl_print(next_type, buf + this_len, doi); 938 939 return; 940 941 pltrunc: 942 if (doi == ISAKMP_DOI) 943 fputs(" [|isakmp]", stdout); 944 else 945 fputs(" [|ipsec]", stdout); 946 } 947