xref: /openbsd/usr.sbin/tcpdump/print-ppp.c (revision cca36db2)
1 /*	$OpenBSD: print-ppp.c,v 1.26 2011/12/28 22:41:55 sthen Exp $	*/
2 
3 /*
4  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
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 #ifdef PPP
25 #include <sys/param.h>
26 #include <sys/time.h>
27 #include <sys/socket.h>
28 #include <sys/file.h>
29 #include <sys/ioctl.h>
30 
31 struct mbuf;
32 struct rtentry;
33 #include <net/if.h>
34 
35 #include <netinet/in.h>
36 #include <netinet/in_systm.h>
37 #include <netinet/ip.h>
38 
39 #include <ctype.h>
40 #include <netdb.h>
41 #include <pcap.h>
42 #include <signal.h>
43 #include <stdio.h>
44 
45 #include <netinet/if_ether.h>
46 #include "ethertype.h"
47 
48 #include <net/ppp_defs.h>
49 #include "interface.h"
50 #include "addrtoname.h"
51 #include "extract.h"
52 
53 struct protonames {
54 	u_short protocol;
55 	char *name;
56 };
57 
58 static struct protonames protonames[] = {
59 	/*
60 	 * Protocol field values.
61 	 */
62 	{ PPP_IP,	"IP" },		/* Internet Protocol */
63 	{ PPP_XNS,	"XNS" },	/* Xerox NS */
64 	{ PPP_IPX,	"IPX" },	/* IPX Datagram (RFC1552) */
65 	{ PPP_VJC_COMP,	"VJC_UNCOMP" },	/* VJ compressed TCP */
66 	{ PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */
67 	{ PPP_COMP,	"COMP" },	/* compressed packet */
68 	{ PPP_IPCP,	"IPCP" },	/* IP Control Protocol */
69 	{ PPP_IPXCP,	"IPXCP" },	/* IPX Control Protocol (RFC1552) */
70 	{ PPP_IPV6CP,	"IPV6CP" },	/* IPv6 Control Protocol */
71 	{ PPP_CCP,	"CCP" },	/* Compression Control Protocol */
72 	{ PPP_LCP,	"LCP" },	/* Link Control Protocol */
73 	{ PPP_PAP,	"PAP" },	/* Password Authentication Protocol */
74 	{ PPP_LQR,	"LQR" },	/* Link Quality Report protocol */
75 	{ PPP_CHAP,	"CHAP" },	/* Cryptographic Handshake Auth. Proto */
76 	{ PPP_IPV6,	"IPV6" },	/* Internet Protocol v6 */
77 };
78 
79 /* LCP */
80 
81 #define LCP_CONF_REQ	1
82 #define LCP_CONF_ACK	2
83 #define LCP_CONF_NAK	3
84 #define LCP_CONF_REJ	4
85 #define LCP_TERM_REQ	5
86 #define LCP_TERM_ACK	6
87 #define LCP_CODE_REJ	7
88 #define LCP_PROT_REJ	8
89 #define LCP_ECHO_REQ	9
90 #define LCP_ECHO_RPL	10
91 #define LCP_DISC_REQ	11
92 
93 #define LCP_MIN	LCP_CONF_REQ
94 #define LCP_MAX LCP_DISC_REQ
95 
96 static char *lcpcodes[] = {
97 	/*
98 	 * LCP code values (RFC1661, pp26)
99 	 */
100 	"Configure-Request",
101 	"Configure-Ack",
102 	"Configure-Nak",
103 	"Configure-Reject",
104 	"Terminate-Request",
105 	"Terminate-Ack",
106  	"Code-Reject",
107 	"Protocol-Reject",
108 	"Echo-Request",
109 	"Echo-Reply",
110 	"Discard-Request",
111 };
112 
113 #define LCPOPT_VEXT	0
114 #define LCPOPT_MRU	1
115 #define LCPOPT_ACCM	2
116 #define LCPOPT_AP	3
117 #define LCPOPT_QP	4
118 #define LCPOPT_MN	5
119 #define LCPOPT_PFC	7
120 #define LCPOPT_ACFC	8
121 
122 #define LCPOPT_MIN 0
123 #define LCPOPT_MAX 24
124 
125 static char *lcpconfopts[] = {
126 	"Vendor-Ext",
127 	"Max-Rx-Unit",
128 	"Async-Ctrl-Char-Map",
129 	"Auth-Prot",
130 	"Quality-Prot",
131 	"Magic-Number",
132 	"unassigned (6)",
133 	"Prot-Field-Compr",
134 	"Add-Ctrl-Field-Compr",
135 	"FCS-Alternatives",
136 	"Self-Describing-Pad",
137 	"Numbered-Mode",
138 	"Multi-Link-Procedure",
139 	"Call-Back",
140 	"Connect-Time"
141 	"Compund-Frames",
142 	"Nominal-Data-Encap",
143 	"Multilink-MRRU",
144 	"Multilink-SSNHF",
145 	"Multilink-ED",
146 	"Proprietary",
147 	"DCE-Identifier",
148 	"Multilink-Plus-Proc",
149 	"Link-Discriminator",
150 	"LCP-Auth-Option",
151 };
152 
153 /* CHAP */
154 
155 #define CHAP_CHAL	1
156 #define CHAP_RESP	2
157 #define CHAP_SUCC	3
158 #define CHAP_FAIL	4
159 
160 #define CHAP_CODEMIN 1
161 #define CHAP_CODEMAX 4
162 
163 static char *chapcode[] = {
164 	"Challenge",
165 	"Response",
166 	"Success",
167 	"Failure",
168 };
169 
170 /* PAP */
171 
172 #define PAP_AREQ	1
173 #define PAP_AACK	2
174 #define PAP_ANAK	3
175 
176 #define PAP_CODEMIN	1
177 #define PAP_CODEMAX	3
178 
179 static char *papcode[] = {
180 	"Authenticate-Request",
181 	"Authenticate-Ack",
182 	"Authenticate-Nak",
183 };
184 
185 /* IPCP */
186 
187 #define IPCP_CODE_CFG_REQ	1
188 #define IPCP_CODE_CFG_ACK	2
189 #define IPCP_CODE_CFG_NAK	3
190 #define IPCP_CODE_CFG_REJ	4
191 #define IPCP_CODE_TRM_REQ	5
192 #define IPCP_CODE_TRM_ACK	6
193 #define IPCP_CODE_COD_REJ	7
194 
195 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ
196 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ
197 
198 #define IPCP_2ADDR	1
199 #define IPCP_CP		2
200 #define IPCP_ADDR	3
201 
202 /* IPV6CP */
203 
204 #define IPV6CP_CODE_CFG_REQ	1
205 #define IPV6CP_CODE_CFG_ACK	2
206 #define IPV6CP_CODE_CFG_NAK	3
207 #define IPV6CP_CODE_CFG_REJ	4
208 #define IPV6CP_CODE_TRM_REQ	5
209 #define IPV6CP_CODE_TRM_ACK	6
210 #define IPV6CP_CODE_COD_REJ	7
211 
212 #define IPV6CP_CODE_MIN IPV6CP_CODE_CFG_REQ
213 #define IPV6CP_CODE_MAX IPV6CP_CODE_COD_REJ
214 
215 #define IPV6CP_IFID	1
216 
217 static int print_lcp_config_options(u_char *p);
218 static void handle_lcp(const u_char *p, int length);
219 static void handle_chap(const u_char *p, int length);
220 static void handle_ipcp(const u_char *p, int length);
221 static void handle_ipv6cp(const u_char *p, int length);
222 static void handle_pap(const u_char *p, int length);
223 
224 struct pppoe_header {
225 	u_int8_t vertype;	/* PPPoE version/type */
226 	u_int8_t code;		/* PPPoE code (packet type) */
227 	u_int16_t sessionid;	/* PPPoE session id */
228 	u_int16_t len;		/* PPPoE payload length */
229 };
230 #define	PPPOE_CODE_SESSION	0x00	/* Session */
231 #define	PPPOE_CODE_PADO		0x07	/* Active Discovery Offer */
232 #define	PPPOE_CODE_PADI		0x09	/* Active Discovery Initiation */
233 #define	PPPOE_CODE_PADR		0x19	/* Active Discovery Request */
234 #define	PPPOE_CODE_PADS		0x65	/* Active Discovery Session-Confirm */
235 #define	PPPOE_CODE_PADT		0xa7	/* Active Discovery Terminate */
236 #define	PPPOE_TAG_END_OF_LIST		0x0000	/* End Of List */
237 #define	PPPOE_TAG_SERVICE_NAME		0x0101	/* Service Name */
238 #define	PPPOE_TAG_AC_NAME		0x0102	/* Access Concentrator Name */
239 #define	PPPOE_TAG_HOST_UNIQ		0x0103	/* Host Uniq */
240 #define	PPPOE_TAG_AC_COOKIE		0x0104	/* Access Concentratr Cookie */
241 #define	PPPOE_TAG_VENDOR_SPEC		0x0105	/* Vendor Specific */
242 #define	PPPOE_TAG_RELAY_SESSION		0x0110	/* Relay Session Id */
243 #define	PPPOE_TAG_MAX_PAYLOAD		0x0120	/* RFC 4638 Max Payload */
244 #define	PPPOE_TAG_SERVICE_NAME_ERROR	0x0201	/* Service Name Error */
245 #define	PPPOE_TAG_AC_SYSTEM_ERROR	0x0202	/* Acc. Concentrator Error */
246 #define	PPPOE_TAG_GENERIC_ERROR		0x0203	/* Generic Error */
247 
248 void
249 ppp_hdlc_print(p, length)
250 	const u_char *p;
251 	int length;
252 {
253 	int proto = PPP_PROTOCOL(p);
254 	int i;
255 
256 	for (i = sizeof(protonames) / sizeof(protonames[0]) - 1; i >= 0; i--) {
257 		if (proto == protonames[i].protocol) {
258 			printf("%s: ", protonames[i].name);
259 
260 			switch(proto) {
261 
262 			case PPP_LCP:
263 				handle_lcp(p, length);
264 				break;
265 			case PPP_CHAP:
266 				handle_chap(p, length);
267 				break;
268 			case PPP_PAP:
269 				handle_pap(p, length);
270 				break;
271 			case PPP_IPCP:
272 				handle_ipcp(p, length);
273 				break;
274 			case PPP_IPV6CP:
275 				handle_ipv6cp(p, length);
276 				break;
277 			}
278 			break;
279 		}
280 	}
281 	if (i < 0)
282 		printf("%04x: ", proto);
283 }
284 
285 /* print LCP frame */
286 
287 static void
288 handle_lcp(p, length)
289 	const u_char *p;
290 	int length;
291 {
292 	int x, j;
293 	u_char *ptr;
294 
295 	TCHECK(*(p + 4));
296 	x = *(p + 4);
297 
298 	if ((x >= LCP_MIN) && (x <= LCP_MAX))
299 		printf("%s", lcpcodes[x-1]);
300 	else {
301 		printf("0x%02x", x);
302 		return;
303 	}
304 
305 	length -= 4;
306 
307 	switch(x) {
308 
309 	case LCP_CONF_REQ:
310 	case LCP_CONF_ACK:
311 	case LCP_CONF_NAK:
312 	case LCP_CONF_REJ:
313 		x = length;
314 		ptr = (u_char *)p+8;
315 		do {
316 			if((j = print_lcp_config_options(ptr)) == 0)
317 				break;
318 			x -= j;
319 			ptr += j;
320 		}
321 		while(x > 0);
322 		break;
323 
324 	case LCP_ECHO_REQ:
325 	case LCP_ECHO_RPL:
326 		TCHECK2(*(p + 8), 4);
327 		printf(", Magic-Number=%d", ((*(p+ 8) << 24) + (*(p+9) << 16) +
328 					     (*(p+10) <<  8) + (*(p+11))));
329 		break;
330 	case LCP_TERM_REQ:
331 	case LCP_TERM_ACK:
332 	case LCP_CODE_REJ:
333 	case LCP_PROT_REJ:
334 	case LCP_DISC_REQ:
335 	default:
336 		break;
337 	}
338 	return;
339 
340 trunc:
341 	printf("[|lcp]");
342 }
343 
344 /* LCP config options */
345 
346 static int
347 print_lcp_config_options(p)
348 	u_char *p;
349 {
350 	int len, opt;
351 
352 	TCHECK2(*p, 2);
353 	len = *(p+1);
354 	opt = *p;
355 
356 	if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
357 		printf(", %s", lcpconfopts[opt]);
358 
359 	switch(opt) {
360 	case LCPOPT_MRU:
361 		if(len == 4) {
362 			TCHECK2(*(p + 2), 2);
363 			printf("=%d", (*(p+2) << 8) + *(p+3));
364 		}
365 		break;
366 	case LCPOPT_AP:
367 		if(len >= 4) {
368 			TCHECK2(*(p + 2), 2);
369 			if(*(p+2) == 0xc0 && *(p+3) == 0x23)
370 				printf(" PAP");
371 			else if(*(p+2) == 0xc2 && *(p+3) == 0x23) {
372 				printf(" CHAP/");
373 				TCHECK(*(p+4));
374 				switch(*(p+4)) {
375 				default:
376 					printf("unknown-algorithm-%d", *(p+4));
377 					break;
378 				case 5:
379 					printf("MD5");
380 					break;
381 				case 0x80:
382 					printf("Microsoft");
383 					break;
384 				}
385 			} else if(*(p+2) == 0xc2 && *(p+3) == 0x27)
386 					printf(" EAP");
387 			else if(*(p+2) == 0xc0 && *(p+3) == 0x27)
388 				printf(" SPAP");
389 			else if(*(p+2) == 0xc1 && *(p+3) == 0x23)
390 				printf(" Old-SPAP");
391 			else
392 				printf("unknown");
393 		}
394 		break;
395 	case LCPOPT_QP:
396 		if(len >= 4) {
397 			TCHECK2(*(p + 2), 2);
398 			if(*(p+2) == 0xc0 && *(p+3) == 0x25)
399 				printf(" LQR");
400 			else
401 				printf(" unknown");
402 		}
403 		break;
404 	case LCPOPT_MN:
405 		if(len == 6) {
406 			TCHECK2(*(p + 2), 4);
407 			printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) +
408 				       (*(p+4) <<  8) + (*(p+5))));
409 		}
410 		break;
411 	case LCPOPT_PFC:
412 		printf(" PFC");
413 		break;
414 	case LCPOPT_ACFC:
415 		printf(" ACFC");
416 		break;
417 	}
418 	return(len);
419 
420 trunc:
421 	printf("[|lcp]");
422 	return 0;
423 }
424 
425 /* CHAP */
426 
427 static void
428 handle_chap(p, length)
429 	const u_char *p;
430 	int length;
431 {
432 	int x;
433 	u_char *ptr;
434 
435 	TCHECK(*(p+4));
436 	x = *(p+4);
437 
438 	if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
439 		printf("%s", chapcode[x-1]);
440 	else {
441 		printf("0x%02x", x);
442 		return;
443 	}
444 
445 	length -= 4;
446 
447 	switch(x) {
448 	case CHAP_CHAL:
449 	case CHAP_RESP:
450 		printf(", Value=");
451 		TCHECK(*(p+8));
452 		x = *(p+8);	/* value size */
453 		ptr = (u_char *)p+9;
454 		while(--x >= 0) {
455 			TCHECK(*ptr);
456 			printf("%02x", *ptr++);
457 		}
458 		x = length - *(p+8) - 1;
459 		printf(", Name=");
460 		while(--x >= 0) {
461 			TCHECK(*ptr);
462 			safeputchar(*ptr++);
463 		}
464 		break;
465 	}
466 	return;
467 
468 trunc:
469 	printf("[|chap]");
470 }
471 
472 /* PAP */
473 
474 static void
475 handle_pap(p, length)
476 	const u_char *p;
477 	int length;
478 {
479 	int x;
480 	u_char *ptr;
481 
482 	TCHECK(*(p+4));
483 	x = *(p+4);
484 
485 	if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
486 		printf("%s", papcode[x-1]);
487 	else {
488 		printf("0x%02x", x);
489 		return;
490 	}
491 
492 	length -= 4;
493 
494 	switch(x) {
495 	case PAP_AREQ:
496 		printf(", Peer-Id=");
497 		TCHECK(*(p+8));
498 		x = *(p+8);	/* peerid size */
499 		ptr = (u_char *)p+9;
500 		while(--x >= 0) {
501 			TCHECK(*ptr);
502 			safeputchar(*ptr++);
503 		}
504 		TCHECK(*ptr);
505 		x = *ptr++;
506 		printf(", Passwd=");
507 		while(--x >= 0) {
508 			TCHECK(*ptr);
509 			safeputchar(*ptr++);
510 		}
511 		break;
512 	case PAP_AACK:
513 	case PAP_ANAK:
514 		break;
515 	}
516 	return;
517 
518 trunc:
519 	printf("[|pap]");
520 }
521 
522 /* IPCP */
523 
524 static void
525 handle_ipcp(p, length)
526 	const u_char *p;
527 	int length;
528 {
529 	int x;
530 
531 	TCHECK(*(p+4));
532 	x = *(p+4);
533 
534 	if((x >= IPCP_CODE_MIN) && (x <= IPCP_CODE_MAX))
535 		printf("%s", lcpcodes[x-1]);	/* share table with LCP */
536 	else {
537 		printf("0x%02x", x);
538 		return;
539 	}
540 
541 	length -= 4;
542 
543 	TCHECK(*(p+8));
544 	switch(*(p+8)) {
545 	case IPCP_2ADDR:
546 		printf(", IP-Addresses");
547 		TCHECK2(*(p+10), 8);
548 		printf(", Src=%d.%d.%d.%d",
549 		       *(p+10), *(p+11), *(p+12), *(p+13));
550 		printf(", Dst=%d.%d.%d.%d",
551 		       *(p+14), *(p+15), *(p+16), *(p+17));
552 		break;
553 
554 	case IPCP_CP:
555 		printf(", IP-Compression-Protocol");
556 		break;
557 
558 	case IPCP_ADDR:
559 		TCHECK2(*(p+10), 4);
560 		printf(", IP-Address=%d.%d.%d.%d",
561 		       *(p+10), *(p+11), *(p+12), *(p+13));
562 		break;
563 	default:
564 		printf(", Unknown IPCP code 0x%x", *(p+8));
565 		break;
566 	}
567 	return;
568 
569 trunc:
570 	printf("[|ipcp]");
571 }
572 
573 /* IPV6CP */
574 
575 static void
576 handle_ipv6cp(p, length)
577 	const u_char *p;
578 	int length;
579 {
580 	int x;
581 
582 	TCHECK(*(p+4));
583 	x = *(p+4);
584 
585 	if((x >= IPV6CP_CODE_MIN) && (x <= IPV6CP_CODE_MAX))
586 		printf("%s", lcpcodes[x-1]);    /* share table with LCP */
587 	else {
588 		printf("0x%02x", x);
589 		return;
590 	}
591 
592 	TCHECK(*(p+8));
593 	switch(*(p+8)) {
594 	case IPV6CP_IFID:
595 		TCHECK2(*(p + 10), 8);
596 		printf(", Interface-ID=%04x:%04x:%04x:%04x",
597 			EXTRACT_16BITS(p + 10),
598 			EXTRACT_16BITS(p + 12),
599 			EXTRACT_16BITS(p + 14),
600 			EXTRACT_16BITS(p + 16));
601 		break;
602 
603 	default:
604 		printf(", Unknown IPV6CP code 0x%x", *(p+8));
605 		break;
606 	}
607 	return;
608 
609 trunc:
610 	printf("[|ipv6cp]");
611 }
612 
613 void
614 ppp_if_print(user, h, p)
615 	u_char *user;
616 	const struct pcap_pkthdr *h;
617 	register const u_char *p;
618 {
619 	register u_int length = h->len;
620 	register u_int caplen = h->caplen;
621 
622 	ts_print(&h->ts);
623 
624 	if (caplen < PPP_HDRLEN) {
625 		printf("[|ppp]");
626 		goto out;
627 	}
628 
629 	/*
630 	 * Some printers want to get back at the link level addresses,
631 	 * and/or check that they're not walking off the end of the packet.
632 	 * Rather than pass them all the way down, we set these globals.
633 	 */
634 	packetp = p;
635 	snapend = p + caplen;
636 
637 	if (eflag)
638 		ppp_hdlc_print(p, length);
639 
640 	length -= PPP_HDRLEN;
641 
642 	switch(PPP_PROTOCOL(p)) {
643 	case PPP_IP:
644 	case ETHERTYPE_IP:
645 		ip_print((const u_char *)(p + PPP_HDRLEN), length);
646 		break;
647 	case PPP_IPV6:
648 	case ETHERTYPE_IPV6:
649 		ip6_print((const u_char *)(p + PPP_HDRLEN), length);
650 		break;
651 	case PPP_IPX:
652 	case ETHERTYPE_IPX:
653 		ipx_print((const u_char *)(p + PPP_HDRLEN), length);
654 		break;
655 
656 #ifndef	PPP_MPLS
657 #define	PPP_MPLS	0x0281
658 #endif
659 	case PPP_MPLS:
660 		mpls_print((const u_char *)(p + PPP_HDRLEN), length);
661 		break;
662 
663 	default:
664 		if(!eflag)
665 			ppp_hdlc_print(p, length);
666 		if(!xflag)
667 			default_print((const u_char *)(p + PPP_HDRLEN),
668 				      caplen - PPP_HDRLEN);
669 	}
670 
671 	if (xflag)
672 		default_print((const u_char *)(p + PPP_HDRLEN),
673 			      caplen - PPP_HDRLEN);
674 out:
675 	putchar('\n');
676 }
677 
678 void
679 ppp_ether_if_print(user, h, p)
680 	u_char *user;
681 	const struct pcap_pkthdr *h;
682 	register const u_char *p;
683 {
684 	u_int16_t pppoe_sid, pppoe_len;
685 	u_int caplen = h->caplen;
686 	u_int16_t length = h->len;
687 	u_int16_t proto;
688 	int i;
689 
690 	ts_print(&h->ts);
691 
692 	packetp = p;
693 	snapend = p + caplen;
694 
695 	if (eflag)
696 		printf("PPPoE ");
697 
698 	if (caplen < sizeof(struct pppoe_header)) {
699 		printf("[|pppoe]");
700 		return;
701 	}
702 
703 	if(eflag)
704 	{
705 		printf("\n\tcode ");
706 		switch (p[1]) {
707 		case PPPOE_CODE_PADI:
708 			printf("Initiation");
709 			break;
710 		case PPPOE_CODE_PADO:
711 			printf("Offer");
712 			break;
713 		case PPPOE_CODE_PADR:
714 			printf("Request");
715 			break;
716 		case PPPOE_CODE_PADS:
717 			printf("Confirm");
718 			break;
719 		case PPPOE_CODE_PADT:
720 			printf("Terminate");
721 			break;
722 		case PPPOE_CODE_SESSION:
723 			printf("Session");
724 			break;
725 		default:
726 			printf("Unknown(0x%02x)", p[1]);
727 			break;
728 		}
729 	}
730 
731 	pppoe_sid = EXTRACT_16BITS(p + 2);
732 	pppoe_len = EXTRACT_16BITS(p + 4);
733 
734 	if(eflag)
735 	    printf(", version %d, type %d, id 0x%04x, length %d",
736 		    (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
737 
738 	length -= sizeof(struct pppoe_header);
739 	caplen -= sizeof(struct pppoe_header);
740 	p += sizeof(struct pppoe_header);
741 
742 	if (pppoe_len > caplen)
743 		pppoe_len = caplen;
744 
745 	if (pppoe_len < 2) {
746 		printf("[|pppoe]");
747 		return;
748 	}
749 	proto = EXTRACT_16BITS(p);
750 
751 	for (i = sizeof(protonames)/sizeof(protonames[0]) - 1; i >= 0; i--) {
752 		if (proto == protonames[i].protocol) {
753 			if (eflag)
754 				printf("\n\t%s: ", protonames[i].name);
755 			switch (proto) {
756 			case PPP_LCP:
757 				handle_lcp(p - 2, length + 2);
758 				break;
759 			case PPP_CHAP:
760 				handle_chap(p - 2, length + 2);
761 				break;
762 			case PPP_PAP:
763 				handle_pap(p - 2, length + 2);
764 				break;
765 			case PPP_IPCP:
766 				handle_ipcp(p - 2, length + 2);
767 				break;
768 			case PPP_IPV6CP:
769 				handle_ipv6cp(p - 2, length + 2);
770 				break;
771 			case PPP_IP:
772 				ip_print(p + 2, length - 2);
773 				break;
774 			case PPP_IPV6:
775 				ip6_print(p + 2, length - 2);
776 				break;
777 			case PPP_IPX:
778 				ipx_print(p + 2, length - 2);
779 			}
780 			break;
781 		}
782 	}
783 	if (i < 0)
784 		printf("\n\t%04x: ", proto);
785 
786 	if (xflag)
787 	    default_print(p + 2, caplen - 2);
788 	putchar('\n');
789 }
790 
791 int
792 pppoe_if_print(ethertype, p, length, caplen)
793 	u_short ethertype;
794 	const u_char *p;
795 	u_int length, caplen;
796 {
797 	u_int16_t pppoe_sid, pppoe_len;
798 
799 	if (ethertype == ETHERTYPE_PPPOEDISC)
800 		printf("PPPoE-Discovery");
801 	else
802 		printf("PPPoE-Session");
803 
804 	if (caplen < sizeof(struct pppoe_header)) {
805 		printf("[|pppoe]");
806 		return (1);
807 	}
808 
809 	printf("\n\tcode ");
810 	switch (p[1]) {
811 	case PPPOE_CODE_PADI:
812 		printf("Initiation");
813 		break;
814 	case PPPOE_CODE_PADO:
815 		printf("Offer");
816 		break;
817 	case PPPOE_CODE_PADR:
818 		printf("Request");
819 		break;
820 	case PPPOE_CODE_PADS:
821 		printf("Confirm");
822 		break;
823 	case PPPOE_CODE_PADT:
824 		printf("Terminate");
825 		break;
826 	case PPPOE_CODE_SESSION:
827 		printf("Session");
828 		break;
829 	default:
830 		printf("Unknown(0x%02x)", p[1]);
831 		break;
832 	}
833 
834 	pppoe_sid = EXTRACT_16BITS(p + 2);
835 	pppoe_len = EXTRACT_16BITS(p + 4);
836 	printf(", version %d, type %d, id 0x%04x, length %d",
837 	    (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
838 
839 	length -= sizeof(struct pppoe_header);
840 	caplen -= sizeof(struct pppoe_header);
841 	p += sizeof(struct pppoe_header);
842 
843 	if (pppoe_len > caplen)
844 		pppoe_len = caplen;
845 
846 	if (ethertype == ETHERTYPE_PPPOEDISC) {
847 		while (pppoe_len > 0) {
848 			u_int16_t t_type, t_len;
849 
850 			if (pppoe_len < 4) {
851 				printf("\n\t[|pppoe]");
852 				break;
853 			}
854 			t_type = EXTRACT_16BITS(p);
855 			t_len = EXTRACT_16BITS(p + 2);
856 
857 			pppoe_len -= 4;
858 			p += 4;
859 
860 			if (pppoe_len < t_len) {
861 				printf("\n\t[|pppoe]");
862 				break;
863 			}
864 
865 			printf("\n\ttag ");
866 			switch (t_type) {
867 			case PPPOE_TAG_END_OF_LIST:
868 				printf("End-Of-List");
869 				break;
870 			case PPPOE_TAG_SERVICE_NAME:
871 				printf("Service-Name");
872 				break;
873 			case PPPOE_TAG_AC_NAME:
874 				printf("AC-Name");
875 				break;
876 			case PPPOE_TAG_HOST_UNIQ:
877 				printf("Host-Uniq");
878 				break;
879 			case PPPOE_TAG_AC_COOKIE:
880 				printf("AC-Cookie");
881 				break;
882 			case PPPOE_TAG_VENDOR_SPEC:
883 				printf("Vendor-Specific");
884 				break;
885 			case PPPOE_TAG_RELAY_SESSION:
886 				printf("Relay-Session");
887 				break;
888 			case PPPOE_TAG_MAX_PAYLOAD:
889 				printf("PPP-Max-Payload");
890 				break;
891 			case PPPOE_TAG_SERVICE_NAME_ERROR:
892 				printf("Service-Name-Error");
893 				break;
894 			case PPPOE_TAG_AC_SYSTEM_ERROR:
895 				printf("AC-System-Error");
896 				break;
897 			case PPPOE_TAG_GENERIC_ERROR:
898 				printf("Generic-Error");
899 				break;
900 			default:
901 				printf("Unknown(0x%04x)", t_type);
902 			}
903 			printf(", length %u%s", t_len, t_len ? " " : "");
904 
905 			if (t_len) {
906 				for (t_type = 0; t_type < t_len; t_type++) {
907 					if (isprint(p[t_type]))
908 						printf("%c", p[t_type]);
909 					else
910 						printf("\\%03o", p[t_type]);
911 				}
912 			}
913 			pppoe_len -= t_len;
914 			p += t_len;
915 		}
916 	}
917 	else if (ethertype == ETHERTYPE_PPPOE) {
918 		u_int16_t proto;
919 		int i;
920 
921 		if (pppoe_len < 2) {
922 			printf("[|pppoe]");
923 			return (1);
924 		}
925 		proto = EXTRACT_16BITS(p);
926 
927 		for (i = sizeof(protonames)/sizeof(protonames[0]) - 1; i >= 0;
928 		     i--) {
929 			if (proto == protonames[i].protocol) {
930 				printf("\n\t%s: ", protonames[i].name);
931 				switch (proto) {
932 				case PPP_LCP:
933 					handle_lcp(p - 2, length + 2);
934 					break;
935 				case PPP_CHAP:
936 					handle_chap(p - 2, length + 2);
937 					break;
938 				case PPP_PAP:
939 					handle_pap(p - 2, length + 2);
940 					break;
941 				case PPP_IPCP:
942 					handle_ipcp(p - 2, length + 2);
943 					break;
944 				case PPP_IPV6CP:
945 					handle_ipv6cp(p - 2, length + 2);
946 					break;
947 				case PPP_IP:
948 					ip_print(p + 2, length - 2);
949 					break;
950 				case PPP_IPV6:
951 					ip6_print(p + 2, length - 2);
952 					break;
953 				case PPP_IPX:
954 					ipx_print(p + 2, length - 2);
955 				}
956 				break;
957 			}
958 		}
959 		if (i < 0)
960 			printf("\n\t%04x: ", proto);
961 	}
962 
963 	return (1);
964 }
965 
966 #else
967 
968 #include <sys/types.h>
969 #include <sys/time.h>
970 
971 #include <stdio.h>
972 
973 #include "interface.h"
974 void
975 ppp_if_print(user, h, p)
976 	u_char *user;
977 	const struct pcap_pkthdr *h;
978 	const u_char *p;
979 {
980 	error("not configured for ppp");
981 	/* NOTREACHED */
982 }
983 #endif
984