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