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