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