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