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