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