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