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