xref: /freebsd/contrib/tcpdump/print-ppp.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1 /*
2  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that: (1) source code distributions
7  * retain the above copyright notice and this paragraph in its entirety, (2)
8  * distributions including binary code include the above copyright notice and
9  * this paragraph in its entirety in the documentation or other materials
10  * provided with the distribution, and (3) all advertising materials mentioning
11  * features or use of this software display the following acknowledgement:
12  * ``This product includes software developed by the University of California,
13  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14  * the University nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior
16  * written permission.
17  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
22  * complete PPP support.
23  *
24  * $FreeBSD$
25  */
26 
27 /*
28  * TODO:
29  * o resolve XXX as much as possible
30  * o MP support
31  * o BAP support
32  */
33 
34 #ifndef lint
35 static const char rcsid[] _U_ =
36     "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.89.2.3 2004/03/24 03:32:43 guy Exp $ (LBL)";
37 #endif
38 
39 #ifdef HAVE_CONFIG_H
40 #include "config.h"
41 #endif
42 
43 #include <tcpdump-stdinc.h>
44 
45 #ifdef __bsdi__
46 #include <net/slcompress.h>
47 #include <net/if_ppp.h>
48 #endif
49 
50 #include <pcap.h>
51 #include <stdio.h>
52 
53 #include "interface.h"
54 #include "extract.h"
55 #include "addrtoname.h"
56 #include "ppp.h"
57 #include "chdlc.h"
58 #include "ethertype.h"
59 
60 /*
61  * The following constatns are defined by IANA. Please refer to
62  *    http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
63  * for the up-to-date information.
64  */
65 
66 /* Protocol Codes defined in ppp.h */
67 
68 struct tok ppptype2str[] = {
69         { PPP_IP,	  "IP" },
70         { PPP_OSI,	  "OSI" },
71         { PPP_NS,	  "NS" },
72         { PPP_DECNET,	  "DECNET" },
73         { PPP_APPLE,	  "APPLE" },
74 	{ PPP_IPX,	  "IPX" },
75 	{ PPP_VJC,	  "VJC" },
76 	{ PPP_VJNC,	  "VJNC" },
77 	{ PPP_BRPDU,	  "BRPDU" },
78 	{ PPP_STII,	  "STII" },
79 	{ PPP_VINES,	  "VINES" },
80 	{ PPP_MPLS_UCAST, "MPLS" },
81 	{ PPP_MPLS_MCAST, "MPLS" },
82 
83 	{ PPP_HELLO,	  "HELLO" },
84 	{ PPP_LUXCOM,	  "LUXCOM" },
85 	{ PPP_SNS,	  "SNS" },
86 	{ PPP_IPCP,	  "IPCP" },
87 	{ PPP_OSICP,	  "OSICP" },
88 	{ PPP_NSCP,	  "NSCP" },
89 	{ PPP_DECNETCP,   "DECNETCP" },
90 	{ PPP_APPLECP,	  "APPLECP" },
91 	{ PPP_IPXCP,	  "IPXCP" },
92 	{ PPP_STIICP,	  "STIICP" },
93 	{ PPP_VINESCP,	  "VINESCP" },
94 	{ PPP_MPLSCP,	  "MPLSCP" },
95 
96 	{ PPP_LCP,	  "LCP" },
97 	{ PPP_PAP,	  "PAP" },
98 	{ PPP_LQM,	  "LQM" },
99 	{ PPP_CHAP,	  "CHAP" },
100 	{ PPP_BACP,	  "BACP" },
101 	{ PPP_BAP,	  "BAP" },
102 	{ PPP_MP,	  "ML" },
103 	{ 0,		  NULL }
104 };
105 
106 /* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */
107 
108 #define CPCODES_VEXT		0	/* Vendor-Specific (RFC2153) */
109 #define CPCODES_CONF_REQ	1	/* Configure-Request */
110 #define CPCODES_CONF_ACK	2	/* Configure-Ack */
111 #define CPCODES_CONF_NAK	3	/* Configure-Nak */
112 #define CPCODES_CONF_REJ	4	/* Configure-Reject */
113 #define CPCODES_TERM_REQ	5	/* Terminate-Request */
114 #define CPCODES_TERM_ACK	6	/* Terminate-Ack */
115 #define CPCODES_CODE_REJ	7	/* Code-Reject */
116 #define CPCODES_PROT_REJ	8	/* Protocol-Reject (LCP only) */
117 #define CPCODES_ECHO_REQ	9	/* Echo-Request (LCP only) */
118 #define CPCODES_ECHO_RPL	10	/* Echo-Reply (LCP only) */
119 #define CPCODES_DISC_REQ	11	/* Discard-Request (LCP only) */
120 #define CPCODES_ID		12	/* Identification (LCP only) RFC1570 */
121 #define CPCODES_TIME_REM	13	/* Time-Remaining (LCP only) RFC1570 */
122 #define CPCODES_RESET_REQ	14	/* Reset-Request (CCP only) RFC1962 */
123 #define CPCODES_RESET_REP	15	/* Reset-Reply (CCP only) */
124 
125 struct tok cpcodes[] = {
126 	{CPCODES_VEXT,      "Vendor-Extension"}, /* RFC2153 */
127 	{CPCODES_CONF_REQ,  "Conf-Request"},
128         {CPCODES_CONF_ACK,  "Conf-Ack"},
129 	{CPCODES_CONF_NAK,  "Conf-Nack"},
130 	{CPCODES_CONF_REJ,  "Conf-Reject"},
131 	{CPCODES_TERM_REQ,  "Term-Request"},
132 	{CPCODES_TERM_ACK,  "Term-Ack"},
133 	{CPCODES_CODE_REJ,  "Code-Reject"},
134 	{CPCODES_PROT_REJ,  "Prot-Reject"},
135 	{CPCODES_ECHO_REQ,  "Echo-Request"},
136 	{CPCODES_ECHO_RPL,  "Echo-Reply"},
137 	{CPCODES_DISC_REQ,  "Disc-Req"},
138 	{CPCODES_ID,        "Ident"},            /* RFC1570 */
139 	{CPCODES_TIME_REM,  "Time-Rem"},         /* RFC1570 */
140 	{CPCODES_RESET_REQ, "Reset-Req"},        /* RFC1962 */
141 	{CPCODES_RESET_REP, "Reset-Ack"},        /* RFC1962 */
142         {0,                 NULL}
143 };
144 
145 /* LCP Config Options */
146 
147 #define LCPOPT_VEXT	0
148 #define LCPOPT_MRU	1
149 #define LCPOPT_ACCM	2
150 #define LCPOPT_AP	3
151 #define LCPOPT_QP	4
152 #define LCPOPT_MN	5
153 #define LCPOPT_DEP6	6
154 #define LCPOPT_PFC	7
155 #define LCPOPT_ACFC	8
156 #define LCPOPT_FCSALT	9
157 #define LCPOPT_SDP	10
158 #define LCPOPT_NUMMODE	11
159 #define LCPOPT_DEP12	12
160 #define LCPOPT_CBACK	13
161 #define LCPOPT_DEP14	14
162 #define LCPOPT_DEP15	15
163 #define LCPOPT_DEP16	16
164 #define LCPOPT_MLMRRU	17
165 #define LCPOPT_MLSSNHF	18
166 #define LCPOPT_MLED	19
167 #define LCPOPT_PROP	20
168 #define LCPOPT_DCEID	21
169 #define LCPOPT_MPP	22
170 #define LCPOPT_LD	23
171 #define LCPOPT_LCPAOPT	24
172 #define LCPOPT_COBS	25
173 #define LCPOPT_PE	26
174 #define LCPOPT_MLHF	27
175 #define LCPOPT_I18N	28
176 #define LCPOPT_SDLOS	29
177 #define LCPOPT_PPPMUX	30
178 
179 #define LCPOPT_MIN LCPOPT_VEXT
180 #define LCPOPT_MAX LCPOPT_PPPMUX
181 
182 static const char *lcpconfopts[] = {
183 	"Vend-Ext",		/* (0) */
184 	"MRU",			/* (1) */
185 	"ACCM",			/* (2) */
186 	"Auth-Prot",		/* (3) */
187 	"Qual-Prot",		/* (4) */
188 	"Magic-Num",		/* (5) */
189 	"deprecated(6)",	/* used to be a Quality Protocol */
190 	"PFC",			/* (7) */
191 	"ACFC",			/* (8) */
192 	"FCS-Alt",		/* (9) */
193 	"SDP",			/* (10) */
194 	"Num-Mode",		/* (11) */
195 	"deprecated(12)",	/* used to be a Multi-Link-Procedure*/
196 	"Call-Back",		/* (13) */
197 	"deprecated(14)",	/* used to be a Connect-Time */
198 	"deprecated(15)",	/* used to be a Compund-Frames */
199 	"deprecated(16)",	/* used to be a Nominal-Data-Encap */
200 	"MRRU",			/* (17) */
201 	"SSNHF",		/* (18) */
202 	"End-Disc",		/* (19) */
203 	"Proprietary",		/* (20) */
204 	"DCE-Id",		/* (21) */
205 	"MP+",			/* (22) */
206 	"Link-Disc",		/* (23) */
207 	"LCP-Auth-Opt",		/* (24) */
208 	"COBS",			/* (25) */
209 	"Prefix-elision",	/* (26) */
210 	"Multilink-header-Form",/* (27) */
211 	"I18N",			/* (28) */
212 	"SDL-over-SONET/SDH",	/* (29) */
213 	"PPP-Muxing",		/* (30) */
214 };
215 
216 /* IPV6CP - to be supported */
217 /* ECP - to be supported */
218 
219 /* CCP Config Options */
220 
221 #define CCPOPT_OUI	0	/* RFC1962 */
222 #define CCPOPT_PRED1	1	/* RFC1962 */
223 #define CCPOPT_PRED2	2	/* RFC1962 */
224 #define CCPOPT_PJUMP	3	/* RFC1962 */
225 /* 4-15 unassigned */
226 #define CCPOPT_HPPPC	16	/* RFC1962 */
227 #define CCPOPT_STACLZS	17	/* RFC1974 */
228 #define CCPOPT_MPPC	18	/* RFC2118 */
229 #define CCPOPT_GFZA	19	/* RFC1962 */
230 #define CCPOPT_V42BIS	20	/* RFC1962 */
231 #define CCPOPT_BSDCOMP	21	/* RFC1977 */
232 /* 22 unassigned */
233 #define CCPOPT_LZSDCP	23	/* RFC1967 */
234 #define CCPOPT_MVRCA	24	/* RFC1975 */
235 #define CCPOPT_DEC	25	/* RFC1976 */
236 #define CCPOPT_DEFLATE	26	/* RFC1979 */
237 /* 27-254 unassigned */
238 #define CCPOPT_RESV	255	/* RFC1962 */
239 
240 #define CCPOPT_MIN CCPOPT_OUI
241 #define CCPOPT_MAX CCPOPT_DEFLATE    /* XXX: should be CCPOPT_RESV but... */
242 
243 static const char *ccpconfopts[] = {
244 	"OUI",			/* (0) */
245 	"Pred-1",		/* (1) */
246 	"Pred-2",		/* (2) */
247 	"Puddle",		/* (3) */
248 	"unassigned(4)",	/* (4) */
249 	"unassigned(5)",	/* (5) */
250 	"unassigned(6)",	/* (6) */
251 	"unassigned(7)",	/* (7) */
252 	"unassigned(8)",	/* (8) */
253 	"unassigned(9)",	/* (9) */
254 	"unassigned(10)",	/* (10) */
255 	"unassigned(11)",	/* (11) */
256 	"unassigned(12)",	/* (12) */
257 	"unassigned(13)",	/* (13) */
258 	"unassigned(14)",	/* (14) */
259 	"unassigned(15)",	/* (15) */
260 	"HP-PPC",		/* (16) */
261 	"Stac-LZS",		/* (17) */
262 	"MPPC",			/* (18) */
263 	"Gand-FZA",		/* (19) */
264 	"V.42bis",		/* (20) */
265 	"BSD-Comp",		/* (21) */
266 	"unassigned(22)",	/* (22) */
267 	"LZS-DCP",		/* (23) */
268 	"MVRCA",		/* (24) */
269 	"DEC",			/* (25) */
270 	"Deflate",		/* (26) */
271 };
272 
273 /* BACP Config Options */
274 
275 #define BACPOPT_FPEER	1	/* RFC2125 */
276 
277 /* SDCP - to be supported */
278 
279 /* IPCP Config Options */
280 
281 #define IPCPOPT_2ADDR	1	/* RFC1172, RFC1332 (deprecated) */
282 #define IPCPOPT_IPCOMP	2	/* RFC1332 */
283 #define IPCPOPT_ADDR	3	/* RFC1332 */
284 #define IPCPOPT_MOBILE4	4	/* RFC2290 */
285 
286 #define IPCPOPT_PRIDNS	129	/* RFC1877 */
287 #define IPCPOPT_PRINBNS	130	/* RFC1877 */
288 #define IPCPOPT_SECDNS	131	/* RFC1877 */
289 #define IPCPOPT_SECNBNS	132	/* RFC1877 */
290 
291 /* ATCP - to be supported */
292 /* OSINLCP - to be supported */
293 /* BVCP - to be supported */
294 /* BCP - to be supported */
295 /* IPXCP - to be supported */
296 /* MPLSCP - to be supported */
297 
298 /* Auth Algorithms */
299 
300 /* 0-4 Reserved (RFC1994) */
301 #define AUTHALG_CHAPMD5	5	/* RFC1994 */
302 #define AUTHALG_MSCHAP1	128	/* RFC2433 */
303 #define AUTHALG_MSCHAP2	129	/* RFC2795 */
304 
305 /* FCS Alternatives - to be supported */
306 
307 /* Multilink Endpoint Discriminator (RFC1717) */
308 #define MEDCLASS_NULL	0	/* Null Class */
309 #define MEDCLASS_LOCAL	1	/* Locally Assigned */
310 #define MEDCLASS_IPV4	2	/* Internet Protocol (IPv4) */
311 #define MEDCLASS_MAC	3	/* IEEE 802.1 global MAC address */
312 #define MEDCLASS_MNB	4	/* PPP Magic Number Block */
313 #define MEDCLASS_PSNDN	5	/* Public Switched Network Director Number */
314 
315 /* PPP LCP Callback */
316 #define CALLBACK_AUTH	0	/* Location determined by user auth */
317 #define CALLBACK_DSTR	1	/* Dialing string */
318 #define CALLBACK_LID	2	/* Location identifier */
319 #define CALLBACK_E164	3	/* E.164 number */
320 #define CALLBACK_X500	4	/* X.500 distinguished name */
321 #define CALLBACK_CBCP	6	/* Location is determined during CBCP nego */
322 
323 /* CHAP */
324 
325 #define CHAP_CHAL	1
326 #define CHAP_RESP	2
327 #define CHAP_SUCC	3
328 #define CHAP_FAIL	4
329 
330 #define CHAP_CODEMIN CHAP_CHAL
331 #define CHAP_CODEMAX CHAP_FAIL
332 
333 static const char *chapcode[] = {
334 	"Chal",		/* (1) */
335 	"Resp",		/* (2) */
336 	"Succ",		/* (3) */
337 	"Fail",		/* (4) */
338 };
339 
340 /* PAP */
341 
342 #define PAP_AREQ	1
343 #define PAP_AACK	2
344 #define PAP_ANAK	3
345 
346 #define PAP_CODEMIN	PAP_AREQ
347 #define PAP_CODEMAX	PAP_ANAK
348 
349 static const char *papcode[] = {
350 	"Auth-Req",	/* (1) */
351 	"Auth-Ack",	/* (2) */
352 	"Auth-Nak",	/* (3) */
353 };
354 
355 /* BAP */
356 #define BAP_CALLREQ	1
357 #define BAP_CALLRES	2
358 #define BAP_CBREQ	3
359 #define BAP_CBRES	4
360 #define BAP_LDQREQ	5
361 #define BAP_LDQRES	6
362 #define BAP_CSIND	7
363 #define BAP_CSRES	8
364 
365 static void handle_ctrl_proto (u_int proto,const u_char *p, int length);
366 static void handle_chap (const u_char *p, int length);
367 static void handle_pap (const u_char *p, int length);
368 static void handle_bap (const u_char *p, int length);
369 static int print_lcp_config_options (const u_char *p, int);
370 static int print_ipcp_config_options (const u_char *p, int);
371 static int print_ccp_config_options (const u_char *p, int);
372 static int print_bacp_config_options (const u_char *p, int);
373 static void handle_ppp (u_int proto, const u_char *p, int length);
374 
375 /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
376 static void
377 handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
378 {
379 	const char *typestr;
380 	u_int code, len;
381 	int (*pfunc)(const u_char *, int);
382 	int x, j;
383         const u_char *tptr;
384 
385         tptr=pptr;
386 
387         typestr = tok2str(ppptype2str, "unknown", proto);
388         printf("%s, ",typestr);
389 
390 	if (length < 4) /* FIXME weak boundary checking */
391 		goto trunc;
392 	TCHECK2(*tptr, 2);
393 
394 	code = *tptr++;
395 
396         printf("%s (0x%02x), id %u",
397                tok2str(cpcodes, "Unknown Opcode",code),
398 	       code,
399                *tptr++); /* ID */
400 
401 	TCHECK2(*tptr, 2);
402 	len = EXTRACT_16BITS(tptr);
403 	tptr += 2;
404 
405 	if (length <= 4)
406 		return;		/* there may be a NULL confreq etc. */
407 
408 	switch (code) {
409 	case CPCODES_VEXT:
410 		if (length < 11)
411 			break;
412 		TCHECK2(*tptr, 4);
413 		printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
414 		tptr += 4;
415 		TCHECK2(*tptr, 3);
416 		printf(" OUI 0x%06x", EXTRACT_24BITS(tptr));
417 		/* XXX: need to decode Kind and Value(s)? */
418 		break;
419 	case CPCODES_CONF_REQ:
420 	case CPCODES_CONF_ACK:
421 	case CPCODES_CONF_NAK:
422 	case CPCODES_CONF_REJ:
423 		x = len - 4;	/* Code(1), Identifier(1) and Length(2) */
424 		do {
425 			switch (proto) {
426 			case PPP_LCP:
427 				pfunc = print_lcp_config_options;
428 				break;
429 			case PPP_IPCP:
430 				pfunc = print_ipcp_config_options;
431 				break;
432 			case PPP_CCP:
433 				pfunc = print_ccp_config_options;
434 				break;
435 			case PPP_BACP:
436 				pfunc = print_bacp_config_options;
437 				break;
438 			default:
439 				/*
440 				 * This should never happen, but we set
441 				 * "pfunc" to squelch uninitialized
442 				 * variable warnings from compilers.
443 				 */
444 				pfunc = NULL;
445 				break;
446 			}
447 			if ((j = (*pfunc)(tptr, len)) == 0)
448 				break;
449 			x -= j;
450 			tptr += j;
451 		} while (x > 0);
452 		break;
453 
454 	case CPCODES_TERM_REQ:
455 	case CPCODES_TERM_ACK:
456 		/* XXX: need to decode Data? */
457 		break;
458 	case CPCODES_CODE_REJ:
459 		/* XXX: need to decode Rejected-Packet? */
460 		break;
461 	case CPCODES_PROT_REJ:
462 		if (length < 6)
463 			break;
464 		TCHECK2(*tptr, 2);
465 		printf(", Rejected %s Protocol (0x%04x)",
466 		       tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)),
467 		       EXTRACT_16BITS(tptr));
468 		/* XXX: need to decode Rejected-Information? */
469 		break;
470 	case CPCODES_ECHO_REQ:
471 	case CPCODES_ECHO_RPL:
472 	case CPCODES_DISC_REQ:
473 	case CPCODES_ID:
474 		if (length < 8)
475 			break;
476 		TCHECK2(*tptr, 4);
477 		printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
478 		/* XXX: need to decode Data? */
479 		break;
480 	case CPCODES_TIME_REM:
481 		if (length < 12)
482 			break;
483 		TCHECK2(*tptr, 4);
484 		printf(", Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
485 		TCHECK2(*(tptr + 4), 4);
486 		printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4));
487 		/* XXX: need to decode Message? */
488 		break;
489 	default:
490             /* XXX this is dirty but we do not get the
491              * original pointer passed to the begin
492              * the PPP packet */
493                 if (vflag <= 1)
494                     print_unknown_data(pptr-2,"\n\t",length+2);
495 		break;
496 	}
497 	printf(", length %u", length);
498 
499         if (vflag >1)
500             print_unknown_data(pptr-2,"\n\t",length+2);
501 	return;
502 
503 trunc:
504 	printf("[|%s]", typestr);
505 }
506 
507 /* LCP config options */
508 static int
509 print_lcp_config_options(const u_char *p, int length)
510 {
511 	int len, opt;
512 
513 	if (length < 2)
514 		return 0;
515 	TCHECK2(*p, 2);
516 	len = p[1];
517 	opt = p[0];
518 	if (length < len)
519 		return 0;
520 	if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
521 		printf(", %s ", lcpconfopts[opt]);
522 	else {
523 		printf(", unknown LCP option 0x%02x", opt);
524 		return len;
525 	}
526 
527 	switch (opt) {
528 	case LCPOPT_VEXT:
529 		if (len >= 6) {
530 			TCHECK2(*(p + 2), 3);
531 			printf(" OUI 0x%06x", EXTRACT_24BITS(p+2));
532 #if 0
533 			TCHECK(p[5]);
534 			printf(" kind 0x%02x", p[5]);
535 			printf(" val 0x")
536 			for (i = 0; i < len - 6; i++) {
537 				TCHECK(p[6 + i]);
538 				printf("%02x", p[6 + i]);
539 			}
540 #endif
541 		}
542 		break;
543 	case LCPOPT_MRU:
544 		if (len == 4) {
545 			TCHECK2(*(p + 2), 2);
546 			printf(" %u", EXTRACT_16BITS(p + 2));
547 		}
548 		break;
549 	case LCPOPT_ACCM:
550 		if (len == 6) {
551 			TCHECK2(*(p + 2), 4);
552 			printf(" %08x", EXTRACT_32BITS(p + 2));
553 		}
554 		break;
555 	case LCPOPT_AP:
556 		if (len >= 4) {
557 		    TCHECK2(*(p + 2), 2);
558 		    switch (EXTRACT_16BITS(p+2)) {
559 		    case PPP_PAP:
560 		        printf(" PAP");
561 			break;
562 		    case PPP_CHAP:
563 		        printf(" CHAP");
564 		        TCHECK(p[4]);
565 			switch (p[4]) {
566 			default:
567 			    printf(", unknown-algorithm-%u", p[4]);
568 			    break;
569 			case AUTHALG_CHAPMD5:
570 			    printf(", MD5");
571 			    break;
572 			case AUTHALG_MSCHAP1:
573 			    printf(", MSCHAPv1");
574 			    break;
575 			case AUTHALG_MSCHAP2:
576 			    printf(", MSCHAPv2");
577 			    break;
578 			}
579 			break;
580 		    case PPP_EAP:
581 		        printf(" EAP");
582 			break;
583 		    case PPP_SPAP:
584 			printf(" SPAP");
585 			break;
586 		    case PPP_SPAP_OLD:
587 			printf(" Old-SPAP");
588 			break;
589 		    default:
590 		      printf("unknown");
591 		    }
592 		}
593 		break;
594 	case LCPOPT_QP:
595 		if (len >= 4) {
596 			TCHECK2(*(p + 2), 2);
597 		        if (EXTRACT_16BITS(p+2) == PPP_LQM)
598 				printf(" LQR");
599 			else
600 				printf(" unknown");
601 		}
602 		break;
603 	case LCPOPT_MN:
604 		if (len == 6) {
605 			TCHECK2(*(p + 2), 4);
606 			printf(" 0x%08x", EXTRACT_32BITS(p + 2));
607 		}
608 		break;
609 	case LCPOPT_PFC:
610 		break;
611 	case LCPOPT_ACFC:
612 		break;
613 	case LCPOPT_LD:
614 		if (len == 4) {
615 			TCHECK2(*(p + 2), 2);
616 			printf(" 0x%04x", EXTRACT_16BITS(p + 2));
617 		}
618 		break;
619 	case LCPOPT_CBACK:
620 		if (len < 3)
621 			break;
622 		TCHECK(p[2]);
623 		switch (p[2]) {		/* Operation */
624 		case CALLBACK_AUTH:
625 			printf(" UserAuth");
626 			break;
627 		case CALLBACK_DSTR:
628 			printf(" DialString");
629 			break;
630 		case CALLBACK_LID:
631 			printf(" LocalID");
632 			break;
633 		case CALLBACK_E164:
634 			printf(" E.164");
635 			break;
636 		case CALLBACK_X500:
637 			printf(" X.500");
638 			break;
639 		case CALLBACK_CBCP:
640 			printf(" CBCP");
641 			break;
642 		default:
643 			printf(" unknown-operation=%u", p[2]);
644 			break;
645 		}
646 		break;
647 	case LCPOPT_MLMRRU:
648 		if (len == 4) {
649 			TCHECK2(*(p + 2), 2);
650 			printf(" %u", EXTRACT_16BITS(p + 2));
651 		}
652 		break;
653 	case LCPOPT_MLED:
654 		if (len < 3)
655 			break;
656 		TCHECK(p[2]);
657 		switch (p[2]) {		/* class */
658 		case MEDCLASS_NULL:
659 			printf(" Null");
660 			break;
661 		case MEDCLASS_LOCAL:
662 			printf(" Local"); /* XXX */
663 			break;
664 		case MEDCLASS_IPV4:
665 			if (len != 7)
666 				break;
667 			TCHECK2(*(p + 3), 4);
668 			printf(" IPv4 %s", ipaddr_string(p + 3));
669 			break;
670 		case MEDCLASS_MAC:
671 			if (len != 9)
672 				break;
673 			TCHECK(p[8]);
674 			printf(" MAC %02x:%02x:%02x:%02x:%02x:%02x",
675 			       p[3], p[4], p[5], p[6], p[7], p[8]);
676 			break;
677 		case MEDCLASS_MNB:
678 			printf(" Magic-Num-Block"); /* XXX */
679 			break;
680 		case MEDCLASS_PSNDN:
681 			printf(" PSNDN"); /* XXX */
682 			break;
683 		}
684 		break;
685 
686 /* XXX: to be supported */
687 #if 0
688 	case LCPOPT_DEP6:
689 	case LCPOPT_FCSALT:
690 	case LCPOPT_SDP:
691 	case LCPOPT_NUMMODE:
692 	case LCPOPT_DEP12:
693 	case LCPOPT_DEP14:
694 	case LCPOPT_DEP15:
695 	case LCPOPT_DEP16:
696 	case LCPOPT_MLSSNHF:
697 	case LCPOPT_PROP:
698 	case LCPOPT_DCEID:
699 	case LCPOPT_MPP:
700 	case LCPOPT_LCPAOPT:
701 	case LCPOPT_COBS:
702 	case LCPOPT_PE:
703 	case LCPOPT_MLHF:
704 	case LCPOPT_I18N:
705 	case LCPOPT_SDLOS:
706 	case LCPOPT_PPPMUX:
707 		break;
708 #endif
709 	}
710 	return len;
711 
712 trunc:
713 	printf("[|lcp]");
714 	return 0;
715 }
716 
717 /* CHAP */
718 static void
719 handle_chap(const u_char *p, int length)
720 {
721 	u_int code, len;
722 	int val_size, name_size, msg_size;
723 	const u_char *p0;
724 	int i;
725 
726 	p0 = p;
727 	if (length < 1) {
728 		printf("[|chap]");
729 		return;
730 	} else if (length < 4) {
731 		TCHECK(*p);
732 		printf("[|chap 0x%02x]", *p);
733 		return;
734 	}
735 
736 	TCHECK(*p);
737 	code = *p;
738 	if ((code >= CHAP_CODEMIN) && (code <= CHAP_CODEMAX))
739 		printf("%s", chapcode[code - 1]);
740 	else {
741 		printf("0x%02x", code);
742 		return;
743 	}
744 	p++;
745 
746 	TCHECK(*p);
747 	printf("(%u)", *p);		/* ID */
748 	p++;
749 
750 	TCHECK2(*p, 2);
751 	len = EXTRACT_16BITS(p);
752 	p += 2;
753 
754 	/*
755 	 * Note that this is a generic CHAP decoding routine. Since we
756 	 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
757 	 * MS-CHAPv2) is used at this point, we can't decode packet
758 	 * specifically to each algorithms. Instead, we simply decode
759 	 * the GCD (Gratest Common Denominator) for all algorithms.
760 	 */
761 	switch (code) {
762 	case CHAP_CHAL:
763 	case CHAP_RESP:
764 		if (length - (p - p0) < 1)
765 			return;
766 		TCHECK(*p);
767 		val_size = *p;		/* value size */
768 		p++;
769 		if (length - (p - p0) < val_size)
770 			return;
771 		printf(", Value ");
772 		for (i = 0; i < val_size; i++) {
773 			TCHECK(*p);
774 			printf("%02x", *p++);
775 		}
776 		name_size = len - (p - p0);
777 		printf(", Name ");
778 		for (i = 0; i < name_size; i++) {
779 			TCHECK(*p);
780 			safeputchar(*p++);
781 		}
782 		break;
783 	case CHAP_SUCC:
784 	case CHAP_FAIL:
785 		msg_size = len - (p - p0);
786 		printf(", Msg ");
787 		for (i = 0; i< msg_size; i++) {
788 			TCHECK(*p);
789 			safeputchar(*p++);
790 		}
791 		break;
792 	}
793 	return;
794 
795 trunc:
796 	printf("[|chap]");
797 }
798 
799 /* PAP (see RFC 1334) */
800 static void
801 handle_pap(const u_char *p, int length)
802 {
803 	u_int code, len;
804 	int peerid_len, passwd_len, msg_len;
805 	const u_char *p0;
806 	int i;
807 
808 	p0 = p;
809 	if (length < 1) {
810 		printf("[|pap]");
811 		return;
812 	} else if (length < 4) {
813 		TCHECK(*p);
814 		printf("[|pap 0x%02x]", *p);
815 		return;
816 	}
817 
818 	TCHECK(*p);
819 	code = *p;
820 	if ((code >= PAP_CODEMIN) && (code <= PAP_CODEMAX))
821 		printf("%s", papcode[code - 1]);
822 	else {
823 		printf("0x%02x", code);
824 		return;
825 	}
826 	p++;
827 
828 	TCHECK(*p);
829 	printf("(%u)", *p);		/* ID */
830 	p++;
831 
832 	TCHECK2(*p, 2);
833 	len = EXTRACT_16BITS(p);
834 	p += 2;
835 
836 	switch (code) {
837 	case PAP_AREQ:
838 		if (length - (p - p0) < 1)
839 			return;
840 		TCHECK(*p);
841 		peerid_len = *p;	/* Peer-ID Length */
842 		p++;
843 		if (length - (p - p0) < peerid_len)
844 			return;
845 		printf(", Peer ");
846 		for (i = 0; i < peerid_len; i++) {
847 			TCHECK(*p);
848 			safeputchar(*p++);
849 		}
850 
851 		if (length - (p - p0) < 1)
852 			return;
853 		TCHECK(*p);
854 		passwd_len = *p;	/* Password Length */
855 		p++;
856 		if (length - (p - p0) < passwd_len)
857 			return;
858 		printf(", Name ");
859 		for (i = 0; i < passwd_len; i++) {
860 			TCHECK(*p);
861 			safeputchar(*p++);
862 		}
863 		break;
864 	case PAP_AACK:
865 	case PAP_ANAK:
866 		if (length - (p - p0) < 1)
867 			return;
868 		TCHECK(*p);
869 		msg_len = *p;		/* Msg-Length */
870 		p++;
871 		if (length - (p - p0) < msg_len)
872 			return;
873 		printf(", Msg ");
874 		for (i = 0; i< msg_len; i++) {
875 			TCHECK(*p);
876 			safeputchar(*p++);
877 		}
878 		break;
879 	}
880 	return;
881 
882 trunc:
883 	printf("[|pap]");
884 }
885 
886 /* BAP */
887 static void
888 handle_bap(const u_char *p _U_, int length _U_)
889 {
890 	/* XXX: to be supported!! */
891 }
892 
893 
894 /* IPCP config options */
895 static int
896 print_ipcp_config_options(const u_char *p, int length)
897 {
898 	int len, opt;
899 
900 	if (length < 2)
901 		return 0;
902 	TCHECK2(*p, 2);
903 	len = p[1];
904 	opt = p[0];
905 	if (length < len)
906 		return 0;
907 	switch (opt) {
908 	case IPCPOPT_2ADDR:		/* deprecated */
909 		if (len != 10)
910 			goto invlen;
911 		TCHECK2(*(p + 6), 4);
912 		printf(", IP-Addrs src %s, dst %s",
913 		       ipaddr_string(p + 2),
914 		       ipaddr_string(p + 6));
915 		break;
916 	case IPCPOPT_IPCOMP:
917 		if (len < 4)
918 			goto invlen;
919 		printf(", IP-Comp");
920 		TCHECK2(*(p + 2), 2);
921 		if (EXTRACT_16BITS(p + 2) == PPP_VJC) {
922 			printf(" VJ-Comp");
923 			/* XXX: VJ-Comp parameters should be decoded */
924 		} else
925 			printf(" unknown-comp-proto=%04x", EXTRACT_16BITS(p + 2));
926 		break;
927 	case IPCPOPT_ADDR:
928 		if (len != 6)
929 			goto invlen;
930 		TCHECK2(*(p + 2), 4);
931 		printf(", IP-Addr %s", ipaddr_string(p + 2));
932 		break;
933 	case IPCPOPT_MOBILE4:
934 		if (len != 6)
935 			goto invlen;
936 		TCHECK2(*(p + 2), 4);
937 		printf(", Home-Addr %s", ipaddr_string(p + 2));
938 		break;
939 	case IPCPOPT_PRIDNS:
940 		if (len != 6)
941 			goto invlen;
942 		TCHECK2(*(p + 2), 4);
943 		printf(", Pri-DNS %s", ipaddr_string(p + 2));
944 		break;
945 	case IPCPOPT_PRINBNS:
946 		if (len != 6)
947 			goto invlen;
948 		TCHECK2(*(p + 2), 4);
949 		printf(", Pri-NBNS %s", ipaddr_string(p + 2));
950 		break;
951 	case IPCPOPT_SECDNS:
952 		if (len != 6)
953 			goto invlen;
954 		TCHECK2(*(p + 2), 4);
955 		printf(", Sec-DNS %s", ipaddr_string(p + 2));
956 		break;
957 	case IPCPOPT_SECNBNS:
958 		if (len != 6)
959 			goto invlen;
960 		TCHECK2(*(p + 2), 4);
961 		printf(", Sec-NBNS %s", ipaddr_string(p + 2));
962 		break;
963 	default:
964 		printf(", unknown-%d", opt);
965 		break;
966 	}
967 	return len;
968 
969 invlen:
970 	printf(", invalid-length-%d", opt);
971 	return 0;
972 
973 trunc:
974 	printf("[|ipcp]");
975 	return 0;
976 }
977 
978 /* CCP config options */
979 static int
980 print_ccp_config_options(const u_char *p, int length)
981 {
982 	int len, opt;
983 
984 	if (length < 2)
985 		return 0;
986 	TCHECK2(*p, 2);
987 	len = p[1];
988 	opt = p[0];
989 	if (length < len)
990 		return 0;
991 	if ((opt >= CCPOPT_MIN) && (opt <= CCPOPT_MAX))
992 		printf(", %s", ccpconfopts[opt]);
993 #if 0	/* XXX */
994 	switch (opt) {
995 	case CCPOPT_OUI:
996 	case CCPOPT_PRED1:
997 	case CCPOPT_PRED2:
998 	case CCPOPT_PJUMP:
999 	case CCPOPT_HPPPC:
1000 	case CCPOPT_STACLZS:
1001 	case CCPOPT_MPPC:
1002 	case CCPOPT_GFZA:
1003 	case CCPOPT_V42BIS:
1004 	case CCPOPT_BSDCOMP:
1005 	case CCPOPT_LZSDCP:
1006 	case CCPOPT_MVRCA:
1007 	case CCPOPT_DEC:
1008 	case CCPOPT_DEFLATE:
1009 	case CCPOPT_RESV:
1010 		break;
1011 
1012 	default:
1013 		printf(", unknown-%d", opt);
1014 		break;
1015 	}
1016 #endif
1017 	return len;
1018 
1019 trunc:
1020 	printf("[|ccp]");
1021 	return 0;
1022 }
1023 
1024 /* BACP config options */
1025 static int
1026 print_bacp_config_options(const u_char *p, int length)
1027 {
1028 	int len, opt;
1029 
1030 	if (length < 2)
1031 		return 0;
1032 	TCHECK2(*p, 2);
1033 	len = p[1];
1034 	opt = p[0];
1035 	if (length < len)
1036 		return 0;
1037 	if (opt == BACPOPT_FPEER) {
1038 		TCHECK2(*(p + 2), 4);
1039 		printf(", Favored-Peer");
1040 		printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2));
1041 	} else {
1042 		printf(", unknown-option-%d", opt);
1043 	}
1044 	return len;
1045 
1046 trunc:
1047 	printf("[|bacp]");
1048 	return 0;
1049 }
1050 
1051 
1052 /* PPP */
1053 static void
1054 handle_ppp(u_int proto, const u_char *p, int length)
1055 {
1056 	switch (proto) {
1057 	case PPP_LCP:
1058 	case PPP_IPCP:
1059 	case PPP_OSICP:
1060 	case PPP_MPLSCP:
1061 	case PPP_IPV6CP:
1062 	case PPP_CCP:
1063 	case PPP_BACP:
1064 		handle_ctrl_proto(proto, p, length);
1065 		break;
1066 	case PPP_CHAP:
1067 		handle_chap(p, length);
1068 		break;
1069 	case PPP_PAP:
1070 		handle_pap(p, length);
1071 		break;
1072 	case PPP_BAP:		/* XXX: not yet completed */
1073 		handle_bap(p, length);
1074 		break;
1075 	case ETHERTYPE_IP:	/*XXX*/
1076 	case PPP_IP:
1077 		ip_print(p, length);
1078 		break;
1079 #ifdef INET6
1080 	case ETHERTYPE_IPV6:	/*XXX*/
1081 	case PPP_IPV6:
1082 		ip6_print(p, length);
1083 		break;
1084 #endif
1085 	case ETHERTYPE_IPX:	/*XXX*/
1086 	case PPP_IPX:
1087 		ipx_print(p, length);
1088 		break;
1089 	case PPP_OSI:
1090 	        isoclns_print(p, length, length);
1091 	        break;
1092 	case PPP_MPLS_UCAST:
1093 	case PPP_MPLS_MCAST:
1094 		mpls_print(p, length);
1095 		break;
1096 	default:
1097                 printf("unknown PPP protocol (0x%04x)", proto);
1098                 print_unknown_data(p,"\n\t",length);
1099                 break;
1100 	}
1101 }
1102 
1103 /* Standard PPP printer */
1104 u_int
1105 ppp_print(register const u_char *p, u_int length)
1106 {
1107 	u_int proto;
1108         u_int olen = length; /* _o_riginal length */
1109 	u_int hdr_len = 0;
1110 
1111 	/*
1112 	 * Here, we assume that p points to the Address and Control
1113 	 * field (if they present).
1114 	 */
1115 	if (length < 2)
1116 		goto trunc;
1117 	TCHECK2(*p, 2);
1118 	if (*p == PPP_ADDRESS && *(p + 1) == PPP_CONTROL) {
1119 		p += 2;			/* ACFC not used */
1120 		length -= 2;
1121 		hdr_len += 2;
1122 	}
1123 
1124 	if (length < 2)
1125 		goto trunc;
1126 	TCHECK(*p);
1127 	if (*p % 2) {
1128 		proto = *p;		/* PFC is used */
1129 		p++;
1130 		length--;
1131 		hdr_len++;
1132 	} else {
1133 		TCHECK2(*p, 2);
1134 		proto = EXTRACT_16BITS(p);
1135 		p += 2;
1136 		length -= 2;
1137 		hdr_len += 2;
1138 	}
1139 
1140         if (eflag)
1141             printf("PPP-%s (0x%04x), length %u: ",
1142                    tok2str(ppptype2str, "unknown", proto),
1143                    proto,
1144                    olen);
1145 
1146 	handle_ppp(proto, p, length);
1147 	return (hdr_len);
1148 trunc:
1149 	printf("[|ppp]");
1150 	return (0);
1151 }
1152 
1153 
1154 /* PPP I/F printer */
1155 u_int
1156 ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1157 {
1158 	register u_int length = h->len;
1159 	register u_int caplen = h->caplen;
1160 
1161 	if (caplen < PPP_HDRLEN) {
1162 		printf("[|ppp]");
1163 		return (caplen);
1164 	}
1165 
1166 #if 0
1167 	/*
1168 	 * XXX: seems to assume that there are 2 octets prepended to an
1169 	 * actual PPP frame. The 1st octet looks like Input/Output flag
1170 	 * while 2nd octet is unknown, at least to me
1171 	 * (mshindo@mshindo.net).
1172 	 *
1173 	 * That was what the original tcpdump code did.
1174 	 *
1175 	 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1176 	 * packets and 0 for inbound packets - but only if the
1177 	 * protocol field has the 0x8000 bit set (i.e., it's a network
1178 	 * control protocol); it does so before running the packet through
1179 	 * "bpf_filter" to see if it should be discarded, and to see
1180 	 * if we should update the time we sent the most recent packet...
1181 	 *
1182 	 * ...but it puts the original address field back after doing
1183 	 * so.
1184 	 *
1185 	 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1186 	 *
1187 	 * I don't know if any PPP implementation handed up to a BPF
1188 	 * device packets with the first octet being 1 for outbound and
1189 	 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1190 	 * whether that ever needs to be checked or not.
1191 	 *
1192 	 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1193 	 * and its tcpdump appears to assume that the frame always
1194 	 * begins with an address field and a control field, and that
1195 	 * the address field might be 0x0f or 0x8f, for Cisco
1196 	 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1197 	 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1198 	 * RFC 1662.
1199 	 *
1200 	 * (Is the Cisco framing in question what DLT_C_HDLC, in
1201 	 * BSD/OS, is?)
1202 	 */
1203 	if (eflag)
1204 		printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
1205 #endif
1206 
1207 	ppp_print(p, length);
1208 
1209 	return (0);
1210 }
1211 
1212 /*
1213  * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1214  * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1215  * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1216  * discard them *if* those are the first two octets, and parse the remaining
1217  * packet as a PPP packet, as "ppp_print()" does).
1218  *
1219  * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1220  */
1221 u_int
1222 ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
1223 {
1224 	register u_int length = h->len;
1225 	register u_int caplen = h->caplen;
1226 	u_int proto;
1227 	u_int hdrlen = 0;
1228 
1229 	if (caplen < 2) {
1230 		printf("[|ppp]");
1231 		return (caplen);
1232 	}
1233 
1234 	switch (p[0]) {
1235 
1236 	case PPP_ADDRESS:
1237 		if (caplen < 4) {
1238 			printf("[|ppp]");
1239 			return (caplen);
1240 		}
1241 
1242 		if (eflag)
1243 			printf("%02x %02x %d ", p[0], p[1], length);
1244 		p += 2;
1245 		length -= 2;
1246 		hdrlen += 2;
1247 
1248 		proto = EXTRACT_16BITS(p);
1249 		p += 2;
1250 		length -= 2;
1251 		hdrlen += 2;
1252 		printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
1253 
1254 		handle_ppp(proto, p, length);
1255 		break;
1256 
1257 	case CHDLC_UNICAST:
1258 	case CHDLC_BCAST:
1259 		return (chdlc_if_print(h, p));
1260 
1261 	default:
1262 		if (eflag)
1263 			printf("%02x %02x %d ", p[0], p[1], length);
1264 		p += 2;
1265 		length -= 2;
1266 		hdrlen += 2;
1267 
1268 		/*
1269 		 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1270 		 * the next two octets as an Ethernet type; does that
1271 		 * ever happen?
1272 		 */
1273 		printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
1274 		break;
1275 	}
1276 
1277 	return (hdrlen);
1278 }
1279 
1280 #define PPP_BSDI_HDRLEN 24
1281 
1282 /* BSD/OS specific PPP printer */
1283 u_int
1284 ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_)
1285 {
1286 	register int hdrlength;
1287 #ifdef __bsdi__
1288 	register u_int length = h->len;
1289 	register u_int caplen = h->caplen;
1290 	u_int16_t ptype;
1291 	const u_char *q;
1292 	int i;
1293 
1294 	if (caplen < PPP_BSDI_HDRLEN) {
1295 		printf("[|ppp]");
1296 		return (caplen)
1297 	}
1298 
1299 	hdrlength = 0;
1300 
1301 #if 0
1302 	if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1303 		if (eflag)
1304 			printf("%02x %02x ", p[0], p[1]);
1305 		p += 2;
1306 		hdrlength = 2;
1307 	}
1308 
1309 	if (eflag)
1310 		printf("%d ", length);
1311 	/* Retrieve the protocol type */
1312 	if (*p & 01) {
1313 		/* Compressed protocol field */
1314 		ptype = *p;
1315 		if (eflag)
1316 			printf("%02x ", ptype);
1317 		p++;
1318 		hdrlength += 1;
1319 	} else {
1320 		/* Un-compressed protocol field */
1321 		ptype = ntohs(*(u_int16_t *)p);
1322 		if (eflag)
1323 			printf("%04x ", ptype);
1324 		p += 2;
1325 		hdrlength += 2;
1326 	}
1327 #else
1328 	ptype = 0;	/*XXX*/
1329 	if (eflag)
1330 		printf("%c ", p[SLC_DIR] ? 'O' : 'I');
1331 	if (p[SLC_LLHL]) {
1332 		/* link level header */
1333 		struct ppp_header *ph;
1334 
1335 		q = p + SLC_BPFHDRLEN;
1336 		ph = (struct ppp_header *)q;
1337 		if (ph->phdr_addr == PPP_ADDRESS
1338 		 && ph->phdr_ctl == PPP_CONTROL) {
1339 			if (eflag)
1340 				printf("%02x %02x ", q[0], q[1]);
1341 			ptype = ntohs(ph->phdr_type);
1342 			if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1343 				printf("%s ", tok2str(ppptype2str,
1344 						"proto-#%d", ptype));
1345 			}
1346 		} else {
1347 			if (eflag) {
1348 				printf("LLH=[");
1349 				for (i = 0; i < p[SLC_LLHL]; i++)
1350 					printf("%02x", q[i]);
1351 				printf("] ");
1352 			}
1353 		}
1354 	}
1355 	if (eflag)
1356 		printf("%d ", length);
1357 	if (p[SLC_CHL]) {
1358 		q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1359 
1360 		switch (ptype) {
1361 		case PPP_VJC:
1362 			ptype = vjc_print(q, ptype);
1363 			hdrlength = PPP_BSDI_HDRLEN;
1364 			p += hdrlength;
1365 			switch (ptype) {
1366 			case PPP_IP:
1367 				ip_print(p, length);
1368 				break;
1369 #ifdef INET6
1370 			case PPP_IPV6:
1371 				ip6_print(p, length);
1372 				break;
1373 #endif
1374 			case PPP_MPLS_UCAST:
1375 			case PPP_MPLS_MCAST:
1376 				mpls_print(p, length);
1377 				break;
1378 			}
1379 			goto printx;
1380 		case PPP_VJNC:
1381 			ptype = vjc_print(q, ptype);
1382 			hdrlength = PPP_BSDI_HDRLEN;
1383 			p += hdrlength;
1384 			switch (ptype) {
1385 			case PPP_IP:
1386 				ip_print(p, length);
1387 				break;
1388 #ifdef INET6
1389 			case PPP_IPV6:
1390 				ip6_print(p, length);
1391 				break;
1392 #endif
1393 			case PPP_MPLS_UCAST:
1394 			case PPP_MPLS_MCAST:
1395 				mpls_print(p, length);
1396 				break;
1397 			}
1398 			goto printx;
1399 		default:
1400 			if (eflag) {
1401 				printf("CH=[");
1402 				for (i = 0; i < p[SLC_LLHL]; i++)
1403 					printf("%02x", q[i]);
1404 				printf("] ");
1405 			}
1406 			break;
1407 		}
1408 	}
1409 
1410 	hdrlength = PPP_BSDI_HDRLEN;
1411 #endif
1412 
1413 	length -= hdrlength;
1414 	p += hdrlength;
1415 
1416 	switch (ptype) {
1417 	case PPP_IP:
1418 		ip_print(p, length);
1419 		break;
1420 #ifdef INET6
1421 	case PPP_IPV6:
1422 		ip6_print(p, length);
1423 		break;
1424 #endif
1425         case PPP_MPLS_UCAST:
1426         case PPP_MPLS_MCAST:
1427                 mpls_print(p, length);
1428                 break;
1429 	default:
1430 		printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype));
1431 	}
1432 
1433 printx:
1434 #else /* __bsdi */
1435 	hdrlength = 0;
1436 #endif /* __bsdi__ */
1437 	return (hdrlength);
1438 }
1439