1 /* $OpenBSD: print-ppp.c,v 1.34 2020/01/24 22:46:37 procter Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #ifdef PPP 25 #include <sys/time.h> 26 #include <sys/socket.h> 27 #include <sys/file.h> 28 #include <sys/ioctl.h> 29 30 struct mbuf; 31 struct rtentry; 32 #include <net/if.h> 33 34 #include <netinet/in.h> 35 #include <netinet/ip.h> 36 37 #include <ctype.h> 38 #include <netdb.h> 39 #include <pcap.h> 40 #include <signal.h> 41 #include <stdio.h> 42 43 #include <netinet/if_ether.h> 44 #include "ethertype.h" 45 46 #include <net/ppp_defs.h> 47 #include "interface.h" 48 #include "addrtoname.h" 49 #include "extract.h" 50 51 #ifndef nitems 52 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0])) 53 #endif 54 55 #ifndef PPP_EAP 56 #define PPP_EAP 0xc227 57 #endif 58 59 #ifndef PPP_CDP 60 #define PPP_CDP 0x0207 61 #endif 62 63 #ifndef PPP_CDPCP 64 #define PPP_CDPCP 0x8207 65 #endif 66 67 struct protonames { 68 u_short protocol; 69 char *name; 70 }; 71 72 static const struct protonames protonames[] = { 73 /* 74 * Protocol field values. 75 */ 76 { PPP_IP, "IP" }, /* Internet Protocol */ 77 { PPP_XNS, "XNS" }, /* Xerox NS */ 78 { PPP_IPX, "IPX" }, /* IPX Datagram (RFC1552) */ 79 { PPP_AT, "AppleTalk" }, /* AppleTalk Protocol */ 80 { PPP_VJC_COMP, "VJC_UNCOMP" }, /* VJ compressed TCP */ 81 { PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */ 82 { PPP_IPV6, "IPv6" }, /* Internet Protocol version 6 */ 83 { PPP_COMP, "COMP" }, /* compressed packet */ 84 { PPP_IPCP, "IPCP" }, /* IP Control Protocol */ 85 { PPP_ATCP, "AppleTalkCP" },/* AppleTalk Control Protocol */ 86 { PPP_IPXCP, "IPXCP" }, /* IPX Control Protocol (RFC1552) */ 87 { PPP_IPV6CP, "IPV6CP" }, /* IPv6 Control Protocol */ 88 { PPP_CCP, "CCP" }, /* Compression Control Protocol */ 89 { PPP_LCP, "LCP" }, /* Link Control Protocol */ 90 { PPP_PAP, "PAP" }, /* Password Authentication Protocol */ 91 { PPP_LQR, "LQR" }, /* Link Quality Report protocol */ 92 { PPP_CBCP, "CBCP" }, /* Callback Control Protocol */ 93 { PPP_CHAP, "CHAP" }, /* Cryptographic Handshake Auth. Proto */ 94 { PPP_EAP, "EAP" }, /* Extensible Auth. Protocol */ 95 { PPP_CDP, "CDP" }, 96 { PPP_CDPCP, "CDPCP" }, 97 }; 98 99 struct ppp_control { 100 uint8_t code; 101 uint8_t id; 102 uint16_t len; 103 }; 104 105 struct ppp_cp_type { 106 const char *unkname; 107 int mincode; 108 int maxcode; 109 const char **codes; 110 }; 111 112 /* LCP */ 113 114 #define LCP_CONF_REQ 1 115 #define LCP_CONF_ACK 2 116 #define LCP_CONF_NAK 3 117 #define LCP_CONF_REJ 4 118 #define LCP_TERM_REQ 5 119 #define LCP_TERM_ACK 6 120 #define LCP_CODE_REJ 7 121 #define LCP_PROT_REJ 8 122 #define LCP_ECHO_REQ 9 123 #define LCP_ECHO_RPL 10 124 #define LCP_DISC_REQ 11 125 126 #define LCP_MIN LCP_CONF_REQ 127 #define LCP_MAX LCP_DISC_REQ 128 129 static const char *lcpcodes[] = { 130 /* 131 * LCP code values (RFC1661, pp26) 132 */ 133 "Configure-Request", 134 "Configure-Ack", 135 "Configure-Nak", 136 "Configure-Reject", 137 "Terminate-Request", 138 "Terminate-Ack", 139 "Code-Reject", 140 "Protocol-Reject", 141 "Echo-Request", 142 "Echo-Reply", 143 "Discard-Request", 144 }; 145 146 #define LCPOPT_VEXT 0 147 #define LCPOPT_MRU 1 148 #define LCPOPT_ACCM 2 149 #define LCPOPT_AP 3 150 #define LCPOPT_QP 4 151 #define LCPOPT_MN 5 152 #define LCPOPT_PFC 7 153 #define LCPOPT_ACFC 8 154 155 #define LCPOPT_MIN 0 156 #define LCPOPT_MAX 24 157 158 static char *lcpconfopts[] = { 159 "Vendor-Ext", 160 "Max-Rx-Unit", 161 "Async-Ctrl-Char-Map", 162 "Auth-Prot", 163 "Quality-Prot", 164 "Magic-Number", 165 "unassigned (6)", 166 "Prot-Field-Compr", 167 "Add-Ctrl-Field-Compr", 168 "FCS-Alternatives", 169 "Self-Describing-Pad", 170 "Numbered-Mode", 171 "Multi-Link-Procedure", 172 "Call-Back", 173 "Connect-Time" 174 "Compund-Frames", 175 "Nominal-Data-Encap", 176 "Multilink-MRRU", 177 "Multilink-SSNHF", 178 "Multilink-ED", 179 "Proprietary", 180 "DCE-Identifier", 181 "Multilink-Plus-Proc", 182 "Link-Discriminator", 183 "LCP-Auth-Option", 184 }; 185 186 /* CHAP */ 187 188 #define CHAP_CHAL 1 189 #define CHAP_RESP 2 190 #define CHAP_SUCC 3 191 #define CHAP_FAIL 4 192 193 #define CHAP_CODEMIN 1 194 #define CHAP_CODEMAX 4 195 196 static const char *chapcode[] = { 197 "Challenge", 198 "Response", 199 "Success", 200 "Failure", 201 }; 202 203 /* PAP */ 204 205 #define PAP_AREQ 1 206 #define PAP_AACK 2 207 #define PAP_ANAK 3 208 209 #define PAP_CODEMIN 1 210 #define PAP_CODEMAX 3 211 212 static const char *papcode[] = { 213 "Authenticate-Request", 214 "Authenticate-Ack", 215 "Authenticate-Nak", 216 }; 217 218 /* EAP */ 219 220 #define EAP_CHAL 1 221 #define EAP_RESP 2 222 #define EAP_SUCC 3 223 #define EAP_FAIL 4 224 225 #define EAP_CODEMIN EAP_CHAL 226 #define EAP_CODEMAX EAP_FAIL 227 228 #define EAP_TYPE_IDENTITY 1 229 #define EAP_TYPE_NOTIFICATION 2 230 #define EAP_TYPE_NAK 3 231 #define EAP_TYPE_MD5_CHALLENGE 4 232 #define EAP_TYPE_OTP 5 233 #define EAP_TYPE_TOKEN 6 234 235 #define EAP_TYPEMIN EAP_TYPE_IDENTITY 236 #define EAP_TYPEMAX EAP_TYPE_TOKEN 237 238 static const char *eapcode[] = { 239 "Challenge", 240 "Response", 241 "Success", 242 "Failure", 243 }; 244 245 static const char *eaptype[] = { 246 "Identity", 247 "Notification", 248 "Nak", 249 "MD5-Challenge", 250 "One-Time-Password", 251 "Token", 252 }; 253 254 255 /* IPCP */ 256 257 #define IPCP_CODE_CFG_REQ 1 258 #define IPCP_CODE_CFG_ACK 2 259 #define IPCP_CODE_CFG_NAK 3 260 #define IPCP_CODE_CFG_REJ 4 261 #define IPCP_CODE_TRM_REQ 5 262 #define IPCP_CODE_TRM_ACK 6 263 #define IPCP_CODE_COD_REJ 7 264 265 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ 266 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ 267 268 #define IPCP_2ADDR 1 269 #define IPCP_CP 2 270 #define IPCP_ADDR 3 271 272 /* IPV6CP */ 273 274 #define IPV6CP_CODE_CFG_REQ 1 275 #define IPV6CP_CODE_CFG_ACK 2 276 #define IPV6CP_CODE_CFG_NAK 3 277 #define IPV6CP_CODE_CFG_REJ 4 278 #define IPV6CP_CODE_TRM_REQ 5 279 #define IPV6CP_CODE_TRM_ACK 6 280 #define IPV6CP_CODE_COD_REJ 7 281 282 #define IPV6CP_CODE_MIN IPV6CP_CODE_CFG_REQ 283 #define IPV6CP_CODE_MAX IPV6CP_CODE_COD_REJ 284 285 #define IPV6CP_IFID 1 286 287 static int print_lcp_config_options(const u_char *p, int); 288 static void handle_lcp(const u_char *, int); 289 static void handle_chap(const u_char *p, int); 290 static void handle_eap(const u_char *p, int); 291 static void handle_ipcp(const u_char *p, int); 292 static int print_ipcp_config_options(const u_char *, int); 293 static void handle_ipv6cp(const u_char *p, int); 294 static int print_ipv6cp_config_options(const u_char *, int); 295 static void handle_pap(const u_char *p, int); 296 297 struct pppoe_header { 298 u_int8_t vertype; /* PPPoE version/type */ 299 u_int8_t code; /* PPPoE code (packet type) */ 300 u_int16_t sessionid; /* PPPoE session id */ 301 u_int16_t len; /* PPPoE payload length */ 302 }; 303 #define PPPOE_CODE_SESSION 0x00 /* Session */ 304 #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ 305 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ 306 #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ 307 #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session-Confirm */ 308 #define PPPOE_CODE_PADT 0xa7 /* Active Discovery Terminate */ 309 #define PPPOE_TAG_END_OF_LIST 0x0000 /* End Of List */ 310 #define PPPOE_TAG_SERVICE_NAME 0x0101 /* Service Name */ 311 #define PPPOE_TAG_AC_NAME 0x0102 /* Access Concentrator Name */ 312 #define PPPOE_TAG_HOST_UNIQ 0x0103 /* Host Uniq */ 313 #define PPPOE_TAG_AC_COOKIE 0x0104 /* Access Concentratr Cookie */ 314 #define PPPOE_TAG_VENDOR_SPEC 0x0105 /* Vendor Specific */ 315 #define PPPOE_TAG_RELAY_SESSION 0x0110 /* Relay Session Id */ 316 #define PPPOE_TAG_MAX_PAYLOAD 0x0120 /* RFC 4638 Max Payload */ 317 #define PPPOE_TAG_SERVICE_NAME_ERROR 0x0201 /* Service Name Error */ 318 #define PPPOE_TAG_AC_SYSTEM_ERROR 0x0202 /* Acc. Concentrator Error */ 319 #define PPPOE_TAG_GENERIC_ERROR 0x0203 /* Generic Error */ 320 321 static void 322 ppp_protoname(uint16_t proto) 323 { 324 const struct protonames *protoname; 325 int i; 326 327 /* bsearch? */ 328 for (i = 0; i < nitems(protonames); i++) { 329 protoname = &protonames[i]; 330 331 if (proto == protoname->protocol) { 332 printf("%s ", protoname->name); 333 return; 334 } 335 } 336 337 printf("unknown-ppp-%04x", proto); 338 } 339 340 void 341 ppp_print(const u_char *p, u_int length) 342 { 343 uint16_t proto; 344 int l; 345 346 l = snapend - p; 347 348 if (l < sizeof(proto)) { 349 printf("[|ppp]"); 350 return; 351 } 352 353 proto = EXTRACT_16BITS(p); 354 355 p += sizeof(proto); 356 l -= sizeof(proto); 357 length -= sizeof(proto); 358 359 if (eflag) 360 ppp_protoname(proto); 361 362 switch (proto) { 363 case PPP_IP: 364 ip_print(p, length); 365 return; 366 case PPP_IPV6: 367 ip6_print(p, length); 368 return; 369 } 370 371 if (!eflag) 372 ppp_protoname(proto); 373 374 switch(proto) { 375 case PPP_LCP: 376 handle_lcp(p, l); 377 break; 378 case PPP_CHAP: 379 handle_chap(p, l); 380 break; 381 case PPP_EAP: 382 handle_eap(p, l); 383 break; 384 case PPP_PAP: 385 handle_pap(p, l); 386 break; 387 case PPP_IPCP: 388 handle_ipcp(p, l); 389 break; 390 case PPP_IPV6CP: 391 handle_ipv6cp(p, l); 392 break; 393 case PPP_CDP: 394 cdp_print(p, length, l, 0); 395 break; 396 } 397 } 398 399 static int 400 ppp_cp_header(struct ppp_control *pc, const u_char *p, int l, 401 const struct ppp_cp_type *t) 402 { 403 uint8_t code; 404 int off = 0; 405 int len; 406 407 len = sizeof(pc->code); 408 if (l < len) 409 return (-1); 410 411 pc->code = code = *(p + off); 412 if (code >= t->mincode && code <= t->maxcode) 413 printf("%s ", t->codes[code - 1]); 414 else 415 printf("unknown-%s-%u ", t->unkname, pc->code); 416 417 off = len; 418 len += sizeof(pc->id); 419 if (l < len) 420 return (-1); 421 422 pc->id = *(p + off); 423 printf("Id=0x%02x:", pc->id); 424 425 off = len; 426 len += sizeof(pc->len); 427 if (l < len) 428 return (-1); 429 430 pc->len = EXTRACT_16BITS(p + off); 431 432 return (len); 433 } 434 435 /* print LCP frame */ 436 437 static const struct ppp_cp_type ppp_cp_lcp = { 438 "lcp", 439 LCP_MIN, LCP_MAX, 440 lcpcodes, 441 }; 442 443 static void 444 handle_lcp(const u_char *p, int l) 445 { 446 struct ppp_control pc; 447 int i; 448 449 if (ppp_cp_header(&pc, p, l, &ppp_cp_lcp) == -1) 450 goto trunc; 451 452 if (l > pc.len) 453 l = pc.len; 454 455 p += sizeof(pc); 456 l -= sizeof(pc); 457 458 switch (pc.code) { 459 case LCP_CONF_REQ: 460 case LCP_CONF_ACK: 461 case LCP_CONF_NAK: 462 case LCP_CONF_REJ: 463 while (l > 0) { 464 int optlen; 465 466 optlen = print_lcp_config_options(p, l); 467 if (optlen == -1) 468 goto trunc; 469 if (optlen == 0) 470 break; 471 472 p += optlen; 473 l -= optlen; 474 } 475 break; 476 case LCP_ECHO_REQ: 477 case LCP_ECHO_RPL: 478 if (l < 4) 479 goto trunc; 480 printf(" Magic-Number=%u", EXTRACT_32BITS(p)); 481 p += 4; 482 l -= 4; 483 484 i = sizeof(pc) + 4; 485 if (i == pc.len) 486 break; 487 488 printf(" Data="); 489 do { 490 if (l == 0) 491 goto trunc; 492 493 printf("%02x", *p); 494 495 p++; 496 l--; 497 } while (++i < pc.len); 498 break; 499 case LCP_TERM_REQ: 500 case LCP_TERM_ACK: 501 case LCP_CODE_REJ: 502 case LCP_PROT_REJ: 503 case LCP_DISC_REQ: 504 default: 505 break; 506 } 507 return; 508 509 trunc: 510 printf("[|lcp]"); 511 } 512 513 /* LCP config options */ 514 515 static int 516 print_lcp_config_options(const u_char *p, int l) 517 { 518 uint8_t type, length; 519 uint16_t proto; 520 521 if (l < sizeof(type)) 522 return (-1); 523 524 type = p[0]; 525 if (type <= LCPOPT_MAX) 526 printf(" %s", lcpconfopts[type]); 527 else 528 printf(" unknown-lcp-%u", type); 529 530 if (l < sizeof(type) + sizeof(length)) 531 return (-1); 532 533 length = p[1]; 534 535 if (length < sizeof(type) + sizeof(length)) 536 return (0); 537 538 if (l > length) 539 l = length; 540 541 p += sizeof(type) + sizeof(length); 542 l -= sizeof(type) + sizeof(length); 543 544 switch (type) { 545 case LCPOPT_MRU: 546 if (length != 4) 547 goto invalid; 548 if (l < 2) 549 return (-1); 550 551 printf("=%u", EXTRACT_16BITS(p)); 552 break; 553 case LCPOPT_AP: 554 if (length < 4) 555 goto invalid; 556 if (l < sizeof(proto)) 557 return (-1); 558 559 proto = EXTRACT_16BITS(p); 560 switch (proto) { 561 case PPP_PAP: 562 printf("=PAP"); 563 break; 564 case PPP_CHAP: 565 printf("=CHAP"); 566 if (length < 5) 567 goto invalid; 568 569 p += sizeof(proto); 570 l -= sizeof(proto); 571 572 type = *p; 573 switch (type) { 574 case 0x05: 575 printf("/MD5"); 576 break; 577 case 0x80: 578 printf("/Microsoft"); 579 break; 580 default: 581 printf("/unknown-algorithm-%02x", type); 582 break; 583 } 584 break; 585 case PPP_EAP: 586 printf("=EAP"); 587 break; 588 case 0xc027: 589 printf("=SPAP"); 590 break; 591 case 0xc127: 592 printf("=Old-SPAP"); 593 break; 594 default: 595 printf("=unknown-ap-%04x", proto); 596 break; 597 } 598 break; 599 case LCPOPT_QP: 600 if (length < 4) 601 goto invalid; 602 if (l < sizeof(proto)) 603 return (-1); 604 605 proto = EXTRACT_16BITS(p); 606 switch (proto) { 607 case PPP_LQR: 608 printf(" LQR"); 609 break; 610 default: 611 printf(" unknown-qp-%u", proto); 612 } 613 break; 614 case LCPOPT_MN: 615 if (length < 6) 616 goto invalid; 617 if (l < 4) 618 return (-1); 619 620 printf("=%u", EXTRACT_32BITS(p)); 621 break; 622 case LCPOPT_PFC: 623 printf(" PFC"); 624 break; 625 case LCPOPT_ACFC: 626 printf(" ACFC"); 627 break; 628 } 629 630 return (length); 631 632 invalid: 633 printf(" invalid opt len %u", length); 634 return (length); 635 } 636 637 /* CHAP */ 638 639 static const struct ppp_cp_type ppp_cp_chap = { 640 "chap", 641 CHAP_CODEMIN, CHAP_CODEMAX, 642 chapcode, 643 }; 644 645 static void 646 handle_chap(const u_char *p, int l) 647 { 648 struct ppp_control pc; 649 uint8_t vsize; 650 int i; 651 652 if (ppp_cp_header(&pc, p, l, &ppp_cp_chap) == -1) 653 goto trunc; 654 655 if (l > pc.len) 656 l = pc.len; 657 658 p += sizeof(pc); 659 l -= sizeof(pc); 660 661 switch (pc.code) { 662 case CHAP_CHAL: 663 case CHAP_RESP: 664 if (l < sizeof(vsize)) 665 goto trunc; 666 667 vsize = *p; 668 if (vsize < 1) { 669 printf(" invalid Value-Size"); 670 return; 671 } 672 673 p += sizeof(vsize); 674 l -= sizeof(vsize); 675 676 printf(" Value="); 677 for (i = 0; i < vsize; i++) { 678 if (l == 0) 679 goto trunc; 680 681 printf("%02x", *p); 682 683 p++; 684 l--; 685 } 686 687 printf(" Name="); 688 for (i += sizeof(pc) + sizeof(vsize); i < pc.len; i++) { 689 if (l == 0) 690 goto trunc; 691 692 safeputchar(*p); 693 694 p++; 695 l--; 696 } 697 break; 698 case CHAP_SUCC: 699 case CHAP_FAIL: 700 printf(" Message="); 701 for (i = sizeof(pc); i < pc.len; i++) { 702 if (l == 0) 703 goto trunc; 704 705 safeputchar(*p); 706 707 p++; 708 l--; 709 } 710 break; 711 } 712 return; 713 714 trunc: 715 printf("[|chap]"); 716 } 717 718 /* EAP */ 719 720 static const struct ppp_cp_type ppp_cp_eap = { 721 "eap", 722 EAP_CODEMIN, EAP_CODEMAX, 723 eapcode, 724 }; 725 726 static void 727 handle_eap(const u_char *p, int l) 728 { 729 struct ppp_control pc; 730 uint8_t type, vsize; 731 int i; 732 733 if (ppp_cp_header(&pc, p, l, &ppp_cp_eap) == -1) 734 goto trunc; 735 736 if (l > pc.len) 737 l = pc.len; 738 739 p += sizeof(pc); 740 l -= sizeof(pc); 741 742 switch (pc.code) { 743 case EAP_CHAL: 744 case EAP_RESP: 745 if (l < sizeof(type)) 746 goto trunc; 747 748 type = *p; 749 p += sizeof(type); 750 l -= sizeof(type); 751 752 if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX) 753 printf(" %s", eaptype[type - 1]); 754 else { 755 printf(" unknown-eap-type-%u", type); 756 return; 757 } 758 759 switch (type) { 760 case EAP_TYPE_IDENTITY: 761 case EAP_TYPE_NOTIFICATION: 762 case EAP_TYPE_OTP: 763 i = sizeof(pc) + sizeof(type); 764 if (i == pc.len) 765 break; 766 767 printf("="); 768 do { 769 if (l == 0) 770 goto trunc; 771 772 safeputchar(*p); 773 774 p++; 775 l--; 776 } while (++i < pc.len); 777 break; 778 779 case EAP_TYPE_NAK: 780 if (l < sizeof(type)) 781 goto trunc; 782 type = *p; 783 if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX) 784 printf(" %s", eaptype[type - 1]); 785 else 786 printf(" unknown-eap-type-%u", type); 787 break; 788 case EAP_TYPE_MD5_CHALLENGE: 789 if (l < sizeof(vsize)) 790 goto trunc; 791 792 vsize = *p; 793 p += sizeof(vsize); 794 l -= sizeof(vsize); 795 796 printf("="); 797 for (i = 0; i < vsize; i++) { 798 if (l == 0) 799 goto trunc; 800 801 printf("%02x", *p); 802 803 p++; 804 l--; 805 } 806 break; 807 } 808 break; 809 case CHAP_SUCC: 810 case CHAP_FAIL: 811 break; 812 } 813 return; 814 815 trunc: 816 printf("[|eap]"); 817 } 818 819 /* PAP */ 820 821 static const struct ppp_cp_type ppp_cp_pap = { 822 "pap", 823 PAP_CODEMIN, PAP_CODEMAX, 824 papcode, 825 }; 826 827 static void 828 handle_pap(const u_char *p, int l) 829 { 830 struct ppp_control pc; 831 uint8_t x; 832 int i; 833 834 if (ppp_cp_header(&pc, p, l, &ppp_cp_pap) == -1) 835 goto trunc; 836 837 if (l > pc.len) 838 l = pc.len; 839 840 p += sizeof(pc); 841 l -= sizeof(pc); 842 843 switch (pc.code) { 844 case PAP_AREQ: 845 if (l < sizeof(x)) /* Peer-ID Length */ 846 goto trunc; 847 848 x = *p; 849 850 p += sizeof(x); 851 l -= sizeof(x); 852 853 printf(" Peer-Id="); 854 for (i = 0; i < x; i++) { 855 if (l == 0) 856 goto trunc; 857 858 safeputchar(*p); 859 860 p++; 861 l--; 862 } 863 864 if (l < sizeof(x)) /* Passwd-Length */ 865 goto trunc; 866 867 x = *p; 868 869 p += sizeof(x); 870 l -= sizeof(x); 871 872 printf(" Passwd="); 873 for (i = 0; i < x; i++) { 874 if (l == 0) 875 goto trunc; 876 877 safeputchar(*p); 878 879 p++; 880 l--; 881 } 882 break; 883 884 case PAP_AACK: 885 case PAP_ANAK: 886 if (l < sizeof(x)) /* Msg-Length */ 887 goto trunc; 888 889 x = *p; 890 891 p += sizeof(x); 892 l -= sizeof(x); 893 894 printf(" Message="); 895 for (i = 0; i < x; i++) { 896 if (l == 0) 897 goto trunc; 898 899 safeputchar(*p); 900 901 p++; 902 l--; 903 } 904 break; 905 } 906 907 return; 908 909 trunc: 910 printf("[|pap]"); 911 } 912 913 /* IPCP */ 914 915 #define IP_LEN 4 916 #define IP_FMT "%u.%u.%u.%u" 917 #define IP_ARG(_p) (_p)[0], (_p)[1], (_p)[2], (_p)[3] 918 919 static const struct ppp_cp_type ppp_cp_ipcp = { 920 "ipcp", 921 IPCP_CODE_MIN, IPCP_CODE_MAX, 922 lcpcodes, 923 }; 924 925 static void 926 handle_ipcp(const u_char *p, int l) 927 { 928 struct ppp_control pc; 929 930 if (ppp_cp_header(&pc, p, l, &ppp_cp_ipcp) == -1) 931 goto trunc; 932 933 if (l > pc.len) 934 l = pc.len; 935 936 p += sizeof(pc); 937 l -= sizeof(pc); 938 939 switch (pc.code) { 940 case IPCP_CODE_CFG_REQ: 941 case IPCP_CODE_CFG_ACK: 942 case IPCP_CODE_CFG_NAK: 943 case IPCP_CODE_CFG_REJ: 944 while (l > 0) { 945 int optlen; 946 947 optlen = print_ipcp_config_options(p, l); 948 if (optlen == -1) 949 goto trunc; 950 if (optlen == 0) 951 break; 952 953 p += optlen; 954 l -= optlen; 955 } 956 break; 957 958 case IPCP_CODE_TRM_REQ: 959 case IPCP_CODE_TRM_ACK: 960 case IPCP_CODE_COD_REJ: 961 default: 962 break; 963 } 964 965 return; 966 967 trunc: 968 printf("[|ipcp]"); 969 } 970 971 static int 972 print_ipcp_config_options(const u_char *p, int l) 973 { 974 uint8_t type, length; 975 976 if (l < sizeof(type)) 977 return (-1); 978 979 type = p[0]; 980 switch (type) { 981 case IPCP_2ADDR: 982 printf(" IP-Addresses"); 983 break; 984 case IPCP_CP: 985 printf(" IP-Compression-Protocol"); 986 break; 987 case IPCP_ADDR: 988 printf(" IP-Address"); 989 break; 990 default: 991 printf(" ipcp-type-%u", type); 992 break; 993 } 994 995 if (l < sizeof(type) + sizeof(length)) 996 return (-1); 997 998 length = p[1]; 999 1000 p += (sizeof(type) + sizeof(length)); 1001 l -= (sizeof(type) + sizeof(length)); 1002 1003 switch (type) { 1004 case IPCP_2ADDR: 1005 if (length != 10) 1006 goto invalid; 1007 if (l < IP_LEN) 1008 return (-1); 1009 1010 printf(" Src=" IP_FMT, IP_ARG(p)); 1011 1012 p += IP_LEN; 1013 l -= IP_LEN; 1014 1015 if (l < IP_LEN) 1016 return (-1); 1017 1018 printf(" Dst=" IP_FMT, IP_ARG(p)); 1019 break; 1020 case IPCP_CP: 1021 if (length < 4) 1022 goto invalid; 1023 if (l < sizeof(type)) 1024 return (-1); 1025 1026 type = EXTRACT_16BITS(p); 1027 switch (type) { 1028 case 0x0037: 1029 printf(" Van Jacobsen Compressed TCP/IP"); 1030 break; 1031 default: 1032 printf("ipcp-compression-type-%u", type); 1033 break; 1034 } 1035 break; 1036 case IPCP_ADDR: 1037 if (length != 6) 1038 goto invalid; 1039 if (l < IP_LEN) 1040 return (-1); 1041 1042 printf("=" IP_FMT, IP_ARG(p)); 1043 break; 1044 } 1045 1046 return (length); 1047 1048 invalid: 1049 printf(" invalid opt len %u", length); 1050 return (length); 1051 } 1052 1053 /* IPV6CP */ 1054 1055 static const struct ppp_cp_type ppp_cp_ipv6cp = { 1056 "ipv6cp", 1057 IPV6CP_CODE_MIN, IPV6CP_CODE_MAX, 1058 lcpcodes, 1059 }; 1060 1061 static void 1062 handle_ipv6cp(const u_char *p, int l) 1063 { 1064 struct ppp_control pc; 1065 1066 if (ppp_cp_header(&pc, p, l, &ppp_cp_ipv6cp) == -1) 1067 goto trunc; 1068 1069 if (l > pc.len) 1070 l = pc.len; 1071 1072 p += sizeof(pc); 1073 l -= sizeof(pc); 1074 1075 switch (pc.code) { 1076 case IPV6CP_CODE_CFG_REQ: 1077 case IPV6CP_CODE_CFG_ACK: 1078 case IPV6CP_CODE_CFG_NAK: 1079 case IPV6CP_CODE_CFG_REJ: 1080 while (l > 0) { 1081 int optlen; 1082 1083 optlen = print_ipv6cp_config_options(p, l); 1084 if (optlen == -1) 1085 goto trunc; 1086 if (optlen == 0) 1087 break; 1088 1089 p += optlen; 1090 l -= optlen; 1091 } 1092 break; 1093 1094 case IPV6CP_CODE_TRM_REQ: 1095 case IPV6CP_CODE_TRM_ACK: 1096 case IPV6CP_CODE_COD_REJ: 1097 default: 1098 break; 1099 } 1100 1101 return; 1102 1103 trunc: 1104 printf("[|ipv6cp]"); 1105 } 1106 1107 static int 1108 print_ipv6cp_config_options(const u_char *p, int l) 1109 { 1110 uint8_t type, length; 1111 1112 if (l < sizeof(type)) 1113 return (-1); 1114 1115 type = p[0]; 1116 switch (type) { 1117 case IPV6CP_IFID: 1118 printf(" IPv6-Interface-Id"); 1119 break; 1120 default: 1121 printf(" ipv6cp-type-%u", type); 1122 break; 1123 } 1124 1125 if (l < sizeof(type) + sizeof(length)) 1126 return (-1); 1127 1128 length = p[1]; 1129 1130 p += (sizeof(type) + sizeof(length)); 1131 l -= (sizeof(type) + sizeof(length)); 1132 1133 switch (type) { 1134 case IPV6CP_IFID: 1135 if (length != 10) 1136 goto invalid; 1137 if (l < 8) 1138 return (-1); 1139 1140 printf("=%04x:%04x:%04x:%04x", EXTRACT_16BITS(p + 0), 1141 EXTRACT_16BITS(p + 2), EXTRACT_16BITS(p + 4), 1142 EXTRACT_16BITS(p + 6)); 1143 break; 1144 default: 1145 break; 1146 } 1147 1148 return (length); 1149 invalid: 1150 printf(" invalid opt len %u", length); 1151 return (length); 1152 } 1153 1154 void 1155 ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 1156 { 1157 u_int length = h->len; 1158 u_int caplen = h->caplen; 1159 1160 packetp = p; 1161 snapend = p + caplen; 1162 1163 ts_print(&h->ts); 1164 1165 ppp_hdlc_print(p, length); 1166 1167 if (xflag) 1168 default_print((const u_char *)(p + PPP_HDRLEN), 1169 caplen - PPP_HDRLEN); 1170 1171 putchar('\n'); 1172 } 1173 1174 void 1175 ppp_ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 1176 { 1177 u_int16_t pppoe_sid, pppoe_len; 1178 u_int l = h->caplen; 1179 u_int length = h->len; 1180 1181 packetp = p; 1182 snapend = p + l; 1183 1184 ts_print(&h->ts); 1185 1186 if (eflag) 1187 printf("PPPoE "); 1188 1189 if (l < sizeof(struct pppoe_header)) { 1190 printf("[|pppoe]"); 1191 return; 1192 } 1193 1194 pppoe_sid = EXTRACT_16BITS(p + 2); 1195 pppoe_len = EXTRACT_16BITS(p + 4); 1196 1197 if (eflag) { 1198 printf("\n\tcode "); 1199 switch (p[1]) { 1200 case PPPOE_CODE_PADI: 1201 printf("Initiation"); 1202 break; 1203 case PPPOE_CODE_PADO: 1204 printf("Offer"); 1205 break; 1206 case PPPOE_CODE_PADR: 1207 printf("Request"); 1208 break; 1209 case PPPOE_CODE_PADS: 1210 printf("Confirm"); 1211 break; 1212 case PPPOE_CODE_PADT: 1213 printf("Terminate"); 1214 break; 1215 case PPPOE_CODE_SESSION: 1216 printf("Session"); 1217 break; 1218 default: 1219 printf("Unknown(0x%02x)", p[1]); 1220 break; 1221 } 1222 printf(", version %d, type %d, id 0x%04x, length %d\n\t", 1223 (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); 1224 } 1225 1226 if (length < pppoe_len) { 1227 printf(" truncated-pppoe - %d bytes missing!", 1228 pppoe_len - length); 1229 pppoe_len = length; 1230 } 1231 1232 ppp_print(p + sizeof(struct pppoe_header), pppoe_len); 1233 1234 if (xflag) 1235 default_print(p, h->caplen); 1236 1237 putchar('\n'); 1238 } 1239 1240 int 1241 pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int l) 1242 { 1243 uint16_t pppoe_sid, pppoe_len; 1244 1245 if (ethertype == ETHERTYPE_PPPOEDISC) 1246 printf("PPPoE-Discovery"); 1247 else 1248 printf("PPPoE-Session"); 1249 1250 if (l < sizeof(struct pppoe_header)) 1251 goto trunc; 1252 1253 printf("\n\tcode "); 1254 switch (p[1]) { 1255 case PPPOE_CODE_PADI: 1256 printf("Initiation"); 1257 break; 1258 case PPPOE_CODE_PADO: 1259 printf("Offer"); 1260 break; 1261 case PPPOE_CODE_PADR: 1262 printf("Request"); 1263 break; 1264 case PPPOE_CODE_PADS: 1265 printf("Confirm"); 1266 break; 1267 case PPPOE_CODE_PADT: 1268 printf("Terminate"); 1269 break; 1270 case PPPOE_CODE_SESSION: 1271 printf("Session"); 1272 break; 1273 default: 1274 printf("Unknown(0x%02x)", p[1]); 1275 break; 1276 } 1277 1278 pppoe_sid = EXTRACT_16BITS(p + 2); 1279 pppoe_len = EXTRACT_16BITS(p + 4); 1280 printf(", version %d, type %d, id 0x%04x, length %d", 1281 (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); 1282 1283 p += sizeof(struct pppoe_header); 1284 l -= sizeof(struct pppoe_header); 1285 length -= sizeof(struct pppoe_header); 1286 1287 if (length < pppoe_len) { 1288 printf(" truncated-pppoe - %d bytes missing!", 1289 pppoe_len - length); 1290 pppoe_len = length; 1291 } 1292 1293 if (l > pppoe_len) 1294 l = pppoe_len; 1295 1296 if (ethertype == ETHERTYPE_PPPOEDISC) { 1297 while (l > 0) { 1298 u_int16_t t_type, t_len; 1299 1300 if (l < 4) 1301 goto trunc; 1302 t_type = EXTRACT_16BITS(p); 1303 t_len = EXTRACT_16BITS(p + 2); 1304 1305 p += 4; 1306 l -= 4; 1307 1308 if (l < t_len) 1309 goto trunc; 1310 1311 printf("\n\ttag "); 1312 switch (t_type) { 1313 case PPPOE_TAG_END_OF_LIST: 1314 printf("End-Of-List"); 1315 break; 1316 case PPPOE_TAG_SERVICE_NAME: 1317 printf("Service-Name"); 1318 break; 1319 case PPPOE_TAG_AC_NAME: 1320 printf("AC-Name"); 1321 break; 1322 case PPPOE_TAG_HOST_UNIQ: 1323 printf("Host-Uniq"); 1324 break; 1325 case PPPOE_TAG_AC_COOKIE: 1326 printf("AC-Cookie"); 1327 break; 1328 case PPPOE_TAG_VENDOR_SPEC: 1329 printf("Vendor-Specific"); 1330 break; 1331 case PPPOE_TAG_RELAY_SESSION: 1332 printf("Relay-Session"); 1333 break; 1334 case PPPOE_TAG_MAX_PAYLOAD: 1335 printf("PPP-Max-Payload"); 1336 break; 1337 case PPPOE_TAG_SERVICE_NAME_ERROR: 1338 printf("Service-Name-Error"); 1339 break; 1340 case PPPOE_TAG_AC_SYSTEM_ERROR: 1341 printf("AC-System-Error"); 1342 break; 1343 case PPPOE_TAG_GENERIC_ERROR: 1344 printf("Generic-Error"); 1345 break; 1346 default: 1347 printf("Unknown(0x%04x)", t_type); 1348 } 1349 printf(", length %u%s", t_len, t_len ? " " : ""); 1350 1351 if (t_len) { 1352 for (t_type = 0; t_type < t_len; t_type++) { 1353 if (isprint(p[t_type])) 1354 printf("%c", p[t_type]); 1355 else 1356 printf("\\%03o", p[t_type]); 1357 } 1358 } 1359 p += t_len; 1360 l -= t_len; 1361 } 1362 } else if (ethertype == ETHERTYPE_PPPOE) { 1363 printf("\n\t"); 1364 ppp_print(p, pppoe_len); 1365 } 1366 1367 return (1); 1368 1369 trunc: 1370 printf("[|pppoe]"); 1371 return (1); 1372 } 1373 1374 void 1375 ppp_hdlc_print(const u_char *p, u_int length) 1376 { 1377 uint8_t address, control; 1378 int l; 1379 1380 l = snapend - p; 1381 1382 if (l < sizeof(address) + sizeof(control)) 1383 goto trunc; 1384 1385 address = p[0]; 1386 control = p[1]; 1387 1388 p += sizeof(address) + sizeof(control); 1389 l -= sizeof(address) + sizeof(control); 1390 length -= sizeof(address) + sizeof(control); 1391 1392 switch (address) { 1393 case 0xff: /* All-Stations */ 1394 if (eflag) 1395 printf("%02x %02x %u ", address, control, length); 1396 1397 if (control != 0x3) { 1398 printf(" discard"); 1399 break; 1400 } 1401 1402 ppp_print(p, length); 1403 break; 1404 1405 default: 1406 printf("ppp address 0x%02x unknown", address); 1407 break; 1408 } 1409 return; 1410 1411 trunc: 1412 printf("[|ppp]"); 1413 } 1414 1415 void 1416 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h, 1417 const u_char *p) 1418 { 1419 int l = h->caplen; 1420 1421 packetp = p; 1422 snapend = p + l; 1423 1424 ts_print(&h->ts); 1425 1426 if (eflag) 1427 printf("PPP "); 1428 1429 ppp_hdlc_print(p, h->len); 1430 1431 if (xflag) 1432 default_print(p, l); 1433 1434 printf("\n"); 1435 } 1436 1437 #else 1438 1439 #include <sys/types.h> 1440 #include <sys/time.h> 1441 1442 #include <stdio.h> 1443 1444 #include "interface.h" 1445 void 1446 ppp_if_print(user, h, p) 1447 u_char *user; 1448 const struct pcap_pkthdr *h; 1449 const u_char *p; 1450 { 1451 error("not configured for ppp"); 1452 /* NOTREACHED */ 1453 } 1454 #endif 1455