xref: /openbsd/usr.sbin/tcpdump/print-ppp.c (revision e5dd7070)
1 /*	$OpenBSD: print-ppp.c,v 1.34 2020/01/24 22:46:37 procter 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 #ifndef nitems
52 #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
53 #endif
54 
55 #ifndef PPP_EAP
56 #define PPP_EAP 0xc227
57 #endif
58 
59 #ifndef PPP_CDP
60 #define PPP_CDP 0x0207
61 #endif
62 
63 #ifndef PPP_CDPCP
64 #define PPP_CDPCP 0x8207
65 #endif
66 
67 struct protonames {
68 	u_short protocol;
69 	char *name;
70 };
71 
72 static const struct protonames protonames[] = {
73 	/*
74 	 * Protocol field values.
75 	 */
76 	{ PPP_IP,	"IP" },		/* Internet Protocol */
77 	{ PPP_XNS,	"XNS" },	/* Xerox NS */
78 	{ PPP_IPX,	"IPX" },	/* IPX Datagram (RFC1552) */
79 	{ PPP_AT,	"AppleTalk" },	/* AppleTalk Protocol */
80 	{ PPP_VJC_COMP,	"VJC_UNCOMP" },	/* VJ compressed TCP */
81 	{ PPP_VJC_UNCOMP,"VJC_UNCOMP" },/* VJ uncompressed TCP */
82 	{ PPP_IPV6,	"IPv6" },	/* Internet Protocol version 6 */
83 	{ PPP_COMP,	"COMP" },	/* compressed packet */
84 	{ PPP_IPCP,	"IPCP" },	/* IP Control Protocol */
85 	{ PPP_ATCP,	"AppleTalkCP" },/* AppleTalk Control Protocol */
86 	{ PPP_IPXCP,	"IPXCP" },	/* IPX Control Protocol (RFC1552) */
87 	{ PPP_IPV6CP,	"IPV6CP" },	/* IPv6 Control Protocol */
88 	{ PPP_CCP,	"CCP" },	/* Compression Control Protocol */
89 	{ PPP_LCP,	"LCP" },	/* Link Control Protocol */
90 	{ PPP_PAP,	"PAP" },	/* Password Authentication Protocol */
91 	{ PPP_LQR,	"LQR" },	/* Link Quality Report protocol */
92 	{ PPP_CBCP,	"CBCP" },	/* Callback Control Protocol */
93 	{ PPP_CHAP,	"CHAP" },	/* Cryptographic Handshake Auth. Proto */
94 	{ PPP_EAP,	"EAP" },	/* Extensible Auth. Protocol */
95 	{ PPP_CDP,	"CDP" },
96 	{ PPP_CDPCP,	"CDPCP" },
97 };
98 
99 struct ppp_control {
100 	uint8_t		code;
101 	uint8_t		id;
102 	uint16_t	len;
103 };
104 
105 struct ppp_cp_type {
106 	const char	 *unkname;
107 	int		  mincode;
108 	int		  maxcode;
109 	const char 	**codes;
110 };
111 
112 /* LCP */
113 
114 #define LCP_CONF_REQ	1
115 #define LCP_CONF_ACK	2
116 #define LCP_CONF_NAK	3
117 #define LCP_CONF_REJ	4
118 #define LCP_TERM_REQ	5
119 #define LCP_TERM_ACK	6
120 #define LCP_CODE_REJ	7
121 #define LCP_PROT_REJ	8
122 #define LCP_ECHO_REQ	9
123 #define LCP_ECHO_RPL	10
124 #define LCP_DISC_REQ	11
125 
126 #define LCP_MIN	LCP_CONF_REQ
127 #define LCP_MAX LCP_DISC_REQ
128 
129 static const char *lcpcodes[] = {
130 	/*
131 	 * LCP code values (RFC1661, pp26)
132 	 */
133 	"Configure-Request",
134 	"Configure-Ack",
135 	"Configure-Nak",
136 	"Configure-Reject",
137 	"Terminate-Request",
138 	"Terminate-Ack",
139  	"Code-Reject",
140 	"Protocol-Reject",
141 	"Echo-Request",
142 	"Echo-Reply",
143 	"Discard-Request",
144 };
145 
146 #define LCPOPT_VEXT	0
147 #define LCPOPT_MRU	1
148 #define LCPOPT_ACCM	2
149 #define LCPOPT_AP	3
150 #define LCPOPT_QP	4
151 #define LCPOPT_MN	5
152 #define LCPOPT_PFC	7
153 #define LCPOPT_ACFC	8
154 
155 #define LCPOPT_MIN 0
156 #define LCPOPT_MAX 24
157 
158 static char *lcpconfopts[] = {
159 	"Vendor-Ext",
160 	"Max-Rx-Unit",
161 	"Async-Ctrl-Char-Map",
162 	"Auth-Prot",
163 	"Quality-Prot",
164 	"Magic-Number",
165 	"unassigned (6)",
166 	"Prot-Field-Compr",
167 	"Add-Ctrl-Field-Compr",
168 	"FCS-Alternatives",
169 	"Self-Describing-Pad",
170 	"Numbered-Mode",
171 	"Multi-Link-Procedure",
172 	"Call-Back",
173 	"Connect-Time"
174 	"Compund-Frames",
175 	"Nominal-Data-Encap",
176 	"Multilink-MRRU",
177 	"Multilink-SSNHF",
178 	"Multilink-ED",
179 	"Proprietary",
180 	"DCE-Identifier",
181 	"Multilink-Plus-Proc",
182 	"Link-Discriminator",
183 	"LCP-Auth-Option",
184 };
185 
186 /* CHAP */
187 
188 #define CHAP_CHAL	1
189 #define CHAP_RESP	2
190 #define CHAP_SUCC	3
191 #define CHAP_FAIL	4
192 
193 #define CHAP_CODEMIN 1
194 #define CHAP_CODEMAX 4
195 
196 static const char *chapcode[] = {
197 	"Challenge",
198 	"Response",
199 	"Success",
200 	"Failure",
201 };
202 
203 /* PAP */
204 
205 #define PAP_AREQ	1
206 #define PAP_AACK	2
207 #define PAP_ANAK	3
208 
209 #define PAP_CODEMIN	1
210 #define PAP_CODEMAX	3
211 
212 static const char *papcode[] = {
213 	"Authenticate-Request",
214 	"Authenticate-Ack",
215 	"Authenticate-Nak",
216 };
217 
218 /* EAP */
219 
220 #define EAP_CHAL	1
221 #define EAP_RESP	2
222 #define EAP_SUCC	3
223 #define EAP_FAIL	4
224 
225 #define EAP_CODEMIN	EAP_CHAL
226 #define EAP_CODEMAX	EAP_FAIL
227 
228 #define EAP_TYPE_IDENTITY	1
229 #define EAP_TYPE_NOTIFICATION	2
230 #define EAP_TYPE_NAK		3
231 #define EAP_TYPE_MD5_CHALLENGE	4
232 #define EAP_TYPE_OTP		5
233 #define EAP_TYPE_TOKEN		6
234 
235 #define EAP_TYPEMIN		EAP_TYPE_IDENTITY
236 #define EAP_TYPEMAX		EAP_TYPE_TOKEN
237 
238 static const char *eapcode[] = {
239 	"Challenge",
240 	"Response",
241 	"Success",
242 	"Failure",
243 };
244 
245 static const char *eaptype[] = {
246 	"Identity",
247 	"Notification",
248 	"Nak",
249 	"MD5-Challenge",
250 	"One-Time-Password",
251 	"Token",
252 };
253 
254 
255 /* IPCP */
256 
257 #define IPCP_CODE_CFG_REQ	1
258 #define IPCP_CODE_CFG_ACK	2
259 #define IPCP_CODE_CFG_NAK	3
260 #define IPCP_CODE_CFG_REJ	4
261 #define IPCP_CODE_TRM_REQ	5
262 #define IPCP_CODE_TRM_ACK	6
263 #define IPCP_CODE_COD_REJ	7
264 
265 #define IPCP_CODE_MIN IPCP_CODE_CFG_REQ
266 #define IPCP_CODE_MAX IPCP_CODE_COD_REJ
267 
268 #define IPCP_2ADDR	1
269 #define IPCP_CP		2
270 #define IPCP_ADDR	3
271 
272 /* IPV6CP */
273 
274 #define IPV6CP_CODE_CFG_REQ	1
275 #define IPV6CP_CODE_CFG_ACK	2
276 #define IPV6CP_CODE_CFG_NAK	3
277 #define IPV6CP_CODE_CFG_REJ	4
278 #define IPV6CP_CODE_TRM_REQ	5
279 #define IPV6CP_CODE_TRM_ACK	6
280 #define IPV6CP_CODE_COD_REJ	7
281 
282 #define IPV6CP_CODE_MIN IPV6CP_CODE_CFG_REQ
283 #define IPV6CP_CODE_MAX IPV6CP_CODE_COD_REJ
284 
285 #define IPV6CP_IFID	1
286 
287 static int print_lcp_config_options(const u_char *p, int);
288 static void handle_lcp(const u_char *, int);
289 static void handle_chap(const u_char *p, int);
290 static void handle_eap(const u_char *p, int);
291 static void handle_ipcp(const u_char *p, int);
292 static int print_ipcp_config_options(const u_char *, int);
293 static void handle_ipv6cp(const u_char *p, int);
294 static int print_ipv6cp_config_options(const u_char *, int);
295 static void handle_pap(const u_char *p, int);
296 
297 struct pppoe_header {
298 	u_int8_t vertype;	/* PPPoE version/type */
299 	u_int8_t code;		/* PPPoE code (packet type) */
300 	u_int16_t sessionid;	/* PPPoE session id */
301 	u_int16_t len;		/* PPPoE payload length */
302 };
303 #define	PPPOE_CODE_SESSION	0x00	/* Session */
304 #define	PPPOE_CODE_PADO		0x07	/* Active Discovery Offer */
305 #define	PPPOE_CODE_PADI		0x09	/* Active Discovery Initiation */
306 #define	PPPOE_CODE_PADR		0x19	/* Active Discovery Request */
307 #define	PPPOE_CODE_PADS		0x65	/* Active Discovery Session-Confirm */
308 #define	PPPOE_CODE_PADT		0xa7	/* Active Discovery Terminate */
309 #define	PPPOE_TAG_END_OF_LIST		0x0000	/* End Of List */
310 #define	PPPOE_TAG_SERVICE_NAME		0x0101	/* Service Name */
311 #define	PPPOE_TAG_AC_NAME		0x0102	/* Access Concentrator Name */
312 #define	PPPOE_TAG_HOST_UNIQ		0x0103	/* Host Uniq */
313 #define	PPPOE_TAG_AC_COOKIE		0x0104	/* Access Concentratr Cookie */
314 #define	PPPOE_TAG_VENDOR_SPEC		0x0105	/* Vendor Specific */
315 #define	PPPOE_TAG_RELAY_SESSION		0x0110	/* Relay Session Id */
316 #define	PPPOE_TAG_MAX_PAYLOAD		0x0120	/* RFC 4638 Max Payload */
317 #define	PPPOE_TAG_SERVICE_NAME_ERROR	0x0201	/* Service Name Error */
318 #define	PPPOE_TAG_AC_SYSTEM_ERROR	0x0202	/* Acc. Concentrator Error */
319 #define	PPPOE_TAG_GENERIC_ERROR		0x0203	/* Generic Error */
320 
321 static void
322 ppp_protoname(uint16_t proto)
323 {
324 	const struct protonames *protoname;
325 	int i;
326 
327 	/* bsearch? */
328 	for (i = 0; i < nitems(protonames); i++) {
329 		protoname = &protonames[i];
330 
331 		if (proto == protoname->protocol) {
332 			printf("%s ", protoname->name);
333 			return;
334 		}
335 	}
336 
337 	printf("unknown-ppp-%04x", proto);
338 }
339 
340 void
341 ppp_print(const u_char *p, u_int length)
342 {
343 	uint16_t proto;
344 	int l;
345 
346 	l = snapend - p;
347 
348 	if (l < sizeof(proto)) {
349 		printf("[|ppp]");
350 		return;
351 	}
352 
353 	proto = EXTRACT_16BITS(p);
354 
355 	p += sizeof(proto);
356 	l -= sizeof(proto);
357 	length -= sizeof(proto);
358 
359 	if (eflag)
360 		ppp_protoname(proto);
361 
362 	switch (proto) {
363 	case PPP_IP:
364 		ip_print(p, length);
365 		return;
366 	case PPP_IPV6:
367 		ip6_print(p, length);
368 		return;
369 	}
370 
371 	if (!eflag)
372 		ppp_protoname(proto);
373 
374 	switch(proto) {
375 	case PPP_LCP:
376 		handle_lcp(p, l);
377 		break;
378 	case PPP_CHAP:
379 		handle_chap(p, l);
380 		break;
381 	case PPP_EAP:
382 		handle_eap(p, l);
383 		break;
384 	case PPP_PAP:
385 		handle_pap(p, l);
386 		break;
387 	case PPP_IPCP:
388 		handle_ipcp(p, l);
389 		break;
390 	case PPP_IPV6CP:
391 		handle_ipv6cp(p, l);
392 		break;
393 	case PPP_CDP:
394 		cdp_print(p, length, l, 0);
395 		break;
396 	}
397 }
398 
399 static int
400 ppp_cp_header(struct ppp_control *pc, const u_char *p, int l,
401     const struct ppp_cp_type *t)
402 {
403 	uint8_t code;
404 	int off = 0;
405 	int len;
406 
407 	len = sizeof(pc->code);
408 	if (l < len)
409 		return (-1);
410 
411 	pc->code = code = *(p + off);
412 	if (code >= t->mincode && code <= t->maxcode)
413 		printf("%s ", t->codes[code - 1]);
414 	else
415 		printf("unknown-%s-%u ", t->unkname, pc->code);
416 
417 	off = len;
418 	len += sizeof(pc->id);
419 	if (l < len)
420 		return (-1);
421 
422 	pc->id = *(p + off);
423 	printf("Id=0x%02x:", pc->id);
424 
425 	off = len;
426 	len += sizeof(pc->len);
427 	if (l < len)
428 		return (-1);
429 
430 	pc->len = EXTRACT_16BITS(p + off);
431 
432 	return (len);
433 }
434 
435 /* print LCP frame */
436 
437 static const struct ppp_cp_type ppp_cp_lcp = {
438 	"lcp",
439 	LCP_MIN, LCP_MAX,
440 	lcpcodes,
441 };
442 
443 static void
444 handle_lcp(const u_char *p, int l)
445 {
446 	struct ppp_control pc;
447 	int i;
448 
449 	if (ppp_cp_header(&pc, p, l, &ppp_cp_lcp) == -1)
450 		goto trunc;
451 
452 	if (l > pc.len)
453 		l = pc.len;
454 
455 	p += sizeof(pc);
456 	l -= sizeof(pc);
457 
458 	switch (pc.code) {
459 	case LCP_CONF_REQ:
460 	case LCP_CONF_ACK:
461 	case LCP_CONF_NAK:
462 	case LCP_CONF_REJ:
463 		while (l > 0) {
464 			int optlen;
465 
466 			optlen = print_lcp_config_options(p, l);
467 			if (optlen == -1)
468 				goto trunc;
469 			if (optlen == 0)
470 				break;
471 
472 			p += optlen;
473 			l -= optlen;
474 		}
475 		break;
476 	case LCP_ECHO_REQ:
477 	case LCP_ECHO_RPL:
478 		if (l < 4)
479 			goto trunc;
480 		printf(" Magic-Number=%u", EXTRACT_32BITS(p));
481 		p += 4;
482 		l -= 4;
483 
484 		i = sizeof(pc) + 4;
485 		if (i == pc.len)
486 			break;
487 
488 		printf(" Data=");
489 		do {
490 			if (l == 0)
491 				goto trunc;
492 
493 			printf("%02x", *p);
494 
495 			p++;
496 			l--;
497 		} while (++i < pc.len);
498 		break;
499 	case LCP_TERM_REQ:
500 	case LCP_TERM_ACK:
501 	case LCP_CODE_REJ:
502 	case LCP_PROT_REJ:
503 	case LCP_DISC_REQ:
504 	default:
505 		break;
506 	}
507 	return;
508 
509 trunc:
510 	printf("[|lcp]");
511 }
512 
513 /* LCP config options */
514 
515 static int
516 print_lcp_config_options(const u_char *p, int l)
517 {
518 	uint8_t type, length;
519 	uint16_t proto;
520 
521 	if (l < sizeof(type))
522 		return (-1);
523 
524 	type = p[0];
525 	if (type <= LCPOPT_MAX)
526 		printf(" %s", lcpconfopts[type]);
527 	else
528 		printf(" unknown-lcp-%u", type);
529 
530 	if (l < sizeof(type) + sizeof(length))
531 		return (-1);
532 
533 	length = p[1];
534 
535 	if (length < sizeof(type) + sizeof(length))
536 		return (0);
537 
538 	if (l > length)
539 		l = length;
540 
541 	p += sizeof(type) + sizeof(length);
542 	l -= sizeof(type) + sizeof(length);
543 
544 	switch (type) {
545 	case LCPOPT_MRU:
546 		if (length != 4)
547 			goto invalid;
548 		if (l < 2)
549 			return (-1);
550 
551 		printf("=%u", EXTRACT_16BITS(p));
552 		break;
553 	case LCPOPT_AP:
554 		if (length < 4)
555 			goto invalid;
556 		if (l < sizeof(proto))
557 			return (-1);
558 
559 		proto = EXTRACT_16BITS(p);
560 		switch (proto) {
561 		case PPP_PAP:
562 			printf("=PAP");
563 			break;
564 		case PPP_CHAP:
565 			printf("=CHAP");
566 			if (length < 5)
567 				goto invalid;
568 
569 			p += sizeof(proto);
570 			l -= sizeof(proto);
571 
572 			type = *p;
573 			switch (type) {
574 			case 0x05:
575 				printf("/MD5");
576 				break;
577 			case 0x80:
578 				printf("/Microsoft");
579 				break;
580 			default:
581 				printf("/unknown-algorithm-%02x", type);
582 				break;
583 			}
584 			break;
585 		case PPP_EAP:
586 			printf("=EAP");
587 			break;
588 		case 0xc027:
589 			printf("=SPAP");
590 			break;
591 		case 0xc127:
592 			printf("=Old-SPAP");
593 			break;
594 		default:
595 			printf("=unknown-ap-%04x", proto);
596 			break;
597 		}
598 		break;
599 	case LCPOPT_QP:
600 		if (length < 4)
601 			goto invalid;
602 		if (l < sizeof(proto))
603 			return (-1);
604 
605 		proto = EXTRACT_16BITS(p);
606 		switch (proto) {
607 		case PPP_LQR:
608 			printf(" LQR");
609 			break;
610 		default:
611 			printf(" unknown-qp-%u", proto);
612 		}
613 		break;
614 	case LCPOPT_MN:
615 		if (length < 6)
616 			goto invalid;
617 		if (l < 4)
618 			return (-1);
619 
620 		printf("=%u", EXTRACT_32BITS(p));
621 		break;
622 	case LCPOPT_PFC:
623 		printf(" PFC");
624 		break;
625 	case LCPOPT_ACFC:
626 		printf(" ACFC");
627 		break;
628 	}
629 
630 	return (length);
631 
632 invalid:
633 	printf(" invalid opt len %u", length);
634 	return (length);
635 }
636 
637 /* CHAP */
638 
639 static const struct ppp_cp_type ppp_cp_chap = {
640 	"chap",
641 	CHAP_CODEMIN, CHAP_CODEMAX,
642 	chapcode,
643 };
644 
645 static void
646 handle_chap(const u_char *p, int l)
647 {
648 	struct ppp_control pc;
649 	uint8_t vsize;
650 	int i;
651 
652 	if (ppp_cp_header(&pc, p, l, &ppp_cp_chap) == -1)
653 		goto trunc;
654 
655 	if (l > pc.len)
656 		l = pc.len;
657 
658 	p += sizeof(pc);
659 	l -= sizeof(pc);
660 
661 	switch (pc.code) {
662 	case CHAP_CHAL:
663 	case CHAP_RESP:
664 		if (l < sizeof(vsize))
665 			goto trunc;
666 
667 		vsize = *p;
668 		if (vsize < 1) {
669 			printf(" invalid Value-Size");
670 			return;
671 		}
672 
673 		p += sizeof(vsize);
674 		l -= sizeof(vsize);
675 
676 		printf(" Value=");
677 		for (i = 0; i < vsize; i++) {
678 			if (l == 0)
679 				goto trunc;
680 
681 			printf("%02x", *p);
682 
683 			p++;
684 			l--;
685 		}
686 
687 		printf(" Name=");
688 		for (i += sizeof(pc) + sizeof(vsize); i < pc.len; i++) {
689 			if (l == 0)
690 				goto trunc;
691 
692 			safeputchar(*p);
693 
694 			p++;
695 			l--;
696 		}
697 		break;
698 	case CHAP_SUCC:
699 	case CHAP_FAIL:
700 		printf(" Message=");
701 		for (i = sizeof(pc); i < pc.len; i++) {
702 			if (l == 0)
703 				goto trunc;
704 
705 			safeputchar(*p);
706 
707 			p++;
708 			l--;
709 		}
710 		break;
711 	}
712 	return;
713 
714 trunc:
715 	printf("[|chap]");
716 }
717 
718 /* EAP */
719 
720 static const struct ppp_cp_type ppp_cp_eap = {
721 	"eap",
722 	EAP_CODEMIN, EAP_CODEMAX,
723 	eapcode,
724 };
725 
726 static void
727 handle_eap(const u_char *p, int l)
728 {
729 	struct ppp_control pc;
730 	uint8_t type, vsize;
731 	int i;
732 
733 	if (ppp_cp_header(&pc, p, l, &ppp_cp_eap) == -1)
734 		goto trunc;
735 
736 	if (l > pc.len)
737 		l = pc.len;
738 
739 	p += sizeof(pc);
740 	l -= sizeof(pc);
741 
742 	switch (pc.code) {
743 	case EAP_CHAL:
744 	case EAP_RESP:
745 		if (l < sizeof(type))
746 			goto trunc;
747 
748 		type = *p;
749 		p += sizeof(type);
750 		l -= sizeof(type);
751 
752 		if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX)
753 			printf(" %s", eaptype[type - 1]);
754 		else {
755 			printf(" unknown-eap-type-%u", type);
756 			return;
757 		}
758 
759 		switch (type) {
760 		case EAP_TYPE_IDENTITY:
761 		case EAP_TYPE_NOTIFICATION:
762 		case EAP_TYPE_OTP:
763 			i = sizeof(pc) + sizeof(type);
764 			if (i == pc.len)
765 				break;
766 
767 			printf("=");
768 			do {
769 				if (l == 0)
770 					goto trunc;
771 
772 				safeputchar(*p);
773 
774 				p++;
775 				l--;
776 			} while (++i < pc.len);
777 			break;
778 
779 		case EAP_TYPE_NAK:
780 			if (l < sizeof(type))
781 				goto trunc;
782 			type = *p;
783 			if (type >= EAP_TYPEMIN && type <= EAP_TYPEMAX)
784 				printf(" %s", eaptype[type - 1]);
785 			else
786 				printf(" unknown-eap-type-%u", type);
787 			break;
788 		case EAP_TYPE_MD5_CHALLENGE:
789 			if (l < sizeof(vsize))
790 				goto trunc;
791 
792 			vsize = *p;
793 			p += sizeof(vsize);
794 			l -= sizeof(vsize);
795 
796 			printf("=");
797 			for (i = 0; i < vsize; i++) {
798 				if (l == 0)
799 					goto trunc;
800 
801 				printf("%02x", *p);
802 
803 				p++;
804 				l--;
805 			}
806 			break;
807 		}
808 		break;
809 	case CHAP_SUCC:
810 	case CHAP_FAIL:
811 		break;
812 	}
813 	return;
814 
815 trunc:
816 	printf("[|eap]");
817 }
818 
819 /* PAP */
820 
821 static const struct ppp_cp_type ppp_cp_pap = {
822 	"pap",
823 	PAP_CODEMIN, PAP_CODEMAX,
824 	papcode,
825 };
826 
827 static void
828 handle_pap(const u_char *p, int l)
829 {
830 	struct ppp_control pc;
831 	uint8_t x;
832 	int i;
833 
834 	if (ppp_cp_header(&pc, p, l, &ppp_cp_pap) == -1)
835 		goto trunc;
836 
837 	if (l > pc.len)
838 		l = pc.len;
839 
840 	p += sizeof(pc);
841 	l -= sizeof(pc);
842 
843 	switch (pc.code) {
844 	case PAP_AREQ:
845 		if (l < sizeof(x)) /* Peer-ID Length */
846 			goto trunc;
847 
848 		x = *p;
849 
850 		p += sizeof(x);
851 		l -= sizeof(x);
852 
853 		printf(" Peer-Id=");
854 		for (i = 0; i < x; i++) {
855 			if (l == 0)
856 				goto trunc;
857 
858 			safeputchar(*p);
859 
860 			p++;
861 			l--;
862 		}
863 
864 		if (l < sizeof(x)) /* Passwd-Length */
865 			goto trunc;
866 
867 		x = *p;
868 
869 		p += sizeof(x);
870 		l -= sizeof(x);
871 
872 		printf(" Passwd=");
873 		for (i = 0; i < x; i++) {
874 			if (l == 0)
875 				goto trunc;
876 
877 			safeputchar(*p);
878 
879 			p++;
880 			l--;
881 		}
882 		break;
883 
884 	case PAP_AACK:
885 	case PAP_ANAK:
886 		if (l < sizeof(x)) /* Msg-Length */
887 			goto trunc;
888 
889 		x = *p;
890 
891 		p += sizeof(x);
892 		l -= sizeof(x);
893 
894 		printf(" Message=");
895 		for (i = 0; i < x; i++) {
896 			if (l == 0)
897 				goto trunc;
898 
899 			safeputchar(*p);
900 
901 			p++;
902 			l--;
903 		}
904 		break;
905 	}
906 
907 	return;
908 
909 trunc:
910 	printf("[|pap]");
911 }
912 
913 /* IPCP */
914 
915 #define IP_LEN 4
916 #define IP_FMT "%u.%u.%u.%u"
917 #define IP_ARG(_p) (_p)[0], (_p)[1], (_p)[2], (_p)[3]
918 
919 static const struct ppp_cp_type ppp_cp_ipcp = {
920 	"ipcp",
921 	IPCP_CODE_MIN, IPCP_CODE_MAX,
922 	lcpcodes,
923 };
924 
925 static void
926 handle_ipcp(const u_char *p, int l)
927 {
928 	struct ppp_control pc;
929 
930 	if (ppp_cp_header(&pc, p, l, &ppp_cp_ipcp) == -1)
931 		goto trunc;
932 
933 	if (l > pc.len)
934 		l = pc.len;
935 
936 	p += sizeof(pc);
937 	l -= sizeof(pc);
938 
939 	switch (pc.code) {
940 	case IPCP_CODE_CFG_REQ:
941 	case IPCP_CODE_CFG_ACK:
942 	case IPCP_CODE_CFG_NAK:
943 	case IPCP_CODE_CFG_REJ:
944 		while (l > 0) {
945 			int optlen;
946 
947 			optlen = print_ipcp_config_options(p, l);
948 			if (optlen == -1)
949 				goto trunc;
950 			if (optlen == 0)
951 				break;
952 
953 			p += optlen;
954 			l -= optlen;
955 		}
956 		break;
957 
958 	case IPCP_CODE_TRM_REQ:
959 	case IPCP_CODE_TRM_ACK:
960 	case IPCP_CODE_COD_REJ:
961 	default:
962 		break;
963 	}
964 
965 	return;
966 
967 trunc:
968 	printf("[|ipcp]");
969 }
970 
971 static int
972 print_ipcp_config_options(const u_char *p, int l)
973 {
974 	uint8_t type, length;
975 
976 	if (l < sizeof(type))
977 		return (-1);
978 
979 	type = p[0];
980 	switch (type) {
981 	case IPCP_2ADDR:
982 		printf(" IP-Addresses");
983 		break;
984 	case IPCP_CP:
985 		printf(" IP-Compression-Protocol");
986 		break;
987 	case IPCP_ADDR:
988 		printf(" IP-Address");
989 		break;
990 	default:
991 		printf(" ipcp-type-%u", type);
992 		break;
993 	}
994 
995 	if (l < sizeof(type) + sizeof(length))
996 		return (-1);
997 
998 	length = p[1];
999 
1000 	p += (sizeof(type) + sizeof(length));
1001 	l -= (sizeof(type) + sizeof(length));
1002 
1003 	switch (type) {
1004 	case IPCP_2ADDR:
1005 		if (length != 10)
1006 			goto invalid;
1007 		if (l < IP_LEN)
1008 			return (-1);
1009 
1010 		printf(" Src=" IP_FMT, IP_ARG(p));
1011 
1012 		p += IP_LEN;
1013 		l -= IP_LEN;
1014 
1015 		if (l < IP_LEN)
1016 			return (-1);
1017 
1018 		printf(" Dst=" IP_FMT, IP_ARG(p));
1019 		break;
1020 	case IPCP_CP:
1021 		if (length < 4)
1022 			goto invalid;
1023 		if (l < sizeof(type))
1024 			return (-1);
1025 
1026 		type = EXTRACT_16BITS(p);
1027 		switch (type) {
1028 		case 0x0037:
1029 			printf(" Van Jacobsen Compressed TCP/IP");
1030 			break;
1031 		default:
1032 			printf("ipcp-compression-type-%u", type);
1033 			break;
1034 		}
1035 		break;
1036 	case IPCP_ADDR:
1037 		if (length != 6)
1038 			goto invalid;
1039 		if (l < IP_LEN)
1040 			return (-1);
1041 
1042 		printf("=" IP_FMT, IP_ARG(p));
1043 		break;
1044 	}
1045 
1046 	return (length);
1047 
1048 invalid:
1049 	printf(" invalid opt len %u", length);
1050 	return (length);
1051 }
1052 
1053 /* IPV6CP */
1054 
1055 static const struct ppp_cp_type ppp_cp_ipv6cp = {
1056 	"ipv6cp",
1057 	IPV6CP_CODE_MIN, IPV6CP_CODE_MAX,
1058 	lcpcodes,
1059 };
1060 
1061 static void
1062 handle_ipv6cp(const u_char *p, int l)
1063 {
1064 	struct ppp_control pc;
1065 
1066 	if (ppp_cp_header(&pc, p, l, &ppp_cp_ipv6cp) == -1)
1067 		goto trunc;
1068 
1069 	if (l > pc.len)
1070 		l = pc.len;
1071 
1072 	p += sizeof(pc);
1073 	l -= sizeof(pc);
1074 
1075 	switch (pc.code) {
1076 	case IPV6CP_CODE_CFG_REQ:
1077 	case IPV6CP_CODE_CFG_ACK:
1078 	case IPV6CP_CODE_CFG_NAK:
1079 	case IPV6CP_CODE_CFG_REJ:
1080 		while (l > 0) {
1081 			int optlen;
1082 
1083 			optlen = print_ipv6cp_config_options(p, l);
1084 			if (optlen == -1)
1085 				goto trunc;
1086 			if (optlen == 0)
1087 				break;
1088 
1089 			p += optlen;
1090 			l -= optlen;
1091 		}
1092 		break;
1093 
1094 	case IPV6CP_CODE_TRM_REQ:
1095 	case IPV6CP_CODE_TRM_ACK:
1096 	case IPV6CP_CODE_COD_REJ:
1097 	default:
1098 		break;
1099 	}
1100 
1101 	return;
1102 
1103 trunc:
1104 	printf("[|ipv6cp]");
1105 }
1106 
1107 static int
1108 print_ipv6cp_config_options(const u_char *p, int l)
1109 {
1110 	uint8_t type, length;
1111 
1112 	if (l < sizeof(type))
1113 		return (-1);
1114 
1115 	type = p[0];
1116 	switch (type) {
1117 	case IPV6CP_IFID:
1118 		printf(" IPv6-Interface-Id");
1119 		break;
1120 	default:
1121 		printf(" ipv6cp-type-%u", type);
1122 		break;
1123 	}
1124 
1125 	if (l < sizeof(type) + sizeof(length))
1126 		return (-1);
1127 
1128 	length = p[1];
1129 
1130 	p += (sizeof(type) + sizeof(length));
1131 	l -= (sizeof(type) + sizeof(length));
1132 
1133 	switch (type) {
1134 	case IPV6CP_IFID:
1135 		if (length != 10)
1136 			goto invalid;
1137 		if (l < 8)
1138 			return (-1);
1139 
1140 		printf("=%04x:%04x:%04x:%04x", EXTRACT_16BITS(p + 0),
1141 		    EXTRACT_16BITS(p + 2), EXTRACT_16BITS(p + 4),
1142 		    EXTRACT_16BITS(p + 6));
1143 		break;
1144 	default:
1145 		break;
1146 	}
1147 
1148 	return (length);
1149 invalid:
1150 	printf(" invalid opt len %u", length);
1151 	return (length);
1152 }
1153 
1154 void
1155 ppp_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
1156 {
1157 	u_int length = h->len;
1158 	u_int caplen = h->caplen;
1159 
1160 	packetp = p;
1161 	snapend = p + caplen;
1162 
1163 	ts_print(&h->ts);
1164 
1165 	ppp_hdlc_print(p, length);
1166 
1167 	if (xflag)
1168 		default_print((const u_char *)(p + PPP_HDRLEN),
1169 		    caplen - PPP_HDRLEN);
1170 
1171 	putchar('\n');
1172 }
1173 
1174 void
1175 ppp_ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
1176 {
1177 	u_int16_t pppoe_sid, pppoe_len;
1178 	u_int l = h->caplen;
1179 	u_int length = h->len;
1180 
1181 	packetp = p;
1182 	snapend = p + l;
1183 
1184 	ts_print(&h->ts);
1185 
1186 	if (eflag)
1187 		printf("PPPoE ");
1188 
1189 	if (l < sizeof(struct pppoe_header)) {
1190 		printf("[|pppoe]");
1191 		return;
1192 	}
1193 
1194 	pppoe_sid = EXTRACT_16BITS(p + 2);
1195 	pppoe_len = EXTRACT_16BITS(p + 4);
1196 
1197 	if (eflag) {
1198 		printf("\n\tcode ");
1199 		switch (p[1]) {
1200 		case PPPOE_CODE_PADI:
1201 			printf("Initiation");
1202 			break;
1203 		case PPPOE_CODE_PADO:
1204 			printf("Offer");
1205 			break;
1206 		case PPPOE_CODE_PADR:
1207 			printf("Request");
1208 			break;
1209 		case PPPOE_CODE_PADS:
1210 			printf("Confirm");
1211 			break;
1212 		case PPPOE_CODE_PADT:
1213 			printf("Terminate");
1214 			break;
1215 		case PPPOE_CODE_SESSION:
1216 			printf("Session");
1217 			break;
1218 		default:
1219 			printf("Unknown(0x%02x)", p[1]);
1220 			break;
1221 		}
1222 		printf(", version %d, type %d, id 0x%04x, length %d\n\t",
1223 		    (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
1224 	}
1225 
1226 	if (length < pppoe_len) {
1227                 printf(" truncated-pppoe - %d bytes missing!",
1228                     pppoe_len - length);
1229                 pppoe_len = length;
1230         }
1231 
1232 	ppp_print(p + sizeof(struct pppoe_header), pppoe_len);
1233 
1234 	if (xflag)
1235 		default_print(p, h->caplen);
1236 
1237 	putchar('\n');
1238 }
1239 
1240 int
1241 pppoe_if_print(u_short ethertype, const u_char *p, u_int length, u_int l)
1242 {
1243 	uint16_t pppoe_sid, pppoe_len;
1244 
1245 	if (ethertype == ETHERTYPE_PPPOEDISC)
1246 		printf("PPPoE-Discovery");
1247 	else
1248 		printf("PPPoE-Session");
1249 
1250 	if (l < sizeof(struct pppoe_header))
1251 		goto trunc;
1252 
1253 	printf("\n\tcode ");
1254 	switch (p[1]) {
1255 	case PPPOE_CODE_PADI:
1256 		printf("Initiation");
1257 		break;
1258 	case PPPOE_CODE_PADO:
1259 		printf("Offer");
1260 		break;
1261 	case PPPOE_CODE_PADR:
1262 		printf("Request");
1263 		break;
1264 	case PPPOE_CODE_PADS:
1265 		printf("Confirm");
1266 		break;
1267 	case PPPOE_CODE_PADT:
1268 		printf("Terminate");
1269 		break;
1270 	case PPPOE_CODE_SESSION:
1271 		printf("Session");
1272 		break;
1273 	default:
1274 		printf("Unknown(0x%02x)", p[1]);
1275 		break;
1276 	}
1277 
1278 	pppoe_sid = EXTRACT_16BITS(p + 2);
1279 	pppoe_len = EXTRACT_16BITS(p + 4);
1280 	printf(", version %d, type %d, id 0x%04x, length %d",
1281 	    (p[0] & 0xf), (p[0] & 0xf0) >> 4, pppoe_sid, pppoe_len);
1282 
1283 	p += sizeof(struct pppoe_header);
1284 	l -= sizeof(struct pppoe_header);
1285 	length -= sizeof(struct pppoe_header);
1286 
1287 	if (length < pppoe_len) {
1288                 printf(" truncated-pppoe - %d bytes missing!",
1289                     pppoe_len - length);
1290                 pppoe_len = length;
1291         }
1292 
1293 	if (l > pppoe_len)
1294 		l = pppoe_len;
1295 
1296 	if (ethertype == ETHERTYPE_PPPOEDISC) {
1297 		while (l > 0) {
1298 			u_int16_t t_type, t_len;
1299 
1300 			if (l < 4)
1301 				goto trunc;
1302 			t_type = EXTRACT_16BITS(p);
1303 			t_len = EXTRACT_16BITS(p + 2);
1304 
1305 			p += 4;
1306 			l -= 4;
1307 
1308 			if (l < t_len)
1309 				goto trunc;
1310 
1311 			printf("\n\ttag ");
1312 			switch (t_type) {
1313 			case PPPOE_TAG_END_OF_LIST:
1314 				printf("End-Of-List");
1315 				break;
1316 			case PPPOE_TAG_SERVICE_NAME:
1317 				printf("Service-Name");
1318 				break;
1319 			case PPPOE_TAG_AC_NAME:
1320 				printf("AC-Name");
1321 				break;
1322 			case PPPOE_TAG_HOST_UNIQ:
1323 				printf("Host-Uniq");
1324 				break;
1325 			case PPPOE_TAG_AC_COOKIE:
1326 				printf("AC-Cookie");
1327 				break;
1328 			case PPPOE_TAG_VENDOR_SPEC:
1329 				printf("Vendor-Specific");
1330 				break;
1331 			case PPPOE_TAG_RELAY_SESSION:
1332 				printf("Relay-Session");
1333 				break;
1334 			case PPPOE_TAG_MAX_PAYLOAD:
1335 				printf("PPP-Max-Payload");
1336 				break;
1337 			case PPPOE_TAG_SERVICE_NAME_ERROR:
1338 				printf("Service-Name-Error");
1339 				break;
1340 			case PPPOE_TAG_AC_SYSTEM_ERROR:
1341 				printf("AC-System-Error");
1342 				break;
1343 			case PPPOE_TAG_GENERIC_ERROR:
1344 				printf("Generic-Error");
1345 				break;
1346 			default:
1347 				printf("Unknown(0x%04x)", t_type);
1348 			}
1349 			printf(", length %u%s", t_len, t_len ? " " : "");
1350 
1351 			if (t_len) {
1352 				for (t_type = 0; t_type < t_len; t_type++) {
1353 					if (isprint(p[t_type]))
1354 						printf("%c", p[t_type]);
1355 					else
1356 						printf("\\%03o", p[t_type]);
1357 				}
1358 			}
1359 			p += t_len;
1360 			l -= t_len;
1361 		}
1362 	} else if (ethertype == ETHERTYPE_PPPOE) {
1363 		printf("\n\t");
1364 		ppp_print(p, pppoe_len);
1365 	}
1366 
1367 	return (1);
1368 
1369 trunc:
1370 	printf("[|pppoe]");
1371 	return (1);
1372 }
1373 
1374 void
1375 ppp_hdlc_print(const u_char *p, u_int length)
1376 {
1377 	uint8_t address, control;
1378 	int l;
1379 
1380 	l = snapend - p;
1381 
1382 	if (l < sizeof(address) + sizeof(control))
1383 		goto trunc;
1384 
1385 	address = p[0];
1386 	control = p[1];
1387 
1388 	p += sizeof(address) + sizeof(control);
1389 	l -= sizeof(address) + sizeof(control);
1390 	length -= sizeof(address) + sizeof(control);
1391 
1392 	switch (address) {
1393 	case 0xff: /* All-Stations */
1394 		if (eflag)
1395 			printf("%02x %02x %u ", address, control, length);
1396 
1397 		if (control != 0x3) {
1398 			printf(" discard");
1399 			break;
1400 		}
1401 
1402 		ppp_print(p, length);
1403 		break;
1404 
1405 	default:
1406 		printf("ppp address 0x%02x unknown", address);
1407 		break;
1408 	}
1409 	return;
1410 
1411 trunc:
1412 	printf("[|ppp]");
1413 }
1414 
1415 void
1416 ppp_hdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
1417     const u_char *p)
1418 {
1419 	int l = h->caplen;
1420 
1421 	packetp = p;
1422 	snapend = p + l;
1423 
1424 	ts_print(&h->ts);
1425 
1426 	if (eflag)
1427 		printf("PPP ");
1428 
1429 	ppp_hdlc_print(p, h->len);
1430 
1431 	if (xflag)
1432 		default_print(p, l);
1433 
1434 	printf("\n");
1435 }
1436 
1437 #else
1438 
1439 #include <sys/types.h>
1440 #include <sys/time.h>
1441 
1442 #include <stdio.h>
1443 
1444 #include "interface.h"
1445 void
1446 ppp_if_print(user, h, p)
1447 	u_char *user;
1448 	const struct pcap_pkthdr *h;
1449 	const u_char *p;
1450 {
1451 	error("not configured for ppp");
1452 	/* NOTREACHED */
1453 }
1454 #endif
1455