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