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