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