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