1 /* $OpenBSD: print-ppp.c,v 1.13 2000/10/03 14:21:56 ho 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 #ifndef lint 25 static const char rcsid[] = 26 "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/print-ppp.c,v 1.13 2000/10/03 14:21:56 ho Exp $ (LBL)"; 27 #endif 28 29 #ifdef PPP 30 #include <sys/param.h> 31 #include <sys/time.h> 32 #include <sys/socket.h> 33 #include <sys/file.h> 34 #include <sys/ioctl.h> 35 36 #ifdef __STDC__ 37 struct mbuf; 38 struct rtentry; 39 #endif 40 #include <net/if.h> 41 42 #include <netinet/in.h> 43 #include <netinet/in_systm.h> 44 #include <netinet/ip.h> 45 46 #include <netipx/ipx.h> 47 #include <netipx/ipx_if.h> 48 49 #include <ctype.h> 50 #include <netdb.h> 51 #include <pcap.h> 52 #include <signal.h> 53 #include <stdio.h> 54 55 #include <netinet/if_ether.h> 56 #include "ethertype.h" 57 58 #include <net/ppp_defs.h> 59 #include "interface.h" 60 #include "addrtoname.h" 61 #include "extract.h" 62 63 struct protonames { 64 u_short protocol; 65 char *name; 66 }; 67 68 static struct protonames protonames[] = { 69 /* 70 * Protocol field values. 71 */ 72 { PPP_IP, "IP" }, /* Internet Protocol */ 73 { PPP_XNS, "XNS" }, /* Xerox NS */ 74 { PPP_IPX, "IPX" }, /* IPX Datagram (RFC1552) */ 75 { PPP_VJC_COMP, "VJC_UNCOMP" }, /* VJ compressed TCP */ 76 { PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */ 77 { PPP_COMP, "COMP" }, /* compressed packet */ 78 { PPP_IPCP, "IPCP" }, /* IP Control Protocol */ 79 { PPP_IPXCP, "IPXCP" }, /* IPX Control Protocol (RFC1552) */ 80 { PPP_CCP, "CCP" }, /* Compression Control Protocol */ 81 { PPP_LCP, "LCP" }, /* Link Control Protocol */ 82 { PPP_PAP, "PAP" }, /* Password Authentication Protocol */ 83 { PPP_LQR, "LQR" }, /* Link Quality Report protocol */ 84 { PPP_CHAP, "CHAP" }, /* Cryptographic Handshake Auth. Proto */ 85 }; 86 87 /* LCP */ 88 89 #define LCP_CONF_REQ 1 90 #define LCP_CONF_ACK 2 91 #define LCP_CONF_NAK 3 92 #define LCP_CONF_REJ 4 93 #define LCP_TERM_REQ 5 94 #define LCP_TERM_ACK 6 95 #define LCP_CODE_REJ 7 96 #define LCP_PROT_REJ 8 97 #define LCP_ECHO_REQ 9 98 #define LCP_ECHO_RPL 10 99 #define LCP_DISC_REQ 11 100 101 #define LCP_MIN LCP_CONF_REQ 102 #define LCP_MAX LCP_DISC_REQ 103 104 static char *lcpcodes[] = { 105 /* 106 * LCP code values (RFC1661, pp26) 107 */ 108 "Configure-Request", 109 "Configure-Ack", 110 "Configure-Nak", 111 "Configure-Reject", 112 "Terminate-Request", 113 "Terminate-Ack", 114 "Code-Reject", 115 "Protocol-Reject", 116 "Echo-Request", 117 "Echo-Reply", 118 "Discard-Request", 119 }; 120 121 #define LCPOPT_VEXT 0 122 #define LCPOPT_MRU 1 123 #define LCPOPT_ACCM 2 124 #define LCPOPT_AP 3 125 #define LCPOPT_QP 4 126 #define LCPOPT_MN 5 127 #define LCPOPT_PFC 7 128 #define LCPOPT_ACFC 8 129 130 #define LCPOPT_MIN 0 131 #define LCPOPT_MAX 24 132 133 static char *lcpconfopts[] = { 134 "Vendor-Ext", 135 "Max-Rx-Unit", 136 "Async-Ctrl-Char-Map", 137 "Auth-Prot", 138 "Quality-Prot", 139 "Magic-Number", 140 "unassigned (6)", 141 "Prot-Field-Compr", 142 "Add-Ctrl-Field-Compr", 143 "FCS-Alternatives", 144 "Self-Describing-Pad", 145 "Numbered-Mode", 146 "Multi-Link-Procedure", 147 "Call-Back", 148 "Connect-Time" 149 "Compund-Frames", 150 "Nominal-Data-Encap", 151 "Multilink-MRRU", 152 "Multilink-SSNHF", 153 "Multilink-ED", 154 "Proprietary", 155 "DCE-Identifier", 156 "Multilink-Plus-Proc", 157 "Link-Discriminator", 158 "LCP-Auth-Option", 159 }; 160 161 /* CHAP */ 162 163 #define CHAP_CHAL 1 164 #define CHAP_RESP 2 165 #define CHAP_SUCC 3 166 #define CHAP_FAIL 4 167 168 #define CHAP_CODEMIN 1 169 #define CHAP_CODEMAX 4 170 171 static char *chapcode[] = { 172 "Challenge", 173 "Response", 174 "Success", 175 "Failure", 176 }; 177 178 /* PAP */ 179 180 #define PAP_AREQ 1 181 #define PAP_AACK 2 182 #define PAP_ANAK 3 183 184 #define PAP_CODEMIN 1 185 #define PAP_CODEMAX 3 186 187 static char *papcode[] = { 188 "Authenticate-Request", 189 "Authenticate-Ack", 190 "Authenticate-Nak", 191 }; 192 193 /* IPCP */ 194 195 #define IPCP_CODE_CFG_REQ 1 196 #define IPCP_CODE_CFG_ACK 2 197 #define IPCP_CODE_CFG_NAK 3 198 #define IPCP_CODE_CFG_REJ 4 199 #define IPCP_CODE_TRM_REQ 5 200 #define IPCP_CODE_TRM_ACK 6 201 #define IPCP_CODE_COD_REJ 7 202 203 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ 204 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ 205 206 #define IPCP_2ADDR 1 207 #define IPCP_CP 2 208 #define IPCP_ADDR 3 209 210 static int print_lcp_config_options(u_char *p); 211 static void handle_lcp(const u_char *p, int length); 212 static void handle_chap(const u_char *p, int length); 213 static void handle_ipcp(const u_char *p, int length); 214 static void handle_pap(const u_char *p, int length); 215 216 struct pppoe_header { 217 u_int8_t vertype; /* PPPoE version/type */ 218 u_int8_t code; /* PPPoE code (packet type) */ 219 u_int16_t sessionid; /* PPPoE session id */ 220 u_int16_t len; /* PPPoE payload length */ 221 }; 222 #define PPPOE_CODE_SESSION 0x00 /* Session */ 223 #define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ 224 #define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ 225 #define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ 226 #define PPPOE_CODE_PADS 0x65 /* Active Discovery Session-Confirm */ 227 #define PPPOE_CODE_PADT 0xa7 /* Active Discovery Terminate */ 228 #define PPPOE_TAG_END_OF_LIST 0x0000 /* End Of List */ 229 #define PPPOE_TAG_SERVICE_NAME 0x0101 /* Service Name */ 230 #define PPPOE_TAG_AC_NAME 0x0102 /* Access Concentrator Name */ 231 #define PPPOE_TAG_HOST_UNIQ 0x0103 /* Host Uniq */ 232 #define PPPOE_TAG_AC_COOKIE 0x0104 /* Access Concentratr Cookie */ 233 #define PPPOE_TAG_VENDOR_SPEC 0x0105 /* Vendor Specific */ 234 #define PPPOE_TAG_RELAY_SESSION 0x0110 /* Relay Session Id */ 235 #define PPPOE_TAG_SERVICE_NAME_ERROR 0x0201 /* Service Name Error */ 236 #define PPPOE_TAG_AC_SYSTEM_ERROR 0x0202 /* Acc. Concentrator Error */ 237 #define PPPOE_TAG_GENERIC_ERROR 0x0203 /* Generic Error */ 238 239 void 240 ppp_hdlc_print(p, length) 241 const u_char *p; 242 int length; 243 { 244 int proto = PPP_PROTOCOL(p); 245 int i; 246 247 printf("ID-%03d ", *(p+5)); 248 249 for (i = sizeof(protonames) / sizeof(protonames[0]) - 1; i >= 0; i--) { 250 if (proto == protonames[i].protocol) { 251 printf("%s: ", protonames[i].name); 252 253 switch(proto) { 254 255 case PPP_LCP: 256 handle_lcp(p, length); 257 break; 258 case PPP_CHAP: 259 handle_chap(p, length); 260 break; 261 case PPP_PAP: 262 handle_pap(p, length); 263 break; 264 case PPP_IPCP: 265 handle_ipcp(p, length); 266 break; 267 } 268 break; 269 } 270 } 271 if (i < 0) 272 printf("%04x: ", proto); 273 } 274 275 /* print LCP frame */ 276 277 static void 278 handle_lcp(p, length) 279 const u_char *p; 280 int length; 281 { 282 int x, j; 283 u_char *ptr; 284 285 x = *(p + 4); 286 287 if ((x >= LCP_MIN) && (x <= LCP_MAX)) 288 printf("%s", lcpcodes[x-1]); 289 else { 290 printf("0x%02x", x); 291 return; 292 } 293 294 length -= 4; 295 296 switch(x) { 297 298 case LCP_CONF_REQ: 299 case LCP_CONF_ACK: 300 case LCP_CONF_NAK: 301 case LCP_CONF_REJ: 302 x = length; 303 ptr = (u_char *)p+8; 304 do { 305 if((j = print_lcp_config_options(ptr)) == 0) 306 break; 307 x -= j; 308 ptr += j; 309 } 310 while(x > 0); 311 break; 312 313 case LCP_ECHO_REQ: 314 case LCP_ECHO_RPL: 315 printf(", Magic-Number=%d", ((*(p+ 8) << 24) + (*(p+9) << 16) + 316 (*(p+10) << 8) + (*(p+11)))); 317 break; 318 case LCP_TERM_REQ: 319 case LCP_TERM_ACK: 320 case LCP_CODE_REJ: 321 case LCP_PROT_REJ: 322 case LCP_DISC_REQ: 323 default: 324 break; 325 } 326 } 327 328 /* LCP config options */ 329 330 static int 331 print_lcp_config_options(p) 332 u_char *p; 333 { 334 int len = *(p+1); 335 int opt = *p; 336 337 if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) 338 printf(", %s", lcpconfopts[opt]); 339 340 switch(opt) { 341 case LCPOPT_MRU: 342 if(len == 4) 343 printf("=%d", (*(p+2) << 8) + *(p+3)); 344 break; 345 case LCPOPT_AP: 346 if(len >= 4) { 347 if(*(p+2) == 0xc0 && *(p+3) == 0x23) 348 printf(" PAP"); 349 else if(*(p+2) == 0xc2 && *(p+3) == 0x23) { 350 printf(" CHAP/"); 351 switch(*(p+4)) { 352 default: 353 printf("unknown-algorithm-%d", *(p+4)); 354 break; 355 case 5: 356 printf("MD5"); 357 break; 358 case 0x80: 359 printf("Microsoft"); 360 break; 361 } 362 } else if(*(p+2) == 0xc2 && *(p+3) == 0x27) 363 printf(" EAP"); 364 else if(*(p+2) == 0xc0 && *(p+3) == 0x27) 365 printf(" SPAP"); 366 else if(*(p+2) == 0xc1 && *(p+3) == 0x23) 367 printf(" Old-SPAP"); 368 else 369 printf("unknown"); 370 } 371 break; 372 case LCPOPT_QP: 373 if(len >= 4) { 374 if(*(p+2) == 0xc0 && *(p+3) == 0x25) 375 printf(" LQR"); 376 else 377 printf(" unknown"); 378 } 379 break; 380 case LCPOPT_MN: 381 if(len == 6) 382 printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + 383 (*(p+4) << 8) + (*(p+5)))); 384 break; 385 case LCPOPT_PFC: 386 printf(" PFC"); 387 break; 388 case LCPOPT_ACFC: 389 printf(" ACFC"); 390 break; 391 } 392 return(len); 393 } 394 395 /* CHAP */ 396 397 static void 398 handle_chap(p, length) 399 const u_char *p; 400 int length; 401 { 402 int x; 403 u_char *ptr; 404 405 x = *(p+4); 406 407 if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX)) 408 printf("%s", chapcode[x-1]); 409 else { 410 printf("0x%02x", x); 411 return; 412 } 413 414 length -= 4; 415 416 switch(x) { 417 case CHAP_CHAL: 418 case CHAP_RESP: 419 printf(", Value="); 420 x = *(p+8); /* value size */ 421 ptr = (u_char *)p+9; 422 while(--x >= 0) 423 printf("%02x", *ptr++); 424 x = length - *(p+8) - 1; 425 printf(", Name="); 426 while(--x >= 0) 427 printf("%c", *ptr++); 428 break; 429 } 430 } 431 432 /* PAP */ 433 434 static void 435 handle_pap(p, length) 436 const u_char *p; 437 int length; 438 { 439 int x; 440 u_char *ptr; 441 442 x = *(p+4); 443 444 if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX)) 445 printf("%s", papcode[x-1]); 446 else { 447 printf("0x%02x", x); 448 return; 449 } 450 451 length -= 4; 452 453 switch(x) { 454 case PAP_AREQ: 455 printf(", Peer-Id="); 456 x = *(p+8); /* peerid size */ 457 ptr = (u_char *)p+9; 458 while(--x >= 0) 459 printf("%c", *ptr++); 460 x = *ptr++; 461 printf(", Passwd="); 462 while(--x >= 0) 463 printf("%c", *ptr++); 464 break; 465 case PAP_AACK: 466 case PAP_ANAK: 467 break; 468 } 469 } 470 471 /* IPCP */ 472 473 static void 474 handle_ipcp(p, length) 475 const u_char *p; 476 int length; 477 { 478 int x; 479 480 x = *(p+4); 481 482 if((x >= IPCP_CODE_MIN) && (x <= IPCP_CODE_MAX)) 483 printf("%s", lcpcodes[x-1]); /* share table with LCP */ 484 else { 485 printf("0x%02x", x); 486 return; 487 } 488 489 length -= 4; 490 491 switch(*(p+8)) { 492 case IPCP_2ADDR: 493 printf(", IP-Addresses"); 494 printf(", Src=%d.%d.%d.%d", 495 *(p+10), *(p+11), *(p+12), *(p+13)); 496 printf(", Dst=%d.%d.%d.%d", 497 *(p+14), *(p+15), *(p+16), *(p+17)); 498 break; 499 500 case IPCP_CP: 501 printf(", IP-Compression-Protocol"); 502 break; 503 504 case IPCP_ADDR: 505 printf(", IP-Address=%d.%d.%d.%d", 506 *(p+10), *(p+11), *(p+12), *(p+13)); 507 break; 508 default: 509 printf(", Unknown IPCP code 0x%x", *(p+8)); 510 break; 511 } 512 } 513 514 void 515 ppp_if_print(user, h, p) 516 u_char *user; 517 const struct pcap_pkthdr *h; 518 register const u_char *p; 519 { 520 register u_int length = h->len; 521 register u_int caplen = h->caplen; 522 523 ts_print(&h->ts); 524 525 if (caplen < PPP_HDRLEN) { 526 printf("[|ppp]"); 527 goto out; 528 } 529 530 /* 531 * Some printers want to get back at the link level addresses, 532 * and/or check that they're not walking off the end of the packet. 533 * Rather than pass them all the way down, we set these globals. 534 */ 535 packetp = p; 536 snapend = p + caplen; 537 538 if (eflag) 539 ppp_hdlc_print(p, length); 540 541 length -= PPP_HDRLEN; 542 543 switch(PPP_PROTOCOL(p)) { 544 case PPP_IP: 545 case ETHERTYPE_IP: 546 ip_print((const u_char *)(p + PPP_HDRLEN), length); 547 break; 548 case PPP_IPX: 549 case ETHERTYPE_IPX: 550 ipx_print((const u_char *)(p + PPP_HDRLEN), length); 551 break; 552 553 default: 554 if(!eflag) 555 ppp_hdlc_print(p, length); 556 if(!xflag) 557 default_print((const u_char *)(p + PPP_HDRLEN), 558 caplen - PPP_HDRLEN); 559 } 560 561 if (xflag) 562 default_print((const u_char *)(p + PPP_HDRLEN), 563 caplen - PPP_HDRLEN); 564 out: 565 putchar('\n'); 566 } 567 568 int 569 pppoe_if_print(ethertype, p, length, caplen) 570 u_short ethertype; 571 const u_char *p; 572 u_int length, caplen; 573 { 574 u_int16_t pppoe_sid, pppoe_len; 575 576 if (ethertype == ETHERTYPE_PPPOEDISC) 577 printf("PPPoE-Discovery"); 578 else 579 printf("PPPoE-Session"); 580 581 if (length < sizeof(sizeof(struct pppoe_header))) { 582 printf("[|pppoe]"); 583 return (1); 584 } 585 586 printf("\n\tcode "); 587 switch (p[1]) { 588 case PPPOE_CODE_PADI: 589 printf("Initiation"); 590 break; 591 case PPPOE_CODE_PADO: 592 printf("Offer"); 593 break; 594 case PPPOE_CODE_PADR: 595 printf("Request"); 596 break; 597 case PPPOE_CODE_PADS: 598 printf("Confirm"); 599 break; 600 case PPPOE_CODE_PADT: 601 printf("Terminate"); 602 break; 603 case PPPOE_CODE_SESSION: 604 printf("Session"); 605 break; 606 default: 607 printf("Unknown(0x%02x)", p[1]); 608 break; 609 } 610 611 pppoe_sid = EXTRACT_16BITS(p + 2); 612 pppoe_len = EXTRACT_16BITS(p + 4); 613 printf(", version %d, type %d, id 0x%04x, length %d", 614 (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len); 615 616 length -= sizeof(struct pppoe_header); 617 caplen -= sizeof(struct pppoe_header); 618 p += sizeof(struct pppoe_header); 619 620 if (pppoe_len > caplen) 621 pppoe_len = caplen; 622 623 if (ethertype == ETHERTYPE_PPPOEDISC) { 624 while (pppoe_len > 0) { 625 u_int16_t t_type, t_len; 626 627 if (pppoe_len < 4) { 628 printf("\n\t[|pppoe]"); 629 break; 630 } 631 t_type = EXTRACT_16BITS(p); 632 t_len = EXTRACT_16BITS(p + 2); 633 634 pppoe_len -= 4; 635 p += 4; 636 637 if (pppoe_len < t_len) { 638 printf("\n\t[|pppoe]"); 639 break; 640 } 641 642 printf("\n\ttag "); 643 switch (t_type) { 644 case PPPOE_TAG_END_OF_LIST: 645 printf("End-Of-List"); 646 break; 647 case PPPOE_TAG_SERVICE_NAME: 648 printf("Service-Name"); 649 break; 650 case PPPOE_TAG_AC_NAME: 651 printf("AC-Name"); 652 break; 653 case PPPOE_TAG_HOST_UNIQ: 654 printf("Host-Uniq"); 655 break; 656 case PPPOE_TAG_AC_COOKIE: 657 printf("AC-Cookie"); 658 break; 659 case PPPOE_TAG_VENDOR_SPEC: 660 printf("Vendor-Specific"); 661 break; 662 case PPPOE_TAG_RELAY_SESSION: 663 printf("Relay-Session"); 664 break; 665 case PPPOE_TAG_SERVICE_NAME_ERROR: 666 printf("Service-Name-Error"); 667 break; 668 case PPPOE_TAG_AC_SYSTEM_ERROR: 669 printf("AC-System-Error"); 670 break; 671 case PPPOE_TAG_GENERIC_ERROR: 672 printf("Generic-Error"); 673 break; 674 default: 675 printf("Unknown(0x%04x)", t_type); 676 } 677 printf(", length %u%s", t_len, t_len ? " " : ""); 678 679 if (t_len) { 680 for (t_type = 0; t_type < t_len; t_type++) { 681 if (isprint(p[t_type])) 682 printf("%c", p[t_type]); 683 else 684 printf("\\%03o", p[t_type]); 685 } 686 } 687 pppoe_len -= t_len; 688 p += t_len; 689 } 690 } 691 else if (ethertype == ETHERTYPE_PPPOE) { 692 u_int16_t proto; 693 int i; 694 695 if (pppoe_len < 2) { 696 printf("[|pppoe]"); 697 return (1); 698 } 699 proto = EXTRACT_16BITS(p); 700 701 for (i = sizeof(protonames)/sizeof(protonames[0]) - 1; i >= 0; 702 i--) { 703 if (proto == protonames[i].protocol) { 704 printf("\n\t%s: ", protonames[i].name); 705 switch (proto) { 706 case PPP_LCP: 707 handle_lcp(p - 2, pppoe_len + 2); 708 break; 709 case PPP_CHAP: 710 handle_chap(p - 2, pppoe_len + 2); 711 break; 712 case PPP_PAP: 713 handle_pap(p - 2, pppoe_len + 2); 714 break; 715 case PPP_IPCP: 716 handle_ipcp(p - 2, pppoe_len + 2); 717 break; 718 case PPP_IP: 719 ip_print(p + 2, pppoe_len - 2); 720 break; 721 case PPP_IPX: 722 ipx_print(p + 2, pppoe_len - 2); 723 } 724 break; 725 } 726 } 727 if (i < 0) 728 printf("\n\t%04x: ", proto); 729 } 730 731 return (1); 732 } 733 734 #else 735 736 #include <sys/types.h> 737 #include <sys/time.h> 738 739 #include <stdio.h> 740 741 #include "interface.h" 742 void 743 ppp_if_print(user, h, p) 744 u_char *user; 745 const struct pcap_pkthdr *h; 746 const u_char *p; 747 { 748 error("not configured for ppp"); 749 /* NOTREACHED */ 750 } 751 #endif 752