/* * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint static const char rcsid[] = "@(#) $Original-Header: print-ppp.c,v 1.26 97/06/12 14:21:29 leres Exp $ (LBL)"; #endif /* * modified by Hellmuth Michaelis (hm@kts.org): * * 08/98: enhanced PPP protocol printing for LCP/IPCP/PAP/CHAP * 07/99: removed my bugs from last year, more PPP enhancements * * last edit-date: [Sun Jul 25 10:25:49 1999] * * $Id: print-ppp.c,v 1.3 1999/07/25 08:23:46 hm Exp $ */ #include #include #include #include #include #if __STDC__ struct mbuf; struct rtentry; #endif #include #include #include #include #include #include #include #include #include #include "ethertype.h" #include #include "interface.h" #include "addrtoname.h" #include "ppp.h" struct protonames { u_short protocol; char *name; }; static struct protonames protonames[] = { /* * Protocol field values, Fri Jul 23 11:21:38 CEST 1999 from * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers */ 0x0001, "PP", /* Padding Protocol */ 0x0021, "IP", /* Internet Protocol version 4 */ 0x0023, "OSINL", /* OSI Network Layer */ 0x0025, "XNSI", /* Xerox NS IDP */ 0x0027, "DECPIV", /* DECnet Phase IV */ 0x0029, "AT", /* Appletalk */ 0x002b, "IPX", /* Novell IPX */ 0x002d, "VJ_CTCP", /* Van Jacobson Compressed TCP/IP */ 0x002f, "VJ_UCTCP", /* Van Jacobson Uncompressed TCP/IP 0x0031, "BPDU", /* Bridging PDU */ 0x0033, "STP", /* Stream Protocol (ST-II) */ 0x0035, "BV", /* Banyan Vines */ 0x0039, "AT-EDDP", /* AppleTalk EDDP */ 0x003b, "AT-SB", /* AppleTalk SmartBuffered */ 0x003d, "ML", /* Multi-Link [RFC1717] */ 0x003f, "NB-FRM", /* NETBIOS Framing 0x0041, "CISCO", /* Cisco Systems */ 0x0043, "ASCOM", /* Ascom Timeplex */ 0x0045, "LBLB", /* Fujitsu Link Backup and Load Balancing (LBLB) */ 0x0047, "DCARL", /* DCA Remote Lan */ 0x0049, "SDTP", /* Serial Data Transport Protocol (PPP-SDTP) */ 0x004b, "SNA802.2", /* SNA over 802.2 */ 0x004d, "SNA", /* SNA */ 0x004f, "IPV6_HC", /* IPv6 Header Compression */ 0x0051, "KNXBD", /* KNX Bridging Data */ 0x0053, "ENCRY", /* Encryption */ 0x0055, "ILE", /* Individual Link Encryption */ 0x0057, "IPV6", /* Internet Protocol version 6 */ 0x006f, "SB", /* Stampede Bridging */ 0x0073, "MP+", /* MP+ Protocol */ 0x0201, "802.1dHELLO", /* 802.1d Hello Packets */ 0x0203, "IBMSRBPDU", /* IBM Source Routing BPDU */ 0x0205, "DECLBST", /* DEC LANBridge100 Spanning Tree */ 0x0207, "CISCO-DP", /* Cisco Discovery Protocol */ 0x0209, "NETCS-TR", /* Netcs Twin Routing */ 0x0231, "LUXCOM", /* Luxcom */ 0x0233, "SIGMA", /* Sigma Network Systems */ 0x0235, "APPLE-CSP", /* Apple Client Server Protocol */ 0x0281, "TS-UNIC", /* Tag Switching - Unicast */ 0x0283, "TS-MULTIC", /* Tag Switching - Multicast */ 0x0285, "IEEE1284.4", /* IEEE p1284.4 standard - data packets */ 0x0287, "ETSI-TETRA1", /* ETSI TETRA Network Protocol Type 1 */ 0x4001, "CRAY-CCP", /* Cray Communications Control Protocol */ 0x4003, "CDPD-MNRP", /* CDPD Mobile Network Registration Protocol */ 0x4021, "STACKER-LZS", /* Stacker LZS */ 0x4023, "REFTEK", /* RefTek Protocol */ 0x8021, "IP-CP", /* Internet Protocol Control Protocol */ 0x8023, "OSINL-CP", /* OSI Network Layer Control Protocol */ 0x8025, "XNSIDP-CP", /* Xerox NS IDP Control Protocol */ 0x8027, "DECPIV-CP", /* DECnet Phase IV Control Protocol */ 0x8029, "AT-CP", /* Appletalk Control Protocol */ 0x802b, "IPX-CP", /* Novell IPX Control Protocol */ 0x8031, "BR-CP", /* Bridging NCP */ 0x8033, "STRP-CP", /* Stream Protocol Control Protocol */ 0x8035, "BV-CP", /* Banyan Vines Control Protocol */ 0x803d, "ML-CP", /* Multi-Link Control Protocol */ 0x803f, "NBF-CP", /* NETBIOS Framing Control Protocol */ 0x8041, "CISCO-CP", /* Cisco Systems Control Protocol */ 0x8043, "ASCOM-CP", /* Ascom Timeplex */ 0x8045, "LBLB-CP", /* Fujitsu LBLB Control Protocol */ 0x8047, "RLN-CP", /* DCA Remote Lan Network Control Protocol (RLNCP) */ 0x8049, "SD-CP", /* Serial Data Control Protocol (PPP-SDCP) */ 0x804b, "SNA802.2-CP", /* SNA over 802.2 Control Protocol */ 0x804d, "SNA-CP", /* SNA Control Protocol */ 0x804f, "IPV6HC-CP", /* IP6 Header Compression Control Protocol */ 0x8051, "KNXB-CP", /* KNX Bridging Control Protocol */ 0x8053, "ENCRY-CP", /* Encryption Control Protocol */ 0x8055, "ILE-CP", /* Individual Link Encryption Control Protocol */ 0x8057, "IPV6-CP", /* IPv6 Control Protovol */ 0x806f, "SB-CP", /* Stampede Bridging Control Protocol */ 0x8073, "MP+-CP", /* MP+ Control Protocol */ 0x80c1, "NTCITSIPI-CP", /* NTCITS IPI Control Protocol */ 0x80fb, "SLCML-CP", /* single link compression in multilink control */ 0x80fd, "COMPR-CP", /* Compression Control Protocol */ 0x8207, "CISCODP-CP", /* Cisco Discovery Protocol Control */ 0x8209, "NETCSTR-CP", /* Netcs Twin Routing */ 0x8235, "APPLECS-CP", /* Apple Client Server Protocol Control */ 0x8281, "TSU-CP", /* Tag Switching - Unicast */ 0x8283, "TSM-CP", /* Tag Switching - Multicast */ 0x8285, "IEEE1284.4-CP",/* IEEE p1284.4 standard - Protocol Control */ 0x8287, "ETSITETRA-CP", /* ETSI TETRA NSP1 Control Protocol */ 0xc021, "LCP", /* Link Control Protocol */ 0xc023, "PAP", /* Password Authentication Protocol */ 0xc025, "LQR", /* Link Quality Report */ 0xc027, "SHIVA-PAP", /* Shiva Password Authentication Protocol */ 0xc029, "CBCP", /* CallBack Control Protocol (CBCP) */ 0xc02b, "BACP", /* BACP Bandwidth Allocation Control Protocol */ 0xc02d, "BAP", /* BAP */ 0xc081, "CCP", /* Container Control Protocol */ 0xc223, "CHAP", /* Challenge Handshake Authentication Protocol */ 0xc225, "RSAAP", /* RSA Authentication Protocol */ 0xc227, "EAP", /* Extensible Authentication Protocol */ 0xc229, "SIEP", /* Mitsubishi Security Info Exch Ptcl */ 0xc26f, "SBAP", /* Stampede Bridging Authorization Protocol */ 0xc281, "PRAPK", /* Proprietary Authentication Protocol [KEN] */ 0xc283, "PRAPT", /* Proprietary Authentication Protocol [Tackabury] */ 0xc481, "PRNIDAP" /* Proprietary Node ID Authentication Protocol */ }; /* LCP and IPCP Codes */ #define LCP_VENDOR 0 #define LCP_CONF_REQ 1 #define LCP_CONF_ACK 2 #define LCP_CONF_NAK 3 #define LCP_CONF_REJ 4 #define LCP_TERM_REQ 5 #define LCP_TERM_ACK 6 #define LCP_CODE_REJ 7 #define LCP_PROT_REJ 8 #define LCP_ECHO_REQ 9 #define LCP_ECHO_RPL 10 #define LCP_DISC_REQ 11 #define LCP_ID 12 #define LCP_TIME_REM 13 #define LCP_RST_REQ 14 #define LCP_RST_RPL 15 #define LCP_MIN LCP_CONF_REQ #define LCP_MAX LCP_DISC_REQ #define IPCP_MIN LCP_CONF_REQ #define IPCP_MAX LCP_CODE_REJ static char *lcpcodes[] = { /* * LCP code values (RFC1661, pp26) */ "Vendor-Specific", "Conf-REQ", "Conf-ACK", "Conf-NAK", "Conf-REJ", "Term-REQ", "Term-ACK", "Code-REJ", "Protocol-REJ", "Echo-REQ", "Echo-RPL", "Disc-REQ", "Identification", "Time-Remaining", "Reset-REQ", "Reset-RPL" }; #define LCPOPT_VEXT 0 #define LCPOPT_MRU 1 #define LCPOPT_ACCM 2 #define LCPOPT_AP 3 #define LCPOPT_QP 4 #define LCPOPT_MN 5 #define LCPOPT_PFC 7 #define LCPOPT_ACFC 8 #define LCPOPT_MIN 0 #define LCPOPT_MAX 29 static char *lcpconfopts[] = { "Vendor-Ext", "Max-Rx-Unit", "Async-Ctrl-Char-Map", "Auth-Prot", "Quality-Prot", "Magic-Number", "unassigned (6)", "Prot-Field-Compr", "Add-Ctrl-Field-Compr", "FCS-Alternatives", "Self-Describing-Pad", "Numbered-Mode", "Multi-Link-Procedure", "Call-Back", "Connect-Time" "Compund-Frames", "Nominal-Data-Encap", "Multilink-MRRU", "Multilink-SSNHF", "Multilink-ED", "Proprietary", "DCE-Identifier", "Multilink-Plus-Proc", "Link-Discriminator", "LCP-Auth-Option", "Consistent-Overhead-Byte-Stuffing", "Prefix-elision", "Multilink-header-format", "Internationalization", "Simple-Data-Link-on-SONET/SDH" }; /* CHAP */ #define CHAP_CHAL 1 #define CHAP_RESP 2 #define CHAP_SUCC 3 #define CHAP_FAIL 4 #define CHAP_CODEMIN 1 #define CHAP_CODEMAX 4 static char *chapcode[] = { "Challenge", "Response", "Success", "Failure", }; /* PAP */ #define PAP_AREQ 1 #define PAP_AACK 2 #define PAP_ANAK 3 #define PAP_CODEMIN 1 #define PAP_CODEMAX 3 static char *papcode[] = { "Authenticate-Request", "Authenticate-Ack", "Authenticate-Nak", }; /* IPCP */ #define IPCP_2ADDR 1 #define IPCP_CP 2 #define IPCP_ADDR 3 static int print_lcp(const u_char *p, int length); static int print_lcp_config_options(u_char *p); static int print_chap(const u_char *p, int length); static int print_ipcp(const u_char *p, int length); static int print_pap(const u_char *p, int length); static int print_default(const u_char *p, int length); static char *printproto(int protocol); /* print LCP frame */ static int print_lcp(const u_char *p, int length) { int x, j; u_char *ptr; printf("ID=%03d ", *(p+1)); x = *p; if((x >= LCP_MIN) && (x <= LCP_MAX)) { printf("%s", lcpcodes[x]); } else { printf("0x%02x", x); return; } length -= 4; switch(x) { case LCP_CONF_REQ: case LCP_CONF_ACK: case LCP_CONF_NAK: case LCP_CONF_REJ: x = length; ptr = (u_char *)p+4; do { if((j = print_lcp_config_options(ptr)) == 0) break; x -= j; ptr += j; } while(x > 0); break; case LCP_ECHO_REQ: case LCP_ECHO_RPL: printf(", Magic-Number=%d", ((*(p+4) << 24) + (*(p+5) << 16) + (*(p+6) << 8) + (*(p+7)))); break; case LCP_PROT_REJ: j = PPP_PROTOCOL(p+2); printf(", Protocol=%s", printproto(j)); break; default: break; } } /* LCP config options */ static int print_lcp_config_options(u_char *p) { int len = *(p+1); int opt = *p; if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX)) printf(", %s", lcpconfopts[opt]); switch(opt) { case LCPOPT_MRU: if(len == 4) printf("=%d", (*(p+2) << 8) + *(p+3)); break; case LCPOPT_AP: if(len >= 4) { if(*(p+2) == 0xc0 && *(p+3) == 0x23) { printf(" PAP"); } else if(*(p+2) == 0xc2 && *(p+3) == 0x23) { printf(" CHAP/"); switch(*(p+4)) { default: printf("unknown-algorithm-%d", *(p+4)); break; case 5: printf("MD5"); break; case 0x80: printf("Microsoft"); break; } } else if(*(p+2) == 0xc2 && *(p+3) == 0x27) { printf(" EAP"); } else if(*(p+2) == 0xc0 && *(p+3) == 0x27) { printf(" SPAP"); } else if(*(p+2) == 0xc1 && *(p+3) == 0x23) { printf(" Old-SPAP"); } else { printf("unknown"); } } break; case LCPOPT_QP: if(len >= 4) { if(*(p+2) == 0xc0 && *(p+3) == 0x25) printf(" LQR"); else printf(" unknown"); } break; case LCPOPT_MN: if(len == 6) { printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + (*(p+4) << 8) + (*(p+5)))); } break; case LCPOPT_PFC: printf(" PFC"); break; case LCPOPT_ACFC: printf(" ACFC"); break; } return(len); } /* CHAP */ static int print_chap(const u_char *p, int length) { int x, j; u_char *ptr; printf("ID=%03d ", *(p+1)); x = *p; if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX)) { printf("%s", chapcode[x-1]); } else { printf("0x%02x", x); return; } length -= 4; switch(x) { case CHAP_CHAL: case CHAP_RESP: printf(", Value="); x = *(p+4); /* value size */ ptr = (u_char *)p+5; while(--x >= 0) printf("%02x", *ptr++); x = length - *(p+4) - 1; printf(", Name="); while(--x >= 0) printf("%c", *ptr++); break; } } /* PAP */ static int print_pap(const u_char *p, int length) { int x, j; u_char *ptr; printf("ID=%03d ", *(p+1)); x = *p; if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX)) { printf("%s", papcode[x-1]); } else { printf("0x%02x", x); return; } length -= 4; switch(x) { case PAP_AREQ: printf(", Peer-Id="); x = *(p+4); /* peerid size */ ptr = (u_char *)p+5; while(--x >= 0) printf("%c", *ptr++); x = *ptr++; printf(", Passwd="); while(--x >= 0) printf("%c", *ptr++); break; case PAP_AACK: case PAP_ANAK: break; } } /* IPCP */ static int print_ipcp(const u_char *p, int length) { unsigned char *ipp = p+4; /* point to type field */ int x; printf("ID=%03d ", *(p+1)); x = *p; if((x >= IPCP_MIN) && (x <= IPCP_MAX)) { printf("%s, ", lcpcodes[x]); } else { printf("0x%02x", x); return; } length -= 4; while(length > 0) { switch(*ipp) { case IPCP_2ADDR: printf("IP-Addresses:"); printf(" Src=%d.%d.%d.%d", *(ipp+2), *(ipp+3), *(ipp+4), *(ipp+5)); printf(" Dst=%d.%d.%d.%d", *(ipp+6), *(ipp+7), *(ipp+8), *(ipp+9)); break; case IPCP_CP: printf("IP-Compression-Protocol: "); printf("Max-Slot-Id=0x%02x, ", *(ipp+4)); printf("Comp-Slot-Id=0x%02x" , *(ipp+5)); break; case IPCP_ADDR: printf("IP-Address: %d.%d.%d.%d", *(ipp+2), *(ipp+3), *(ipp+4), *(ipp+5)); break; } length -= *(ipp+1); if(length > 0) { ipp += *(ipp+1); printf(" "); } } } /* default */ static int print_default(const u_char *p, int length) { while(length) { printf("0x%02x ", *p); length--; p++; } } static char * printproto(int protocol) { static char buffer[64]; int i; /* print protocol */ for(i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i) { if(protocol == protonames[i].protocol) { sprintf(buffer, "%s (%04x): ", protonames[i].name, protocol); break; } } if (i < 0) { sprintf(buffer, "??? (%04x): ", protocol); } return(buffer); } void ppp_if_print(u_char *user, const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; int proto = PPP_PROTOCOL(p); int i; if(vflag > 2) /* print raw data */ { u_char *q = p; int z = length; printf("dump: "); while(z) { printf("0x%02x ", *q); z--; q++; } printf("\n"); } ts_print(&h->ts); /* print timestamp */ if (caplen < PPP_HDRLEN) /* short frame */ { printf("[|ppp]"); goto out; } /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + caplen; /* print protocol */ printf("%s", printproto(proto)); switch(proto) { case PPP_LCP: print_lcp(p + PPP_HDRLEN, length - PPP_HDRLEN); break; case PPP_CHAP: print_chap(p + PPP_HDRLEN, length - PPP_HDRLEN); break; case PPP_PAP: print_pap(p + PPP_HDRLEN, length - PPP_HDRLEN); break; case PPP_IPCP: print_ipcp(p + PPP_HDRLEN, length - PPP_HDRLEN); break; case PPP_IP: case ETHERTYPE_IP: ip_print((const u_char *)(p + PPP_HDRLEN), length-PPP_HDRLEN); break; case PPP_IPX: case ETHERTYPE_IPX: ipx_print((const u_char *)(p + PPP_HDRLEN), length-PPP_HDRLEN); break; default: print_default(p + PPP_HDRLEN, length - PPP_HDRLEN); break; } if (xflag) default_print((const u_char *)(p + PPP_HDRLEN), caplen - PPP_HDRLEN); out: putchar('\n'); } /* proto type to string mapping */ static struct tok ptype2str[] = { { PPP_VJC, "VJC" }, { PPP_VJNC, "VJNC" }, { PPP_OSI, "OSI" }, { PPP_LCP, "LCP" }, { PPP_IPCP, "IPCP" }, { 0, NULL } }; #define PPP_BSDI_HDRLEN 24 /* BSD/OS specific PPP printer */ void ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, register const u_char *p) { register u_int length = h->len; register u_int caplen = h->caplen; register int hdrlength; u_short ptype; ts_print(&h->ts); if (caplen < PPP_BSDI_HDRLEN) { printf("[|ppp]"); goto out; } /* * Some printers want to get back at the link level addresses, * and/or check that they're not walking off the end of the packet. * Rather than pass them all the way down, we set these globals. */ packetp = p; snapend = p + caplen; hdrlength = 0; if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) { if (eflag) printf("%02x %02x ", p[0], p[1]); p += 2; hdrlength = 2; } if (eflag) printf("%d ", length); /* Retrieve the protocol type */ if (*p & 01) { /* Compressed protocol field */ ptype = *p; if (eflag) printf("%02x ", ptype); p++; hdrlength += 1; } else { /* Un-compressed protocol field */ ptype = ntohs(*(u_short *)p); if (eflag) printf("%04x ", ptype); p += 2; hdrlength += 2; } length -= hdrlength; if (ptype == PPP_IP) ip_print(p, length); else printf("%s ", tok2str(ptype2str, "proto-#%d", ptype)); if (xflag) default_print((const u_char *)p, caplen - hdrlength); out: putchar('\n'); }