xref: /freebsd/contrib/tcpdump/print-ppp.c (revision 5129159789cc9d7bc514e4546b88e3427695002d)
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  * $FreeBSD$
22  */
23 
24 #ifndef lint
25 static const char rcsid[] =
26     "@(#) $Header: print-ppp.c,v 1.26 97/06/12 14:21:29 leres Exp $ (LBL)";
27 #endif
28 
29 #include <sys/param.h>
30 #include <sys/time.h>
31 #include <sys/socket.h>
32 #include <sys/file.h>
33 #include <sys/ioctl.h>
34 
35 #if __STDC__
36 struct mbuf;
37 struct rtentry;
38 #endif
39 #include <net/if.h>
40 
41 #include <netinet/in.h>
42 #include <netinet/in_systm.h>
43 #include <netinet/ip.h>
44 
45 #include <ctype.h>
46 #include <netdb.h>
47 #include <pcap.h>
48 #include <stdio.h>
49 
50 #include <net/ethernet.h>
51 #include "ethertype.h"
52 
53 #include <net/ppp_defs.h>
54 #include "interface.h"
55 #include "addrtoname.h"
56 #include "ppp.h"
57 
58 struct protonames {
59 	u_short protocol;
60 	char *name;
61 };
62 
63 static struct protonames protonames[] = {
64 	/*
65 	 * Protocol field values.
66 	 */
67 	PPP_IP,		"IP",		/* Internet Protocol */
68 	PPP_XNS,	"XNS",		/* Xerox NS */
69 	PPP_IPX,	"IPX",		/* IPX Datagram (RFC1552) */
70 	PPP_VJC_COMP,	"VJC_UNCOMP",	/* VJ compressed TCP */
71 	PPP_VJC_UNCOMP,	"VJC_UNCOMP",	/* VJ uncompressed TCP */
72 	PPP_COMP,	"COMP",		/* compressed packet */
73 	PPP_IPCP,	"IPCP",		/* IP Control Protocol */
74 	PPP_IPXCP,	"IPXCP",	/* IPX Control Protocol (RFC1552) */
75 	PPP_CCP,	"CCP",		/* Compression Control Protocol */
76 	PPP_LCP,	"LCP",		/* Link Control Protocol */
77 	PPP_PAP,	"PAP",		/* Password Authentication Protocol */
78 	PPP_LQR,	"LQR",		/* Link Quality Report protocol */
79 	PPP_CHAP,	"CHAP",		/* Cryptographic Handshake Auth. Proto*/
80 };
81 
82 /* LCP */
83 
84 #define LCP_CONF_REQ	1
85 #define LCP_CONF_ACK	2
86 #define LCP_CONF_NAK	3
87 #define LCP_CONF_REJ	4
88 #define LCP_TERM_REQ	5
89 #define LCP_TERM_ACK	6
90 #define LCP_CODE_REJ	7
91 #define LCP_PROT_REJ	8
92 #define LCP_ECHO_REQ	9
93 #define LCP_ECHO_RPL	10
94 #define LCP_DISC_REQ	11
95 
96 #define LCP_MIN	LCP_CONF_REQ
97 #define LCP_MAX LCP_DISC_REQ
98 
99 static char *lcpcodes[] = {
100 	/*
101 	 * LCP code values (RFC1661, pp26)
102 	 */
103 	"Configure-Request",
104 	"Configure-Ack",
105 	"Configure-Nak",
106 	"Configure-Reject",
107 	"Terminate-Request",
108 	"Terminate-Ack",
109  	"Code-Reject",
110 	"Protocol-Reject",
111 	"Echo-Request",
112 	"Echo-Reply",
113 	"Discard-Request",
114 };
115 
116 #define LCPOPT_VEXT	0
117 #define LCPOPT_MRU	1
118 #define LCPOPT_ACCM	2
119 #define LCPOPT_AP	3
120 #define LCPOPT_QP	4
121 #define LCPOPT_MN	5
122 #define LCPOPT_PFC	7
123 #define LCPOPT_ACFC	8
124 
125 #define LCPOPT_MIN 0
126 #define LCPOPT_MAX 24
127 
128 static char *lcpconfopts[] = {
129 	"Vendor-Ext",
130 	"Max-Rx-Unit",
131 	"Async-Ctrl-Char-Map",
132 	"Auth-Prot",
133 	"Quality-Prot",
134 	"Magic-Number",
135 	"unassigned (6)",
136 	"Prot-Field-Compr",
137 	"Add-Ctrl-Field-Compr",
138 	"FCS-Alternatives",
139 	"Self-Describing-Pad",
140 	"Numbered-Mode",
141 	"Multi-Link-Procedure",
142 	"Call-Back",
143 	"Connect-Time",
144 	"Compund-Frames",
145 	"Nominal-Data-Encap",
146 	"Multilink-MRRU",
147 	"Multilink-SSNHF",
148 	"Multilink-ED",
149 	"Proprietary",
150 	"DCE-Identifier",
151 	"Multilink-Plus-Proc",
152 	"Link-Discriminator",
153 	"LCP-Auth-Option",
154 };
155 
156 /* CHAP */
157 
158 #define CHAP_CHAL	1
159 #define CHAP_RESP	2
160 #define CHAP_SUCC	3
161 #define CHAP_FAIL	4
162 
163 #define CHAP_CODEMIN 1
164 #define CHAP_CODEMAX 4
165 
166 static char *chapcode[] = {
167 	"Challenge",
168 	"Response",
169 	"Success",
170 	"Failure",
171 };
172 
173 /* PAP */
174 
175 #define PAP_AREQ	1
176 #define PAP_AACK	2
177 #define PAP_ANAK	3
178 
179 #define PAP_CODEMIN	1
180 #define PAP_CODEMAX	3
181 
182 static char *papcode[] = {
183 	"Authenticate-Request",
184 	"Authenticate-Ack",
185 	"Authenticate-Nak",
186 };
187 
188 /* IPCP */
189 
190 #define IPCP_2ADDR	1
191 #define IPCP_CP		2
192 #define IPCP_ADDR	3
193 
194 /* PPPoE */
195 
196 struct typenames {
197 	u_short type;
198 	char *name;
199 };
200 
201 static struct typenames typenames[] = {
202 	/*
203 	 * PPPoE type field values
204 	 */
205 	0x00,	"DATA",			/* PPPoE Data packet                */
206 	0x09,	"PADI",			/* Active Discovery Initiation      */
207 	0x07,	"PADO",			/* Active Discovery Offer           */
208 	0x19,	"PADR",			/* Active Discovery Request         */
209 	0x65,	"PADS",			/* Active Discovery Session-Confirm */
210 	0xa7,	"PADT",			/* Active Discovery Terminate       */
211 };
212 
213 struct tagnames {
214 	u_short tag;
215 	char *name;
216 	int isascii;
217 };
218 
219 static struct tagnames tagnames[] = {
220   /*
221    * PPPoE tag field values
222    */
223   0x0000, "End-Of-List",	0,	/* Optional last tag (len 0) */
224   0x0101, "Service-Name",	1,	/* The (ascii) service */
225   0x0102, "AC-Name",		-1,	/* Access Concentrator */
226   0x0103, "Host-Uniq",		0,	/* Associate PAD[OS] with PAD[IR] */
227   0x0104, "AC-Cookie",		0,	/* Optional at PADO time */
228   0x0105, "Vendor-Specific",	0,	/* First 4 bytes special (ignore) */
229   0x0110, "Relay-Session-Id",	0,	/* Max 12 octets, added by gateway */
230   0x0201, "Service-Name-Error",	-1,	/* Request not honoured */
231   0x0203, "Generic-Error",	1	/* Access Concentrator error */
232 };
233 
234 static int handle_lcp(const u_char *p, int length);
235 static int print_lcp_config_options(u_char *p);
236 static int handle_chap(const u_char *p, int length);
237 static int handle_ipcp(const u_char *p, int length);
238 static int handle_pap(const u_char *p, int length);
239 static void do_ppp_print(const u_char *p, u_int length, u_int caplen);
240 
241 /* Standard PPP printer */
242 void
243 ppp_hdlc_print(const u_char *p, int length)
244 {
245 	int proto = PPP_PROTOCOL(p);
246 	int i, j, x;
247 	u_char *ptr;
248 
249 	printf("ID-%03d ", *(p+5));
250 
251 	for (i = (sizeof(protonames) / sizeof(protonames[0])) - 1; i >= 0; --i)
252 	{
253 		if (proto == protonames[i].protocol)
254 		{
255 			printf("%s: ", protonames[i].name);
256 
257 			switch(proto)
258 			{
259 				case PPP_LCP:
260 					handle_lcp(p, length);
261 					break;
262 				case PPP_CHAP:
263 					handle_chap(p, length);
264 					break;
265 				case PPP_PAP:
266 					handle_pap(p, length);
267 					break;
268 				case PPP_IPCP:
269 					handle_ipcp(p, length);
270 					break;
271 			}
272 			break;
273 		}
274 	}
275 	if (i < 0)
276 	{
277 		printf("%04x: ", proto);
278 	}
279 }
280 
281 /* print LCP frame */
282 
283 static int
284 handle_lcp(const u_char *p, int length)
285 {
286 	int x, j;
287 	u_char *ptr;
288 
289 	x = *(p+4);
290 
291 	if((x >= LCP_MIN) && (x <= LCP_MAX))
292 	{
293 		printf("%s", lcpcodes[x-1]);
294 	}
295 	else
296 	{
297 		printf("0x%02x", x);
298 		return;
299 	}
300 
301 	length -= 4;
302 
303 	switch(x)
304 	{
305 		case LCP_CONF_REQ:
306 		case LCP_CONF_ACK:
307 		case LCP_CONF_NAK:
308 		case LCP_CONF_REJ:
309 			x = length;
310 			ptr = (u_char *)p+8;
311 			do
312 			{
313 				if((j = print_lcp_config_options(ptr)) == 0)
314 					break;
315 				x -= j;
316 				ptr += j;
317 			}
318 			while(x > 0);
319 			break;
320 
321 		case LCP_ECHO_REQ:
322 		case LCP_ECHO_RPL:
323 			printf(", Magic-Number=%d", ((*(p+8) << 24) + (*(p+9) << 16) + (*(p+10) << 8) + (*(p+11))));
324 			break;
325 		case LCP_TERM_REQ:
326 		case LCP_TERM_ACK:
327 		case LCP_CODE_REJ:
328 		case LCP_PROT_REJ:
329 		case LCP_DISC_REQ:
330 		default:
331 			break;
332 	}
333 }
334 
335 /* LCP config options */
336 
337 static int
338 print_lcp_config_options(u_char *p)
339 {
340 	int len	= *(p+1);
341 	int opt = *p;
342 
343 	if((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
344 		printf(", %s", lcpconfopts[opt]);
345 
346 	switch(opt)
347 	{
348 		case LCPOPT_MRU:
349 			if(len == 4)
350 				printf("=%d", (*(p+2) << 8) + *(p+3));
351 			break;
352 		case LCPOPT_AP:
353 			if(len >= 4)
354 			{
355 				if(*(p+2) == 0xc0 && *(p+3) == 0x23)
356 				{
357 					printf(" PAP");
358 				}
359 				else if(*(p+2) == 0xc2 && *(p+3) == 0x23)
360 				{
361 					printf(" CHAP/");
362 					switch(*(p+4))
363 					{
364 						default:
365 							printf("unknown-algorithm-%d", *(p+4));
366 							break;
367 						case 5:
368 							printf("MD5");
369 							break;
370 						case 0x80:
371 							printf("Microsoft");
372 							break;
373 					}
374 				}
375 				else if(*(p+2) == 0xc2 && *(p+3) == 0x27)
376 				{
377 					printf(" EAP");
378 				}
379 				else if(*(p+2) == 0xc0 && *(p+3) == 0x27)
380 				{
381 					printf(" SPAP");
382 				}
383 				else if(*(p+2) == 0xc1 && *(p+3) == 0x23)
384 				{
385 					printf(" Old-SPAP");
386 				}
387 				else
388 				{
389 					printf("unknown");
390 				}
391 			}
392 			break;
393 		case LCPOPT_QP:
394 			if(len >= 4)
395 			{
396 				if(*(p+2) == 0xc0 && *(p+3) == 0x25)
397 					printf(" LQR");
398 				else
399 					printf(" unknown");
400 			}
401 			break;
402 		case LCPOPT_MN:
403 			if(len == 6)
404 			{
405 				printf("=%d", ((*(p+2) << 24) + (*(p+3) << 16) + (*(p+4) << 8) + (*(p+5))));
406 			}
407 			break;
408 		case LCPOPT_PFC:
409 			printf(" PFC");
410 			break;
411 		case LCPOPT_ACFC:
412 			printf(" ACFC");
413 			break;
414 	}
415 	return(len);
416 }
417 
418 /* CHAP */
419 
420 static int
421 handle_chap(const u_char *p, int length)
422 {
423 	int x, j;
424 	u_char *ptr;
425 
426 	x = *(p+4);
427 
428 	if((x >= CHAP_CODEMIN) && (x <= CHAP_CODEMAX))
429 	{
430 		printf("%s", chapcode[x-1]);
431 	}
432 	else
433 	{
434 		printf("0x%02x", x);
435 		return;
436 	}
437 
438 	length -= 4;
439 
440 	switch(x)
441 	{
442 		case CHAP_CHAL:
443 		case CHAP_RESP:
444 			printf(", Value=");
445 			x = *(p+8);	/* value size */
446 			ptr = (u_char *)p+9;
447 			while(--x >= 0)
448 				printf("%02x", *ptr++);
449 			x = length - *(p+8) - 1;
450 			printf(", Name=");
451 			while(--x >= 0)
452 				printf("%c", *ptr++);
453 			break;
454 	}
455 }
456 
457 /* PAP */
458 
459 static int
460 handle_pap(const u_char *p, int length)
461 {
462 	int x, j;
463 	u_char *ptr;
464 
465 	x = *(p+4);
466 
467 	if((x >= PAP_CODEMIN) && (x <= PAP_CODEMAX))
468 	{
469 		printf("%s", papcode[x-1]);
470 	}
471 	else
472 	{
473 		printf("0x%02x", x);
474 		return;
475 	}
476 
477 	length -= 4;
478 
479 	switch(x)
480 	{
481 		case PAP_AREQ:
482 			printf(", Peer-Id=");
483 			x = *(p+8);	/* peerid size */
484 			ptr = (u_char *)p+9;
485 			while(--x >= 0)
486 				printf("%c", *ptr++);
487 			x = *ptr++;
488 			printf(", Passwd=");
489 			while(--x >= 0)
490 				printf("%c", *ptr++);
491 			break;
492 		case PAP_AACK:
493 		case PAP_ANAK:
494 			break;
495 	}
496 }
497 
498 /* IPCP */
499 
500 static int
501 handle_ipcp(const u_char *p, int length)
502 {
503 	int x, j;
504 
505 	x = *(p+8);
506 
507 	length -= 4;
508 
509 	switch(x)
510 	{
511 		case IPCP_2ADDR:
512 			printf("IP-Addresses");
513 			printf(", Src=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
514 			printf(", Dst=%d.%d.%d.%d", *(p+14), *(p+15), *(p+16), *(p+17));
515 			break;
516 
517 		case IPCP_CP:
518 			printf("IP-Compression-Protocol");
519 			break;
520 
521 		case IPCP_ADDR:
522 			printf("IP-Address=%d.%d.%d.%d", *(p+10), *(p+11), *(p+12), *(p+13));
523 			break;
524 	}
525 }
526 
527 void
528 ppp_if_print(u_char *user, const struct pcap_pkthdr *h,
529 	     register const u_char *p)
530 {
531 	register u_int length = h->len;
532 	register u_int caplen = h->caplen;
533 
534 	ts_print(&h->ts);
535 
536 	if (caplen < PPP_HDRLEN) {
537 		puts("[|ppp]");
538 		return;
539 	}
540 
541 	/*
542 	 * Some printers want to get back at the link level addresses,
543 	 * and/or check that they're not walking off the end of the packet.
544 	 * Rather than pass them all the way down, we set these globals.
545 	 */
546 	packetp = p;
547 	snapend = p + caplen;
548 
549 	do_ppp_print(p, length, caplen);
550 }
551 
552 /*
553  * Print PPPoE discovery & session packets
554  */
555 void
556 pppoe_print(const u_char *p, u_int length)
557 {
558 	u_short tag, len, tlen;
559 	u_char type;
560 	int f, asc;
561 
562 	fputs("PPPoE ", stdout);
563 
564 	/*
565 	 * A PPPoE header:
566 	 *
567 	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
568 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
569 	 * |  VER  | TYPE  |      CODE     |          SESSION_ID           |
570 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
571 	 * |            LENGTH             |           payload             ~
572 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
573 	 */
574 
575 	type = p[1];
576 	for (f = sizeof typenames / sizeof typenames[0] - 1; f >= 0; f--)
577 		if (typenames[f].type == type) {
578 			fputs(typenames[f].name, stdout);
579 			break;
580 		}
581 
582 	if (f == -1) {
583 		printf("<0x%02x>\n", type);
584 	}
585 
586 	len = ntohs(*(u_short *)(p + 4));
587 	printf(" v%d, type %d, sess %d len %d", p[0] >> 4, p[0] & 0xf,
588 	    ntohs(*(u_short *)(p + 2)), len);
589 
590 	if (type == 0x00) {
591 		/* This is a data packet */
592 		p += 4;
593 		fputs("] ", stdout);
594 		/* If eflag is set, ignore the trailing 2 bytes for LCP... */
595 		do_ppp_print(p, eflag ? len - 2 : len + 2, len + 4);
596 		return;
597 	}
598 
599 	p += 6;
600 	length -= 6;
601 	if (len > length)
602 		len = length;	/* puke ! */
603 
604 	/*
605 	 * A PPPoE tag:
606 	 *
607 	 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
608 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
609 	 * |          TAG_TYPE             |        TAG_LENGTH             |
610 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
611 	 * |          TAG_VALUE ...                                        ~
612 	 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
613 	 */
614 
615 	while (len >= 4) {
616 		tag = ntohs(*(u_short *)p);
617 		tlen = ntohs(*(u_short *)(p + 2));
618 
619 		fputs(" [", stdout);
620 		for (f = sizeof tagnames / sizeof tagnames[0] - 1; f >= 0; f--)
621 			if (tagnames[f].tag == tag) {
622 				asc = tagnames[f].isascii;
623 				fputs(tagnames[f].name, stdout);
624         			break;
625       			}
626 
627 		if (f == -1) {
628 			printf("<0x%04x>", tag);
629 			asc = -1;
630 		}
631 
632 		p += 4;
633 		if (tlen > 0) {
634 			if (asc == -1) {
635 				for (f = 0; f < tlen; f++)
636 					if (!isascii(p[f]))
637 						break;
638 				asc = f == tlen;
639 			}
640 			fputc(' ', stdout);
641 			if (asc)
642 				printf("%.*s", (int)tlen, p);
643 			else for (f = 0; f < tlen; f++)
644 				printf("%02x", p[f]);
645 		}
646 		fputc(']', stdout);
647 
648 		p += tlen;
649 		len -= tlen + 4;
650 	}
651 }
652 
653 /*
654  * Actually do the job
655  */
656 static void
657 do_ppp_print(const u_char *p, u_int length, u_int caplen)
658 {
659 	if (eflag)
660 		ppp_hdlc_print(p, length);
661 
662 	length -= PPP_HDRLEN;
663 
664 	switch(PPP_PROTOCOL(p)) {
665 	case PPP_IP:
666 	case ETHERTYPE_IP:
667 		ip_print((const u_char *)(p + PPP_HDRLEN), length);
668 		break;
669 	case PPP_IPX:
670 	case ETHERTYPE_IPX:
671 		ipx_print((const u_char *)(p + PPP_HDRLEN), length);
672 		break;
673 
674 	default:
675 		if(!eflag)
676 			ppp_hdlc_print(p, length);
677 		if(!xflag)
678 			default_print((const u_char *)(p + PPP_HDRLEN),
679 					caplen - PPP_HDRLEN);
680 	}
681 
682 	if (xflag)
683 		default_print((const u_char *)(p + PPP_HDRLEN),
684 				caplen - PPP_HDRLEN);
685 out:
686 	putchar('\n');
687 }
688 
689 /* proto type to string mapping */
690 static struct tok ptype2str[] = {
691 	{ PPP_VJC,	"VJC" },
692 	{ PPP_VJNC,	"VJNC" },
693 	{ PPP_OSI,	"OSI" },
694 	{ PPP_LCP,	"LCP" },
695 	{ PPP_IPCP,	"IPCP" },
696 	{ 0,		NULL }
697 };
698 
699 #define PPP_BSDI_HDRLEN 24
700 
701 /* BSD/OS specific PPP printer */
702 void
703 ppp_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h,
704 	     register const u_char *p)
705 {
706 	register u_int length = h->len;
707 	register u_int caplen = h->caplen;
708 	register int hdrlength;
709 	u_short ptype;
710 
711 	ts_print(&h->ts);
712 
713 	if (caplen < PPP_BSDI_HDRLEN) {
714 		printf("[|ppp]");
715 		goto out;
716 	}
717 
718 	/*
719 	 * Some printers want to get back at the link level addresses,
720 	 * and/or check that they're not walking off the end of the packet.
721 	 * Rather than pass them all the way down, we set these globals.
722 	 */
723 	packetp = p;
724 	snapend = p + caplen;
725 	hdrlength = 0;
726 
727 	if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
728 		if (eflag)
729 			printf("%02x %02x ", p[0], p[1]);
730 		p += 2;
731 		hdrlength = 2;
732 	}
733 
734 	if (eflag)
735 		printf("%d ", length);
736 	/* Retrieve the protocol type */
737 	if (*p & 01) {
738 		/* Compressed protocol field */
739 		ptype = *p;
740 		if (eflag)
741 			printf("%02x ", ptype);
742 		p++;
743 		hdrlength += 1;
744 	} else {
745 		/* Un-compressed protocol field */
746 		ptype = ntohs(*(u_short *)p);
747 		if (eflag)
748 			printf("%04x ", ptype);
749 		p += 2;
750 		hdrlength += 2;
751 	}
752 
753 	length -= hdrlength;
754 
755 	if (ptype == PPP_IP)
756 		ip_print(p, length);
757 	else
758 		printf("%s ", tok2str(ptype2str, "proto-#%d", ptype));
759 
760 	if (xflag)
761 		default_print((const u_char *)p, caplen - hdrlength);
762 out:
763 	putchar('\n');
764 }
765