]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ppp.c
Bring in KAME IPv6 tcpdump. replaces esp/ah/isakmp decoder.
[tcpdump] / print-ppp.c
index 4a84fc955452972a161d128c5aee6e7e5d902f34..89ab24dca0899d15fe4ee12143abb5b40ede0b18 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.26 1999-10-07 23:47:12 mcr Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.27 1999-10-30 05:11:19 itojun Exp $ (LBL)";
 #endif
 
 #include <sys/param.h>
@@ -39,11 +39,16 @@ struct rtentry;
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
+#include <netinet/if_ether.h>
 
 #include <ctype.h>
 #include <netdb.h>
 #include <pcap.h>
 #include <stdio.h>
+#ifdef __bsdi__
+#include <net/slcompress.h>
+#include <net/if_ppp.h>
+#endif
 
 #include "interface.h"
 #include "addrtoname.h"
@@ -52,6 +57,390 @@ struct rtentry;
 /* XXX This goes somewhere else. */
 #define PPP_HDRLEN 4
 
+/* LCP */
+
+#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_MIN        LCP_CONF_REQ
+#define LCP_MAX LCP_DISC_REQ
+
+static char *lcpcodes[] = {
+       /*
+        * LCP code values (RFC1661, pp26)
+        */
+       "Configure-Request",
+       "Configure-Ack",
+       "Configure-Nak",
+       "Configure-Reject",
+       "Terminate-Request",
+       "Terminate-Ack",
+       "Code-Reject",
+       "Protocol-Reject",
+       "Echo-Request",
+       "Echo-Reply",
+       "Discard-Request",
+};
+
+#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 24
+
+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",
+};
+
+/* 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 const char *ppp_protoname __P((int proto));
+static void handle_lcp __P((const u_char *p, int length));
+static int print_lcp_config_options __P((const u_char *p));
+static void handle_chap __P((const u_char *p, int length));
+static void handle_ipcp __P((const u_char *p, int length));
+static void handle_pap __P((const u_char *p, int length));
+
+static const char *
+ppp_protoname(int proto)
+{
+       static char buf[20];
+
+       switch (proto) {
+       case PPP_IP:    return "IP";
+#ifdef PPP_XNS
+       case PPP_XNS:   return "XNS";
+#endif
+#ifdef PPP_IPX
+       case PPP_IPX:   return "IPX";
+#endif
+#ifdef PPP_COMP
+       case PPP_COMP:  return "COMP";
+#endif
+#ifdef PPP_IPCP
+       case PPP_IPCP:  return "IPCP";
+#endif
+#ifdef PPP_IPV6CP
+       case PPP_IPV6CP: return "IPV6CP";
+#endif
+#ifdef PPP_IPXCP
+       case PPP_IPXCP: return "IPXCP";
+#endif
+#ifdef PPP_CCP
+       case PPP_CCP:   return "CCP";
+#endif
+#ifdef PPP_LCP
+       case PPP_LCP:   return "LCP";
+#endif
+#ifdef PPP_PAP
+       case PPP_PAP:   return "PAP";
+#endif
+#ifdef PPP_LQR
+       case PPP_LQR:   return "LQR";
+#endif
+#ifdef PPP_CHAP
+       case PPP_CHAP:  return "CHAP";
+#endif
+       default:
+               snprintf(buf, sizeof(buf), "unknown-0x%04x\n", proto);
+               return buf;
+       }
+}
+
+/* print LCP frame */
+static void
+handle_lcp(const u_char *p, int length)
+{
+       int x, j;
+       const u_char *ptr;
+
+       x = p[4];
+
+       if ((x >= LCP_MIN) && (x <= LCP_MAX))
+               printf("%s", lcpcodes[x - 1]);
+       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 = p + 8;
+               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=%u",
+                       (u_int32_t)ntohl(*(u_int32_t *)(p + 8)));
+               break;
+       case LCP_TERM_REQ:
+       case LCP_TERM_ACK:
+       case LCP_CODE_REJ:
+       case LCP_PROT_REJ:
+       case LCP_DISC_REQ:
+       default:
+               break;
+       }
+}
+
+/* LCP config options */
+static int
+print_lcp_config_options(const u_char *p)
+{
+       int len = p[1];
+       int opt = p[0];
+       
+       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-%u", 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("=%u", (u_int32_t)ntohl(*(u_int32_t *)(p + 2)));
+               break;
+       case LCPOPT_PFC:
+               printf(" PFC");
+               break;
+       case LCPOPT_ACFC:
+               printf(" ACFC");
+               break;
+       }
+       return len;
+}
+
+/* CHAP */
+static void
+handle_chap(const u_char *p, int length)
+{
+       int x;
+       const u_char *ptr;
+
+       if ((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
+               printf("%s", chapcode[x - 1]);
+       else {
+               printf("0x%02x", x);
+               return;
+       }
+
+       length -= 4;
+       
+       switch (p[4]) {
+       case CHAP_CHAL:
+       case CHAP_RESP:
+               printf(", Value=");
+               x = p[8];       /* value size */
+               ptr = p + 9;
+               while (--x >= 0)
+                       printf("%02x", *ptr++);
+               x = length - p[8] - 1;
+               printf(", Name=");
+               while (--x >= 0) {
+                       if (isprint(*ptr))
+                               printf("%c", *ptr);
+                       else
+                               printf("\%03o", *ptr);
+                       ptr++;
+               }
+               break;
+       }
+}
+
+/* PAP */
+static void
+handle_pap(const u_char *p, int length)
+{
+       int x;
+       const u_char *ptr;
+
+       x = p[4];
+
+       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[8];       /* peerid size */
+               ptr = p + 9;
+               while (--x >= 0) {
+                       if (isprint(*ptr))
+                               printf("%c", *ptr);
+                       else
+                               printf("\%03o", *ptr);
+                       ptr++;
+               }
+               x = *ptr++;
+               printf(", Passwd=");
+               while (--x >= 0) {
+                       if (isprint(*ptr))
+                               printf("%c", *ptr);
+                       else
+                               printf("\%03o", *ptr);
+                       ptr++;
+               }
+               break;
+       case PAP_AACK:
+       case PAP_ANAK:
+               break;
+       }
+}
+
+/* IPCP */
+static void
+handle_ipcp(const u_char *p, int length)
+{
+       length -= 4;
+       
+       switch (p[8]) {
+       case IPCP_2ADDR:
+               printf("IP-Addresses");
+               printf(", src=%s", ipaddr_string(p + 10));
+               printf(", drc=%s", ipaddr_string(p + 14));
+               break;
+               
+       case IPCP_CP:
+               printf("IP-Compression-Protocol");
+               break;
+
+       case IPCP_ADDR:
+               printf("IP-Address=%s", ipaddr_string(p + 10));
+               break;
+       }
+}
+       
 /* Standard PPP printer */
 void
 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
@@ -60,6 +449,7 @@ ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
        register u_int length = h->len;
        register u_int caplen = h->caplen;
        const struct ip *ip;
+       u_int proto;
 
        ts_print(&h->ts);
 
@@ -73,23 +463,49 @@ ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
         * 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.
         */
+       proto = ntohs(*(u_short *)&p[2]);
        packetp = p;
        snapend = p + caplen;
 
        if (eflag)
-               printf("%c %4d %02x %04x: ", p[0] ? 'O' : 'I', length,
-                      p[1], ntohs(*(u_short *)&p[2]));
+               printf("%c %4d %02x %s: ", p[0] ? 'O' : 'I', length,
+                      p[1], ppp_protoname(proto));
 
        length -= PPP_HDRLEN;
        ip = (struct ip *)(p + PPP_HDRLEN);
-       ip_print((const u_char *)ip, length);
-
+       switch (proto) {
+       case PPP_LCP:
+               handle_lcp(p, length);
+               break;
+       case PPP_CHAP:
+               handle_chap(p, length);
+               break;
+       case PPP_PAP:
+               handle_pap(p, length);
+               break;
+       case PPP_IPCP:
+               handle_ipcp(p, length);
+               break;
+       case ETHERTYPE_IP:      /*XXX*/
+       case PPP_IP:
+               ip_print((const u_char *)ip, length);
+               break;
+#ifdef INET6
+       case ETHERTYPE_IPV6:    /*XXX*/
+#ifdef PPP_IPV6
+       case PPP_IPV6:
+#endif
+               ip6_print((const u_char *)ip, length);
+               break;
+#endif
+       }
        if (xflag)
                default_print((const u_char *)ip, caplen - PPP_HDRLEN);
 out:
        putchar('\n');
 }
 
+#ifdef __bsdi__
 /* proto type to string mapping */
 static struct tok ptype2str[] = {
        { PPP_VJC,      "VJC" },
@@ -99,6 +515,7 @@ static struct tok ptype2str[] = {
        { PPP_IPCP,     "IPCP" },
        { 0,            NULL }
 };
+#endif
 
 #define PPP_BSDI_HDRLEN 24
 
@@ -107,10 +524,13 @@ void
 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
             register const u_char *p)
 {
+#ifdef __bsdi__
        register u_int length = h->len;
        register u_int caplen = h->caplen;
        register int hdrlength;
        u_short ptype;
+       const u_char *q;
+       int i;
 
        ts_print(&h->ts);
 
@@ -128,6 +548,7 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
        snapend = p + caplen;
        hdrlength = 0;
 
+#if 0
        if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
                if (eflag) 
                        printf("%02x %02x ", p[0], p[1]);
@@ -153,16 +574,80 @@ ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
                p += 2;
                hdrlength += 2;
        }
-  
+#else
+       ptype = 0;      /*XXX*/
+       if (eflag)
+               printf("%c ", p[SLC_DIR] ? 'O' : 'I');
+       if (p[SLC_LLHL]) {
+               /* link level header */
+               struct ppp_header *ph;
+
+               q = p + SLC_BPFHDRLEN;
+               ph = (struct ppp_header *)q;
+               if (ph->phdr_addr == PPP_ADDRESS
+                && ph->phdr_ctl == PPP_CONTROL) {
+                       if (eflag) 
+                               printf("%02x %02x ", q[0], q[1]);
+                       ptype = ntohs(ph->phdr_type);
+                       if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
+                               printf("%s ", tok2str(ptype2str,
+                                               "proto-#%d", ptype));
+                       }
+               } else {
+                       if (eflag) {
+                               printf("LLH=[");
+                               for (i = 0; i < p[SLC_LLHL]; i++)
+                                       printf("%02x", q[i]);
+                               printf("] ");
+                       }
+               }
+               if (eflag) 
+                       printf("%d ", length);
+       }
+       if (p[SLC_CHL]) {
+               q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
+
+               switch (ptype) {
+               case PPP_VJC:
+                       ptype = vjc_print(q, length - (q - p), ptype);
+                       hdrlength = PPP_BSDI_HDRLEN;
+                       p += hdrlength;
+                       if (ptype == PPP_IP)
+                               ip_print(p, length);
+                       goto printx;
+               case PPP_VJNC:
+                       ptype = vjc_print(q, length - (q - p), ptype);
+                       hdrlength = PPP_BSDI_HDRLEN;
+                       p += hdrlength;
+                       if (ptype == PPP_IP)
+                               ip_print(p, length);
+                       goto printx;
+               default:
+                       if (eflag) {
+                               printf("CH=[");
+                               for (i = 0; i < p[SLC_LLHL]; i++)
+                                       printf("%02x", q[i]);
+                               printf("] ");
+                       }
+                       break;
+               }
+       }
+
+       hdrlength = PPP_BSDI_HDRLEN;
+#endif
+
        length -= hdrlength;
+       p += hdrlength;
 
        if (ptype == PPP_IP)
                ip_print(p, length);
        else
                printf("%s ", tok2str(ptype2str, "proto-#%d", ptype));
 
+printx:
        if (xflag)
                default_print((const u_char *)p, caplen - hdrlength);
 out:
        putchar('\n');
+#endif /* __bsdi__ */
 }