print-ppp.c revision 53146
1193326Sed/* 2193326Sed * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3193326Sed * The Regents of the University of California. All rights reserved. 4193326Sed * 5193326Sed * Redistribution and use in source and binary forms, with or without 6193326Sed * modification, are permitted provided that: (1) source code distributions 7193326Sed * retain the above copyright notice and this paragraph in its entirety, (2) 8193326Sed * distributions including binary code include the above copyright notice and 9193326Sed * this paragraph in its entirety in the documentation or other materials 10193326Sed * provided with the distribution, and (3) all advertising materials mentioning 11193326Sed * features or use of this software display the following acknowledgement: 12193326Sed * ``This product includes software developed by the University of California, 13193326Sed * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14193326Sed * the University nor the names of its contributors may be used to endorse 15249423Sdim * or promote products derived from this software without specific prior 16193326Sed * written permission. 17212904Sdim * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18212904Sdim * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19193326Sed * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20198398Srdivacky * 21193326Sed * $FreeBSD: head/contrib/tcpdump/print-ppp.c 53146 1999-11-14 11:28:11Z brian $ 22193326Sed */ 23193326Sed 24234353Sdim#ifndef lint 25234353Sdimstatic const char rcsid[] = 26234353Sdim "@(#) $Header: print-ppp.c,v 1.26 97/06/12 14:21:29 leres Exp $ (LBL)"; 27234353Sdim#endif 28234353Sdim 29234353Sdim#include <sys/param.h> 30234353Sdim#include <sys/time.h> 31234353Sdim#include <sys/socket.h> 32193326Sed#include <sys/file.h> 33234353Sdim#include <sys/ioctl.h> 34234353Sdim 35234353Sdim#if __STDC__ 36249423Sdimstruct mbuf; 37193326Sedstruct rtentry; 38234353Sdim#endif 39234353Sdim#include <net/if.h> 40234353Sdim 41234353Sdim#include <netinet/in.h> 42234353Sdim#include <netinet/in_systm.h> 43234353Sdim#include <netinet/ip.h> 44234353Sdim 45234353Sdim#include <ctype.h> 46234353Sdim#include <netdb.h> 47234353Sdim#include <pcap.h> 48234353Sdim#include <stdio.h> 49234353Sdim 50234353Sdim#include <net/ethernet.h> 51234353Sdim#include "ethertype.h" 52234353Sdim 53234353Sdim#include <net/ppp_defs.h> 54234353Sdim#include "interface.h" 55234353Sdim#include "addrtoname.h" 56234353Sdim#include "ppp.h" 57234353Sdim 58234353Sdimstruct protonames { 59234353Sdim u_short protocol; 60234353Sdim char *name; 61234353Sdim}; 62234353Sdim 63234353Sdimstatic struct protonames protonames[] = { 64193326Sed /* 65193326Sed * Protocol field values. 66193326Sed */ 67234353Sdim PPP_IP, "IP", /* Internet Protocol */ 68234353Sdim PPP_XNS, "XNS", /* Xerox NS */ 69276479Sdim PPP_IPX, "IPX", /* IPX Datagram (RFC1552) */ 70234353Sdim PPP_VJC_COMP, "VJC_UNCOMP", /* VJ compressed TCP */ 71276479Sdim PPP_VJC_UNCOMP, "VJC_UNCOMP", /* VJ uncompressed TCP */ 72276479Sdim PPP_COMP, "COMP", /* compressed packet */ 73276479Sdim PPP_IPCP, "IPCP", /* IP Control Protocol */ 74276479Sdim PPP_IPXCP, "IPXCP", /* IPX Control Protocol (RFC1552) */ 75276479Sdim PPP_CCP, "CCP", /* Compression Control Protocol */ 76276479Sdim PPP_LCP, "LCP", /* Link Control Protocol */ 77276479Sdim PPP_PAP, "PAP", /* Password Authentication Protocol */ 78276479Sdim PPP_LQR, "LQR", /* Link Quality Report protocol */ 79276479Sdim PPP_CHAP, "CHAP", /* Cryptographic Handshake Auth. Proto*/ 80234353Sdim}; 81276479Sdim 82276479Sdim/* LCP */ 83276479Sdim 84276479Sdim#define LCP_CONF_REQ 1 85276479Sdim#define LCP_CONF_ACK 2 86276479Sdim#define LCP_CONF_NAK 3 87276479Sdim#define LCP_CONF_REJ 4 88276479Sdim#define LCP_TERM_REQ 5 89276479Sdim#define LCP_TERM_ACK 6 90276479Sdim#define LCP_CODE_REJ 7 91276479Sdim#define LCP_PROT_REJ 8 92193326Sed#define LCP_ECHO_REQ 9 93193326Sed#define LCP_ECHO_RPL 10 94207619Srdivacky#define LCP_DISC_REQ 11 95207619Srdivacky 96207619Srdivacky#define LCP_MIN LCP_CONF_REQ 97207619Srdivacky#define LCP_MAX LCP_DISC_REQ 98207619Srdivacky 99207619Srdivackystatic char *lcpcodes[] = { 100207619Srdivacky /* 101207619Srdivacky * LCP code values (RFC1661, pp26) 102207619Srdivacky */ 103207619Srdivacky "Configure-Request", 104207619Srdivacky "Configure-Ack", 105207619Srdivacky "Configure-Nak", 106207619Srdivacky "Configure-Reject", 107193326Sed "Terminate-Request", 108193326Sed "Terminate-Ack", 109193326Sed "Code-Reject", 110193326Sed "Protocol-Reject", 111193326Sed "Echo-Request", 112193326Sed "Echo-Reply", 113193326Sed "Discard-Request", 114193326Sed}; 115193326Sed 116193326Sed#define LCPOPT_VEXT 0 117193326Sed#define LCPOPT_MRU 1 118193326Sed#define LCPOPT_ACCM 2 119193326Sed#define LCPOPT_AP 3 120193326Sed#define LCPOPT_QP 4 121193326Sed#define LCPOPT_MN 5 122193326Sed#define LCPOPT_PFC 7 123193326Sed#define LCPOPT_ACFC 8 124193326Sed 125193326Sed#define LCPOPT_MIN 0 126193326Sed#define LCPOPT_MAX 24 127193326Sed 128193326Sedstatic char *lcpconfopts[] = { 129193326Sed "Vendor-Ext", 130193326Sed "Max-Rx-Unit", 131212904Sdim "Async-Ctrl-Char-Map", 132193326Sed "Auth-Prot", 133193326Sed "Quality-Prot", 134193326Sed "Magic-Number", 135193326Sed "unassigned (6)", 136193326Sed "Prot-Field-Compr", 137193326Sed "Add-Ctrl-Field-Compr", 138193326Sed "FCS-Alternatives", 139193326Sed "Self-Describing-Pad", 140234353Sdim "Numbered-Mode", 141198398Srdivacky "Multi-Link-Procedure", 142198398Srdivacky "Call-Back", 143193326Sed "Connect-Time", 144193326Sed "Compund-Frames", 145198092Srdivacky "Nominal-Data-Encap", 146193326Sed "Multilink-MRRU", 147193326Sed "Multilink-SSNHF", 148193326Sed "Multilink-ED", 149226633Sdim "Proprietary", 150206084Srdivacky "DCE-Identifier", 151288943Sdim "Multilink-Plus-Proc", 152193326Sed "Link-Discriminator", 153193326Sed "LCP-Auth-Option", 154193326Sed}; 155198092Srdivacky 156193326Sed/* CHAP */ 157193326Sed 158198092Srdivacky#define CHAP_CHAL 1 159193326Sed#define CHAP_RESP 2 160193326Sed#define CHAP_SUCC 3 161193326Sed#define CHAP_FAIL 4 162193326Sed 163198092Srdivacky#define CHAP_CODEMIN 1 164193326Sed#define CHAP_CODEMAX 4 165193326Sed 166193326Sedstatic char *chapcode[] = { 167193326Sed "Challenge", 168193326Sed "Response", 169198092Srdivacky "Success", 170193326Sed "Failure", 171193326Sed}; 172193326Sed 173193326Sed/* PAP */ 174198092Srdivacky 175193326Sed#define PAP_AREQ 1 176193326Sed#define PAP_AACK 2 177193326Sed#define PAP_ANAK 3 178193326Sed 179193326Sed#define PAP_CODEMIN 1 180198092Srdivacky#define PAP_CODEMAX 3 181193326Sed 182193326Sedstatic char *papcode[] = { 183198092Srdivacky "Authenticate-Request", 184193326Sed "Authenticate-Ack", 185193326Sed "Authenticate-Nak", 186193326Sed}; 187193326Sed 188193326Sed/* IPCP */ 189193326Sed 190193326Sed#define IPCP_2ADDR 1 191193326Sed#define IPCP_CP 2 192193326Sed#define IPCP_ADDR 3 193193326Sed 194193326Sed/* PPPoE */ 195193326Sed 196234353Sdimstruct typenames { 197234353Sdim u_short type; 198234353Sdim char *name; 199234353Sdim}; 200234353Sdim 201218893Sdimstatic struct typenames typenames[] = { 202218893Sdim /* 203226633Sdim * PPPoE type field values 204226633Sdim */ 205226633Sdim 0x00, "DATA", /* PPPoE Data packet */ 206226633Sdim 0x09, "PADI", /* Active Discovery Initiation */ 207212904Sdim 0x07, "PADO", /* Active Discovery Offer */ 208198092Srdivacky 0x19, "PADR", /* Active Discovery Request */ 209207619Srdivacky 0x65, "PADS", /* Active Discovery Session-Confirm */ 210207619Srdivacky 0xa7, "PADT", /* Active Discovery Terminate */ 211207619Srdivacky}; 212207619Srdivacky 213234353Sdimstruct tagnames { 214207619Srdivacky u_short tag; 215207619Srdivacky char *name; 216218893Sdim int isascii; 217218893Sdim}; 218207619Srdivacky 219207619Srdivackystatic struct tagnames tagnames[] = { 220212904Sdim /* 221212904Sdim * PPPoE tag field values 222276479Sdim */ 223207619Srdivacky 0x0000, "End-Of-List", 0, /* Optional last tag (len 0) */ 224193326Sed 0x0101, "Service-Name", 1, /* The (ascii) service */ 225207619Srdivacky 0x0102, "AC-Name", -1, /* Access Concentrator */ 226207619Srdivacky 0x0103, "Host-Uniq", 0, /* Associate PAD[OS] with PAD[IR] */ 227207619Srdivacky 0x0104, "AC-Cookie", 0, /* Optional at PADO time */ 228207619Srdivacky 0x0105, "Vendor-Specific", 0, /* First 4 bytes special (ignore) */ 229261991Sdim 0x0110, "Relay-Session-Id", 0, /* Max 12 octets, added by gateway */ 230207619Srdivacky 0x0201, "Service-Name-Error", -1, /* Request not honoured */ 231207619Srdivacky 0x0203, "Generic-Error", 1 /* Access Concentrator error */ 232207619Srdivacky}; 233207619Srdivacky 234207619Srdivackystatic int handle_lcp(const u_char *p, int length); 235207619Srdivackystatic int print_lcp_config_options(u_char *p); 236207619Srdivackystatic int handle_chap(const u_char *p, int length); 237207619Srdivackystatic int handle_ipcp(const u_char *p, int length); 238207619Srdivackystatic int handle_pap(const u_char *p, int length); 239212904Sdimstatic void do_ppp_print(const u_char *p, u_int length, u_int caplen); 240276479Sdim 241207619Srdivacky/* Standard PPP printer */ 242207619Srdivackyvoid 243207619Srdivackyppp_hdlc_print(const u_char *p, int length) 244207619Srdivacky{ 245207619Srdivacky int proto = PPP_PROTOCOL(p); 246207619Srdivacky int i, j, x; 247212904Sdim u_char *ptr; 248234353Sdim 249207619Srdivacky printf("ID-%03d ", *(p+5)); 250207619Srdivacky 251212904Sdim for (i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i) 252207619Srdivacky { 253207619Srdivacky if (proto == protonames[i].protocol) 254207619Srdivacky { 255288943Sdim printf("%s: ", protonames[i].name); 256288943Sdim 257288943Sdim switch(proto) 258212904Sdim { 259288943Sdim case PPP_LCP: 260288943Sdim handle_lcp(p, length); 261288943Sdim break; 262288943Sdim case PPP_CHAP: 263288943Sdim handle_chap(p, length); 264288943Sdim break; 265212904Sdim case PPP_PAP: 266207619Srdivacky handle_pap(p, length); 267207619Srdivacky break; 268207619Srdivacky case PPP_IPCP: 269261991Sdim handle_ipcp(p, length); 270207619Srdivacky break; 271207619Srdivacky } 272207619Srdivacky break; 273288943Sdim } 274288943Sdim } 275288943Sdim if (i < 0) 276288943Sdim { 277288943Sdim printf("%04x: ", proto); 278288943Sdim } 279288943Sdim} 280288943Sdim 281288943Sdim/* print LCP frame */ 282288943Sdim 283288943Sdimstatic int 284288943Sdimhandle_lcp(const u_char *p, int length) 285288943Sdim{ 286288943Sdim int x, j; 287288943Sdim u_char *ptr; 288288943Sdim 289207619Srdivacky x = *(p+4); 290207619Srdivacky 291276479Sdim if((x >= LCP_MIN) && (x <= LCP_MAX)) 292207619Srdivacky { 293212904Sdim printf("%s", lcpcodes[x-1]); 294207619Srdivacky } 295207619Srdivacky else 296207619Srdivacky { 297207619Srdivacky printf("0x%02x", x); 298207619Srdivacky return; 299193326Sed } 300193326Sed 301207619Srdivacky length -= 4; 302207619Srdivacky 303193326Sed switch(x) 304193326Sed { 305193326Sed case LCP_CONF_REQ: 306207619Srdivacky case LCP_CONF_ACK: 307207619Srdivacky case LCP_CONF_NAK: 308207619Srdivacky case LCP_CONF_REJ: 309207619Srdivacky x = length; 310207619Srdivacky ptr = (u_char *)p+8; 311261991Sdim do 312243830Sdim { 313207619Srdivacky if((j = print_lcp_config_options(ptr)) == 0) 314193326Sed break; 315198092Srdivacky x -= j; 316193326Sed ptr += j; 317193326Sed } 318198092Srdivacky while(x > 0); 319193326Sed break; 320234353Sdim 321193326Sed case LCP_ECHO_REQ: 322207619Srdivacky case LCP_ECHO_RPL: 323193326Sed printf(", Magic-Number=%d", ((*(p+8) << 24) + (*(p+9) << 16) + (*(p+10) << 8) + (*(p+11)))); 324193326Sed break; 325212904Sdim case LCP_TERM_REQ: 326276479Sdim case LCP_TERM_ACK: 327193326Sed case LCP_CODE_REJ: 328193326Sed case LCP_PROT_REJ: 329193326Sed case LCP_DISC_REQ: 330193326Sed default: 331276479Sdim break; 332193326Sed } 333193326Sed} 334193326Sed 335193326Sed/* LCP config options */ 336193326Sed 337212904Sdimstatic int 338193326Sedprint_lcp_config_options(u_char *p) 339261991Sdim{ 340243830Sdim int len = *(p+1); 341193326Sed int opt = *p; 342276479Sdim 343276479Sdim if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) 344193326Sed printf(", %s", lcpconfopts[opt]); 345193326Sed 346193326Sed switch(opt) 347226633Sdim { 348226633Sdim case LCPOPT_MRU: 349226633Sdim if(len == 4) 350193326Sed printf("=%d", (*(p+2) << 8) + *(p+3)); 351193326Sed break; 352193326Sed case LCPOPT_AP: 353193326Sed if(len >= 4) 354193326Sed { 355193326Sed if(*(p+2) == 0xc0 && *(p+3) == 0x23) 356193326Sed { 357193326Sed printf(" PAP"); 358193326Sed } 359193326Sed else if(*(p+2) == 0xc2 && *(p+3) == 0x23) 360193326Sed { 361193326Sed printf(" CHAP/"); 362193326Sed switch(*(p+4)) 363193326Sed { 364193326Sed default: 365193326Sed printf("unknown-algorithm-%d", *(p+4)); 366193326Sed break; 367193326Sed case 5: 368193326Sed printf("MD5"); 369198092Srdivacky break; 370193326Sed case 0x80: 371193326Sed printf("Microsoft"); 372193326Sed break; 373206084Srdivacky } 374193326Sed } 375193326Sed else if(*(p+2) == 0xc2 && *(p+3) == 0x27) 376193326Sed { 377193326Sed printf(" EAP"); 378193326Sed } 379193326Sed else if(*(p+2) == 0xc0 && *(p+3) == 0x27) 380193326Sed { 381193326Sed printf(" SPAP"); 382193326Sed } 383193326Sed else if(*(p+2) == 0xc1 && *(p+3) == 0x23) 384193326Sed { 385193326Sed printf(" Old-SPAP"); 386193326Sed } 387193326Sed else 388193326Sed { 389193326Sed printf("unknown"); 390193326Sed } 391193326Sed } 392218893Sdim break; 393218893Sdim case LCPOPT_QP: 394193326Sed if(len >= 4) 395212904Sdim { 396218893Sdim if(*(p+2) == 0xc0 && *(p+3) == 0x25) 397218893Sdim printf(" LQR"); 398226633Sdim else 399226633Sdim printf(" unknown"); 400226633Sdim } 401193326Sed break; 402193326Sed case LCPOPT_MN: 403193326Sed if(len == 6) 404243830Sdim { 405193326Sed printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + (*(p+4) << 8) + (*(p+5)))); 406193326Sed } 407193326Sed break; 408234353Sdim case LCPOPT_PFC: 409193326Sed printf(" PFC"); 410193326Sed break; 411251662Sdim case LCPOPT_ACFC: 412193326Sed printf(" ACFC"); 413193326Sed break; 414193326Sed } 415193326Sed return(len); 416193326Sed} 417234353Sdim 418234353Sdim/* CHAP */ 419234353Sdim 420234353Sdimstatic int 421234353Sdimhandle_chap(const u_char *p, int length) 422234353Sdim{ 423234353Sdim int x, j; 424234353Sdim u_char *ptr; 425234353Sdim 426234353Sdim x = *(p+4); 427234353Sdim 428193326Sed if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX)) 429193326Sed { 430193326Sed printf("%s", chapcode[x-1]); 431193326Sed } 432212904Sdim else 433234353Sdim { 434193326Sed printf("0x%02x", x); 435193326Sed return; 436193326Sed } 437198092Srdivacky 438218893Sdim length -= 4; 439218893Sdim 440280031Sdim switch(x) 441280031Sdim { 442280031Sdim case CHAP_CHAL: 443193326Sed case CHAP_RESP: 444280031Sdim printf(", Value="); 445276479Sdim x = *(p+8); /* value size */ 446193326Sed ptr = (u_char *)p+9; 447193326Sed while(--x >= 0) 448198092Srdivacky printf("%02x", *ptr++); 449193326Sed x = length - *(p+8) - 1; 450221345Sdim printf(", Name="); 451193326Sed while(--x >= 0) 452193326Sed printf("%c", *ptr++); 453193326Sed break; 454193326Sed } 455193326Sed} 456193326Sed 457193326Sed/* PAP */ 458261991Sdim 459193326Sedstatic int 460193326Sedhandle_pap(const u_char *p, int length) 461193326Sed{ 462193326Sed int x, j; 463193326Sed u_char *ptr; 464193326Sed 465193326Sed x = *(p+4); 466193326Sed 467193326Sed if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX)) 468193326Sed { 469193326Sed printf("%s", papcode[x-1]); 470193326Sed } 471193326Sed else 472226633Sdim { 473226633Sdim printf("0x%02x", x); 474226633Sdim return; 475226633Sdim } 476243830Sdim 477226633Sdim length -= 4; 478193326Sed 479193326Sed switch(x) 480193326Sed { 481193326Sed case PAP_AREQ: 482234353Sdim printf(", Peer-Id="); 483234353Sdim x = *(p+8); /* peerid size */ 484234353Sdim ptr = (u_char *)p+9; 485234353Sdim while(--x >= 0) 486234353Sdim printf("%c", *ptr++); 487234353Sdim x = *ptr++; 488234353Sdim printf(", Passwd="); 489234353Sdim while(--x >= 0) 490234353Sdim printf("%c", *ptr++); 491234353Sdim break; 492234353Sdim case PAP_AACK: 493234353Sdim case PAP_ANAK: 494276479Sdim break; 495234353Sdim } 496234353Sdim} 497234353Sdim 498234353Sdim/* IPCP */ 499234353Sdim 500234353Sdimstatic int 501234353Sdimhandle_ipcp(const u_char *p, int length) 502234353Sdim{ 503234353Sdim int x, j; 504234353Sdim 505234353Sdim x = *(p+8); 506234353Sdim 507234353Sdim length -= 4; 508234353Sdim 509234353Sdim switch(x) 510234353Sdim { 511234353Sdim case IPCP_2ADDR: 512234353Sdim printf("IP-Addresses"); 513276479Sdim printf(", Src=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13)); 514234353Sdim printf(", Dst=%d.%d.%d.%d", *(p+14), *(p+15), *(p+16), *(p+17)); 515234353Sdim break; 516234353Sdim 517234353Sdim case IPCP_CP: 518234353Sdim printf("IP-Compression-Protocol"); 519234353Sdim break; 520234353Sdim 521234353Sdim case IPCP_ADDR: 522234353Sdim printf("IP-Address=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13)); 523234353Sdim break; 524234353Sdim } 525234353Sdim} 526234353Sdim 527234353Sdimvoid 528276479Sdimppp_if_print(u_char *user, const struct pcap_pkthdr *h, 529234353Sdim register const u_char *p) 530234353Sdim{ 531234353Sdim register u_int length = h->len; 532234353Sdim register u_int caplen = h->caplen; 533234353Sdim 534234353Sdim ts_print(&h->ts); 535234353Sdim 536234353Sdim if (caplen < PPP_HDRLEN) { 537234353Sdim puts("[|ppp]"); 538234353Sdim return; 539234353Sdim } 540234353Sdim 541234353Sdim /* 542234353Sdim * Some printers want to get back at the link level addresses, 543234353Sdim * and/or check that they're not walking off the end of the packet. 544234353Sdim * 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 */ 555void 556pppoe_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 p += 4; 592 length -= 4; 593 if (len > length) 594 len = length; /* puke ! */ 595 /* This is a data packet */ 596 fputs("] ", stdout); 597 do_ppp_print(p, len, len); 598 return; 599 } 600 601 p += 6; 602 length -= 6; 603 if (len > length) 604 len = length; /* puke ! */ 605 606 /* 607 * A PPPoE tag: 608 * 609 * 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 610 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 611 * | TAG_TYPE | TAG_LENGTH | 612 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 613 * | TAG_VALUE ... ~ 614 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 615 */ 616 617 while (len >= 4) { 618 tag = ntohs(*(u_short *)p); 619 tlen = ntohs(*(u_short *)(p + 2)); 620 621 fputs(" [", stdout); 622 for (f = sizeof tagnames / sizeof tagnames[0] - 1; f >= 0; f--) 623 if (tagnames[f].tag == tag) { 624 asc = tagnames[f].isascii; 625 fputs(tagnames[f].name, stdout); 626 break; 627 } 628 629 if (f == -1) { 630 printf("<0x%04x>", tag); 631 asc = -1; 632 } 633 634 p += 4; 635 if (tlen > 0) { 636 if (asc == -1) { 637 for (f = 0; f < tlen; f++) 638 if (!isascii(p[f])) 639 break; 640 asc = f == tlen; 641 } 642 fputc(' ', stdout); 643 if (asc) 644 printf("%.*s", (int)tlen, p); 645 else for (f = 0; f < tlen; f++) 646 printf("%02x", p[f]); 647 } 648 fputc(']', stdout); 649 650 p += tlen; 651 len -= tlen + 4; 652 } 653} 654 655/* 656 * Actually do the job 657 */ 658static void 659do_ppp_print(const u_char *p, u_int length, u_int caplen) 660{ 661 if (eflag) 662 ppp_hdlc_print(p, length); 663 664 length -= PPP_HDRLEN; 665 666 switch(PPP_PROTOCOL(p)) { 667 case PPP_IP: 668 case ETHERTYPE_IP: 669 ip_print((const u_char *)(p + PPP_HDRLEN), length); 670 break; 671 case PPP_IPX: 672 case ETHERTYPE_IPX: 673 ipx_print((const u_char *)(p + PPP_HDRLEN), length); 674 break; 675 676 default: 677 if(!eflag) 678 ppp_hdlc_print(p, length); 679 if(!xflag) 680 default_print((const u_char *)(p + PPP_HDRLEN), 681 caplen - PPP_HDRLEN); 682 } 683 684 if (xflag) 685 default_print((const u_char *)(p + PPP_HDRLEN), 686 caplen - PPP_HDRLEN); 687out: 688 putchar('\n'); 689} 690 691/* proto type to string mapping */ 692static struct tok ptype2str[] = { 693 { PPP_VJC, "VJC" }, 694 { PPP_VJNC, "VJNC" }, 695 { PPP_OSI, "OSI" }, 696 { PPP_LCP, "LCP" }, 697 { PPP_IPCP, "IPCP" }, 698 { 0, NULL } 699}; 700 701#define PPP_BSDI_HDRLEN 24 702 703/* BSD/OS specific PPP printer */ 704void 705ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, 706 register const u_char *p) 707{ 708 register u_int length = h->len; 709 register u_int caplen = h->caplen; 710 register int hdrlength; 711 u_short ptype; 712 713 ts_print(&h->ts); 714 715 if (caplen < PPP_BSDI_HDRLEN) { 716 printf("[|ppp]"); 717 goto out; 718 } 719 720 /* 721 * Some printers want to get back at the link level addresses, 722 * and/or check that they're not walking off the end of the packet. 723 * Rather than pass them all the way down, we set these globals. 724 */ 725 packetp = p; 726 snapend = p + caplen; 727 hdrlength = 0; 728 729 if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { 730 if (eflag) 731 printf("%02x %02x ", p[0], p[1]); 732 p += 2; 733 hdrlength = 2; 734 } 735 736 if (eflag) 737 printf("%d ", length); 738 /* Retrieve the protocol type */ 739 if (*p & 01) { 740 /* Compressed protocol field */ 741 ptype = *p; 742 if (eflag) 743 printf("%02x ", ptype); 744 p++; 745 hdrlength += 1; 746 } else { 747 /* Un-compressed protocol field */ 748 ptype = ntohs(*(u_short *)p); 749 if (eflag) 750 printf("%04x ", ptype); 751 p += 2; 752 hdrlength += 2; 753 } 754 755 length -= hdrlength; 756 757 if (ptype == PPP_IP) 758 ip_print(p, length); 759 else 760 printf("%s ", tok2str(ptype2str, "proto-#%d", ptype)); 761 762 if (xflag) 763 default_print((const u_char *)p, caplen - hdrlength); 764out: 765 putchar('\n'); 766} 767