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