print-ppp.c revision 38638
117680Spst/*
217680Spst * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
317680Spst *	The Regents of the University of California.  All rights reserved.
417680Spst *
517680Spst * Redistribution and use in source and binary forms, with or without
617680Spst * modification, are permitted provided that: (1) source code distributions
717680Spst * retain the above copyright notice and this paragraph in its entirety, (2)
817680Spst * distributions including binary code include the above copyright notice and
917680Spst * this paragraph in its entirety in the documentation or other materials
1017680Spst * provided with the distribution, and (3) all advertising materials mentioning
1117680Spst * features or use of this software display the following acknowledgement:
1217680Spst * ``This product includes software developed by the University of California,
1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1417680Spst * the University nor the names of its contributors may be used to endorse
1517680Spst * or promote products derived from this software without specific prior
1617680Spst * written permission.
1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2017680Spst */
2117680Spst
2217680Spst#ifndef lint
2326183Sfennerstatic const char rcsid[] =
2426183Sfenner    "@(#) $Header: print-ppp.c,v 1.24 96/12/10 23:23:12 leres Exp $ (LBL)";
2517680Spst#endif
2617680Spst
2717680Spst#ifdef PPP
2817680Spst#include <sys/param.h>
2917680Spst#include <sys/time.h>
3017680Spst#include <sys/socket.h>
3117680Spst#include <sys/file.h>
3217680Spst#include <sys/ioctl.h>
3317680Spst
3417680Spst#if __STDC__
3517680Spststruct mbuf;
3617680Spststruct rtentry;
3717680Spst#endif
3817680Spst#include <net/if.h>
3917680Spst
4017680Spst#include <netinet/in.h>
4117680Spst#include <netinet/in_systm.h>
4217680Spst#include <netinet/ip.h>
4317680Spst
4417680Spst#include <ctype.h>
4517680Spst#include <netdb.h>
4617680Spst#include <pcap.h>
4717680Spst#include <signal.h>
4817680Spst#include <stdio.h>
4917680Spst
5021262Swollman#include <net/ethernet.h>
5117692Spst#include "ethertype.h"
5217692Spst
5317692Spst#include <net/ppp_defs.h>
5417680Spst#include "interface.h"
5517680Spst#include "addrtoname.h"
5617680Spst
5717692Spststruct protonames {
5817692Spst	u_short protocol;
5917692Spst	char *name;
6017692Spst};
6117680Spst
6217692Spststatic struct protonames protonames[] = {
6317692Spst	/*
6417692Spst	 * Protocol field values.
6517692Spst	 */
6617692Spst	PPP_IP,		"IP",		/* Internet Protocol */
6717692Spst	PPP_XNS,	"XNS",		/* Xerox NS */
6817692Spst	PPP_IPX,	"IPX",		/* IPX Datagram (RFC1552) */
6917692Spst	PPP_VJC_COMP,	"VJC_UNCOMP",	/* VJ compressed TCP */
7017692Spst	PPP_VJC_UNCOMP,	"VJC_UNCOMP",	/* VJ uncompressed TCP */
7117692Spst	PPP_COMP,	"COMP",		/* compressed packet */
7217692Spst	PPP_IPCP,	"IPCP",		/* IP Control Protocol */
7317692Spst	PPP_IPXCP,	"IPXCP",	/* IPX Control Protocol (RFC1552) */
7417692Spst	PPP_CCP,	"CCP",		/* Compression Control Protocol */
7517692Spst	PPP_LCP,	"LCP",		/* Link Control Protocol */
7617692Spst	PPP_PAP,	"PAP",		/* Password Authentication Protocol */
7717692Spst	PPP_LQR,	"LQR",		/* Link Quality Report protocol */
7817692Spst	PPP_CHAP,	"CHAP",		/* Cryptographic Handshake Auth. Proto*/
7917692Spst};
8017692Spst
8138638Sthepish/* LCP */
8238638Sthepish
8338638Sthepish#define LCP_CONF_REQ	1
8438638Sthepish#define LCP_CONF_ACK	2
8538638Sthepish#define LCP_CONF_NAK	3
8638638Sthepish#define LCP_CONF_REJ	4
8738638Sthepish#define LCP_TERM_REQ	5
8838638Sthepish#define LCP_TERM_ACK	6
8938638Sthepish#define LCP_CODE_REJ	7
9038638Sthepish#define LCP_PROT_REJ	8
9138638Sthepish#define LCP_ECHO_REQ	9
9238638Sthepish#define LCP_ECHO_RPL	10
9338638Sthepish#define LCP_DISC_REQ	11
9438638Sthepish
9538638Sthepish#define LCP_MIN	LCP_CONF_REQ
9638638Sthepish#define LCP_MAX LCP_DISC_REQ
9738638Sthepish
9838638Sthepishstatic char *lcpcodes[] = {
9938638Sthepish	/*
10038638Sthepish	 * LCP code values (RFC1661, pp26)
10138638Sthepish	 */
10238638Sthepish	"Configure-Request",
10338638Sthepish	"Configure-Ack",
10438638Sthepish	"Configure-Nak",
10538638Sthepish	"Configure-Reject",
10638638Sthepish	"Terminate-Request",
10738638Sthepish	"Terminate-Ack",
10838638Sthepish 	"Code-Reject",
10938638Sthepish	"Protocol-Reject",
11038638Sthepish	"Echo-Request",
11138638Sthepish	"Echo-Reply",
11238638Sthepish	"Discard-Request",
11338638Sthepish};
11438638Sthepish
11538638Sthepish#define LCPOPT_VEXT	0
11638638Sthepish#define LCPOPT_MRU	1
11738638Sthepish#define LCPOPT_ACCM	2
11838638Sthepish#define LCPOPT_AP	3
11938638Sthepish#define LCPOPT_QP	4
12038638Sthepish#define LCPOPT_MN	5
12138638Sthepish#define LCPOPT_PFC	7
12238638Sthepish#define LCPOPT_ACFC	8
12338638Sthepish
12438638Sthepish#define LCPOPT_MIN 0
12538638Sthepish#define LCPOPT_MAX 24
12638638Sthepish
12738638Sthepishstatic char *lcpconfopts[] = {
12838638Sthepish	"Vendor-Ext",
12938638Sthepish	"Max-Rx-Unit",
13038638Sthepish	"Async-Ctrl-Char-Map",
13138638Sthepish	"Auth-Prot",
13238638Sthepish	"Quality-Prot",
13338638Sthepish	"Magic-Number",
13438638Sthepish	"unassigned (6)",
13538638Sthepish	"Prot-Field-Compr",
13638638Sthepish	"Add-Ctrl-Field-Compr",
13738638Sthepish	"FCS-Alternatives",
13838638Sthepish	"Self-Describing-Pad",
13938638Sthepish	"Numbered-Mode",
14038638Sthepish	"Multi-Link-Procedure",
14138638Sthepish	"Call-Back",
14238638Sthepish	"Connect-Time"
14338638Sthepish	"Compund-Frames",
14438638Sthepish	"Nominal-Data-Encap",
14538638Sthepish	"Multilink-MRRU",
14638638Sthepish	"Multilink-SSNHF",
14738638Sthepish	"Multilink-ED",
14838638Sthepish	"Proprietary",
14938638Sthepish	"DCE-Identifier",
15038638Sthepish	"Multilink-Plus-Proc",
15138638Sthepish	"Link-Discriminator",
15238638Sthepish	"LCP-Auth-Option",
15338638Sthepish};
15438638Sthepish
15538638Sthepish/* CHAP */
15638638Sthepish
15738638Sthepish#define CHAP_CHAL	1
15838638Sthepish#define CHAP_RESP	2
15938638Sthepish#define CHAP_SUCC	3
16038638Sthepish#define CHAP_FAIL	4
16138638Sthepish
16238638Sthepish#define CHAP_CODEMIN 1
16338638Sthepish#define CHAP_CODEMAX 4
16438638Sthepish
16538638Sthepishstatic char *chapcode[] = {
16638638Sthepish	"Challenge",
16738638Sthepish	"Response",
16838638Sthepish	"Success",
16938638Sthepish	"Failure",
17038638Sthepish};
17138638Sthepish
17238638Sthepish/* PAP */
17338638Sthepish
17438638Sthepish#define PAP_AREQ	1
17538638Sthepish#define PAP_AACK	2
17638638Sthepish#define PAP_ANAK	3
17738638Sthepish
17838638Sthepish#define PAP_CODEMIN	1
17938638Sthepish#define PAP_CODEMAX	3
18038638Sthepish
18138638Sthepishstatic char *papcode[] = {
18238638Sthepish	"Authenticate-Request",
18338638Sthepish	"Authenticate-Ack",
18438638Sthepish	"Authenticate-Nak",
18538638Sthepish};
18638638Sthepish
18738638Sthepish/* IPCP */
18838638Sthepish
18938638Sthepish#define IPCP_2ADDR	1
19038638Sthepish#define IPCP_CP		2
19138638Sthepish#define IPCP_ADDR	3
19238638Sthepish
19338638Sthepishstatic int handle_lcp(const u_char *p, int length);
19438638Sthepishstatic int print_lcp_config_options(u_char *p);
19538638Sthepishstatic int handle_chap(const u_char *p, int length);
19638638Sthepishstatic int handle_ipcp(const u_char *p, int length);
19738638Sthepishstatic int handle_pap(const u_char *p, int length);
19838638Sthepish
19917680Spstvoid
20017692Spstppp_hdlc_print(const u_char *p, int length)
20117692Spst{
20217692Spst	int proto = PPP_PROTOCOL(p);
20338638Sthepish	int i, j, x;
20438638Sthepish	u_char *ptr;
20517692Spst
20638638Sthepish	printf("ID-%03d ", *(p+5));
20738638Sthepish
20838638Sthepish	for (i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i)
20938638Sthepish	{
21038638Sthepish		if (proto == protonames[i].protocol)
21138638Sthepish		{
21238638Sthepish			printf("%s: ", protonames[i].name);
21317692Spst
21438638Sthepish			switch(proto)
21538638Sthepish			{
21638638Sthepish				case PPP_LCP:
21738638Sthepish					handle_lcp(p, length);
21838638Sthepish					break;
21938638Sthepish				case PPP_CHAP:
22038638Sthepish					handle_chap(p, length);
22138638Sthepish					break;
22238638Sthepish				case PPP_PAP:
22338638Sthepish					handle_pap(p, length);
22438638Sthepish					break;
22538638Sthepish				case PPP_IPCP:
22638638Sthepish					handle_ipcp(p, length);
22738638Sthepish					break;
22838638Sthepish			}
22917692Spst			break;
23017692Spst		}
23117692Spst	}
23217692Spst	if (i < 0)
23338638Sthepish	{
23417692Spst		printf("%04x: ", proto);
23538638Sthepish	}
23617692Spst}
23717692Spst
23838638Sthepish/* print LCP frame */
23938638Sthepish
24038638Sthepishstatic int
24138638Sthepishhandle_lcp(const u_char *p, int length)
24217680Spst{
24338638Sthepish	int x, j;
24438638Sthepish	u_char *ptr;
24517680Spst
24638638Sthepish	x = *(p+4);
24732149Spst
24838638Sthepish	if((x >= LCP_MIN) && (x <= LCP_MAX))
24938638Sthepish	{
25038638Sthepish		printf("%s", lcpcodes[x-1]);
25138638Sthepish	}
25238638Sthepish	else
25338638Sthepish	{
25438638Sthepish		printf("0x%02x", x);
25538638Sthepish		return;
25638638Sthepish	}
25732149Spst
25838638Sthepish	length -= 4;
25938638Sthepish
26038638Sthepish	switch(x)
26138638Sthepish	{
26238638Sthepish		case LCP_CONF_REQ:
26338638Sthepish		case LCP_CONF_ACK:
26438638Sthepish		case LCP_CONF_NAK:
26538638Sthepish		case LCP_CONF_REJ:
26638638Sthepish			x = length;
26738638Sthepish			ptr = (u_char *)p+8;
26838638Sthepish			do
26938638Sthepish			{
27038638Sthepish				if((j = print_lcp_config_options(ptr)) == 0)
27138638Sthepish					break;
27238638Sthepish				x -= j;
27338638Sthepish				ptr += j;
27438638Sthepish			}
27538638Sthepish			while(x > 0);
27638638Sthepish			break;
27732149Spst
27838638Sthepish		case LCP_ECHO_REQ:
27938638Sthepish		case LCP_ECHO_RPL:
28038638Sthepish			printf(", Magic-Number=%d", ((*(p+8) << 24) + (*(p+9) << 16) + (*(p+10) << 8) + (*(p+11))));
28138638Sthepish			break;
28238638Sthepish		case LCP_TERM_REQ:
28338638Sthepish		case LCP_TERM_ACK:
28438638Sthepish		case LCP_CODE_REJ:
28538638Sthepish		case LCP_PROT_REJ:
28638638Sthepish		case LCP_DISC_REQ:
28738638Sthepish		default:
28838638Sthepish			break;
28938638Sthepish	}
29038638Sthepish}
29132149Spst
29238638Sthepish/* LCP config options */
29338638Sthepish
29438638Sthepishstatic int
29538638Sthepishprint_lcp_config_options(u_char *p)
29638638Sthepish{
29738638Sthepish	int len	= *(p+1);
29838638Sthepish	int opt = *p;
29938638Sthepish
30038638Sthepish	if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
30138638Sthepish		printf(", %s", lcpconfopts[opt]);
30238638Sthepish
30338638Sthepish	switch(opt)
30438638Sthepish	{
30538638Sthepish		case LCPOPT_MRU:
30638638Sthepish			if(len == 4)
30738638Sthepish				printf("=%d", (*(p+2) << 8) + *(p+3));
30838638Sthepish			break;
30938638Sthepish		case LCPOPT_AP:
31038638Sthepish			if(len >= 4)
31138638Sthepish			{
31238638Sthepish				if(*(p+2) == 0xc0 && *(p+3) == 0x23)
31338638Sthepish				{
31438638Sthepish					printf(" PAP");
31538638Sthepish				}
31638638Sthepish				else if(*(p+2) == 0xc2 && *(p+3) == 0x23)
31738638Sthepish				{
31838638Sthepish					printf(" CHAP/");
31938638Sthepish					switch(*(p+4))
32038638Sthepish					{
32138638Sthepish						default:
32238638Sthepish							printf("unknown-algorithm-%d", *(p+4));
32338638Sthepish							break;
32438638Sthepish						case 5:
32538638Sthepish							printf("MD5");
32638638Sthepish							break;
32738638Sthepish						case 0x80:
32838638Sthepish							printf("Microsoft");
32938638Sthepish							break;
33038638Sthepish					}
33138638Sthepish				}
33238638Sthepish				else if(*(p+2) == 0xc2 && *(p+3) == 0x27)
33338638Sthepish				{
33438638Sthepish					printf(" EAP");
33538638Sthepish				}
33638638Sthepish				else if(*(p+2) == 0xc0 && *(p+3) == 0x27)
33738638Sthepish				{
33838638Sthepish					printf(" SPAP");
33938638Sthepish				}
34038638Sthepish				else if(*(p+2) == 0xc1 && *(p+3) == 0x23)
34138638Sthepish				{
34238638Sthepish					printf(" Old-SPAP");
34338638Sthepish				}
34438638Sthepish				else
34538638Sthepish				{
34638638Sthepish					printf("unknown");
34738638Sthepish				}
34838638Sthepish			}
34938638Sthepish			break;
35038638Sthepish		case LCPOPT_QP:
35138638Sthepish			if(len >= 4)
35238638Sthepish			{
35338638Sthepish				if(*(p+2) == 0xc0 && *(p+3) == 0x25)
35438638Sthepish					printf(" LQR");
35538638Sthepish				else
35638638Sthepish					printf(" unknown");
35738638Sthepish			}
35838638Sthepish			break;
35938638Sthepish		case LCPOPT_MN:
36038638Sthepish			if(len == 6)
36138638Sthepish			{
36238638Sthepish				printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + (*(p+4) << 8) + (*(p+5))));
36338638Sthepish			}
36438638Sthepish			break;
36538638Sthepish		case LCPOPT_PFC:
36638638Sthepish			printf(" PFC");
36738638Sthepish			break;
36838638Sthepish		case LCPOPT_ACFC:
36938638Sthepish			printf(" ACFC");
37038638Sthepish			break;
37138638Sthepish	}
37238638Sthepish	return(len);
37338638Sthepish}
37438638Sthepish
37538638Sthepish/* CHAP */
37638638Sthepish
37738638Sthepishstatic int
37838638Sthepishhandle_chap(const u_char *p, int length)
37938638Sthepish{
38038638Sthepish	int x, j;
38138638Sthepish	u_char *ptr;
38238638Sthepish
38338638Sthepish	x = *(p+4);
38438638Sthepish
38538638Sthepish	if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
38638638Sthepish	{
38738638Sthepish		printf("%s", chapcode[x-1]);
38838638Sthepish	}
38938638Sthepish	else
39038638Sthepish	{
39138638Sthepish		printf("0x%02x", x);
39232149Spst		return;
39332149Spst	}
39432149Spst
39538638Sthepish	length -= 4;
39638638Sthepish
39738638Sthepish	switch(x)
39838638Sthepish	{
39938638Sthepish		case CHAP_CHAL:
40038638Sthepish		case CHAP_RESP:
40138638Sthepish			printf(", Value=");
40238638Sthepish			x = *(p+8);	/* value size */
40338638Sthepish			ptr = (u_char *)p+9;
40438638Sthepish			while(--x >= 0)
40538638Sthepish				printf("%02x", *ptr++);
40638638Sthepish			x = length - *(p+8) - 1;
40738638Sthepish			printf(", Name=");
40838638Sthepish			while(--x >= 0)
40938638Sthepish				printf("%c", *ptr++);
41038638Sthepish			break;
41138638Sthepish	}
41238638Sthepish}
41338638Sthepish
41438638Sthepish/* PAP */
41538638Sthepish
41638638Sthepishstatic int
41738638Sthepishhandle_pap(const u_char *p, int length)
41838638Sthepish{
41938638Sthepish	int x, j;
42038638Sthepish	u_char *ptr;
42138638Sthepish
42238638Sthepish	x = *(p+4);
42338638Sthepish
42438638Sthepish	if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
42538638Sthepish	{
42638638Sthepish		printf("%s", papcode[x-1]);
42738638Sthepish	}
42838638Sthepish	else
42938638Sthepish	{
43038638Sthepish		printf("0x%02x", x);
43138638Sthepish		return;
43238638Sthepish	}
43338638Sthepish
43438638Sthepish	length -= 4;
43538638Sthepish
43638638Sthepish	switch(x)
43738638Sthepish	{
43838638Sthepish		case PAP_AREQ:
43938638Sthepish			printf(", Peer-Id=");
44038638Sthepish			x = *(p+8);	/* peerid size */
44138638Sthepish			ptr = (u_char *)p+9;
44238638Sthepish			while(--x >= 0)
44338638Sthepish				printf("%c", *ptr++);
44438638Sthepish			x = *ptr++;
44538638Sthepish			printf(", Passwd=");
44638638Sthepish			while(--x >= 0)
44738638Sthepish				printf("%c", *ptr++);
44838638Sthepish			break;
44938638Sthepish		case PAP_AACK:
45038638Sthepish		case PAP_ANAK:
45138638Sthepish			break;
45238638Sthepish	}
45338638Sthepish}
45438638Sthepish
45538638Sthepish/* IPCP */
45638638Sthepish
45738638Sthepishstatic int
45838638Sthepishhandle_ipcp(const u_char *p, int length)
45938638Sthepish{
46038638Sthepish	int x, j;
46138638Sthepish
46238638Sthepish	x = *(p+8);
46338638Sthepish
46438638Sthepish	length -= 4;
46538638Sthepish
46638638Sthepish	switch(x)
46738638Sthepish	{
46838638Sthepish		case IPCP_2ADDR:
46938638Sthepish			printf("IP-Addresses");
47038638Sthepish			printf(", Src=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
47138638Sthepish			printf(", Dst=%d.%d.%d.%d", *(p+14), *(p+15), *(p+16), *(p+17));
47238638Sthepish			break;
47338638Sthepish
47438638Sthepish		case IPCP_CP:
47538638Sthepish			printf("IP-Compression-Protocol");
47638638Sthepish			break;
47738638Sthepish
47838638Sthepish		case IPCP_ADDR:
47938638Sthepish			printf("IP-Address=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
48038638Sthepish			break;
48138638Sthepish	}
48238638Sthepish}
48338638Sthepish
48438638Sthepishvoid
48538638Sthepishppp_if_print(u_char *user, const struct pcap_pkthdr *h,
48638638Sthepish	     register const u_char *p)
48738638Sthepish{
48838638Sthepish	register u_int length = h->len;
48938638Sthepish	register u_int caplen = h->caplen;
49038638Sthepish
49117680Spst	ts_print(&h->ts);
49217680Spst
49317680Spst	if (caplen < PPP_HDRLEN) {
49417680Spst		printf("[|ppp]");
49517680Spst		goto out;
49617680Spst	}
49717680Spst
49817680Spst	/*
49917680Spst	 * Some printers want to get back at the link level addresses,
50017680Spst	 * and/or check that they're not walking off the end of the packet.
50117680Spst	 * Rather than pass them all the way down, we set these globals.
50217680Spst	 */
50317680Spst	packetp = p;
50417680Spst	snapend = p + caplen;
50517680Spst
50617680Spst	if (eflag)
50717692Spst		ppp_hdlc_print(p, length);
50817680Spst
50917680Spst	length -= PPP_HDRLEN;
51017680Spst
51117692Spst	switch(PPP_PROTOCOL(p)) {
51217692Spst	case PPP_IP:
51317692Spst	case ETHERTYPE_IP:
51417692Spst		ip_print((const u_char *)(p + PPP_HDRLEN), length);
51517692Spst		break;
51617692Spst	case PPP_IPX:
51717692Spst	case ETHERTYPE_IPX:
51817692Spst		ipx_print((const u_char *)(p + PPP_HDRLEN), length);
51917692Spst		break;
52038638Sthepish
52117692Spst	default:
52238638Sthepish		if(!eflag)
52338638Sthepish			ppp_hdlc_print(p, length);
52417692Spst		if(!xflag)
52517692Spst			default_print((const u_char *)(p + PPP_HDRLEN),
52617692Spst					caplen - PPP_HDRLEN);
52717692Spst	}
52817692Spst
52917680Spst	if (xflag)
53017692Spst		default_print((const u_char *)(p + PPP_HDRLEN),
53117692Spst				caplen - PPP_HDRLEN);
53217680Spstout:
53317680Spst	putchar('\n');
53417680Spst}
53517680Spst#else
53617680Spst#include <sys/types.h>
53717680Spst#include <sys/time.h>
53817680Spst
53917680Spst#include <stdio.h>
54017680Spst
54117680Spst#include "interface.h"
54217680Spstvoid
54317680Spstppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
54417680Spst{
54517680Spst	error("not configured for ppp");
54617680Spst	/* NOTREACHED */
54717680Spst}
54817680Spst#endif
549