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