xref: /minix3/external/bsd/tcpdump/dist/print-ppp.c (revision b636d99d91c3d54204248f643c14627405d4afd1)
1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek  * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
3*b636d99dSDavid van Moolenbroek  *	The Regents of the University of California.  All rights reserved.
4*b636d99dSDavid van Moolenbroek  *
5*b636d99dSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek  * modification, are permitted provided that: (1) source code distributions
7*b636d99dSDavid van Moolenbroek  * retain the above copyright notice and this paragraph in its entirety, (2)
8*b636d99dSDavid van Moolenbroek  * distributions including binary code include the above copyright notice and
9*b636d99dSDavid van Moolenbroek  * this paragraph in its entirety in the documentation or other materials
10*b636d99dSDavid van Moolenbroek  * provided with the distribution, and (3) all advertising materials mentioning
11*b636d99dSDavid van Moolenbroek  * features or use of this software display the following acknowledgement:
12*b636d99dSDavid van Moolenbroek  * ``This product includes software developed by the University of California,
13*b636d99dSDavid van Moolenbroek  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*b636d99dSDavid van Moolenbroek  * the University nor the names of its contributors may be used to endorse
15*b636d99dSDavid van Moolenbroek  * or promote products derived from this software without specific prior
16*b636d99dSDavid van Moolenbroek  * written permission.
17*b636d99dSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*b636d99dSDavid van Moolenbroek  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*b636d99dSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*b636d99dSDavid van Moolenbroek  *
21*b636d99dSDavid van Moolenbroek  * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
22*b636d99dSDavid van Moolenbroek  * complete PPP support.
23*b636d99dSDavid van Moolenbroek  */
24*b636d99dSDavid van Moolenbroek 
25*b636d99dSDavid van Moolenbroek /*
26*b636d99dSDavid van Moolenbroek  * TODO:
27*b636d99dSDavid van Moolenbroek  * o resolve XXX as much as possible
28*b636d99dSDavid van Moolenbroek  * o MP support
29*b636d99dSDavid van Moolenbroek  * o BAP support
30*b636d99dSDavid van Moolenbroek  */
31*b636d99dSDavid van Moolenbroek 
32*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
33*b636d99dSDavid van Moolenbroek #ifndef lint
34*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-ppp.c,v 1.6 2015/03/31 21:59:35 christos Exp $");
35*b636d99dSDavid van Moolenbroek #endif
36*b636d99dSDavid van Moolenbroek 
37*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
38*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
39*b636d99dSDavid van Moolenbroek #include "config.h"
40*b636d99dSDavid van Moolenbroek #endif
41*b636d99dSDavid van Moolenbroek 
42*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
43*b636d99dSDavid van Moolenbroek 
44*b636d99dSDavid van Moolenbroek #ifdef __bsdi__
45*b636d99dSDavid van Moolenbroek #include <net/slcompress.h>
46*b636d99dSDavid van Moolenbroek #include <net/if_ppp.h>
47*b636d99dSDavid van Moolenbroek #endif
48*b636d99dSDavid van Moolenbroek 
49*b636d99dSDavid van Moolenbroek #include <stdlib.h>
50*b636d99dSDavid van Moolenbroek 
51*b636d99dSDavid van Moolenbroek #include "interface.h"
52*b636d99dSDavid van Moolenbroek #include "extract.h"
53*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
54*b636d99dSDavid van Moolenbroek #include "ppp.h"
55*b636d99dSDavid van Moolenbroek #include "chdlc.h"
56*b636d99dSDavid van Moolenbroek #include "ethertype.h"
57*b636d99dSDavid van Moolenbroek #include "oui.h"
58*b636d99dSDavid van Moolenbroek 
59*b636d99dSDavid van Moolenbroek /*
60*b636d99dSDavid van Moolenbroek  * The following constatns are defined by IANA. Please refer to
61*b636d99dSDavid van Moolenbroek  *    http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
62*b636d99dSDavid van Moolenbroek  * for the up-to-date information.
63*b636d99dSDavid van Moolenbroek  */
64*b636d99dSDavid van Moolenbroek 
65*b636d99dSDavid van Moolenbroek /* Protocol Codes defined in ppp.h */
66*b636d99dSDavid van Moolenbroek 
67*b636d99dSDavid van Moolenbroek static const struct tok ppptype2str[] = {
68*b636d99dSDavid van Moolenbroek         { PPP_IP,	  "IP" },
69*b636d99dSDavid van Moolenbroek         { PPP_OSI,	  "OSI" },
70*b636d99dSDavid van Moolenbroek         { PPP_NS,	  "NS" },
71*b636d99dSDavid van Moolenbroek         { PPP_DECNET,	  "DECNET" },
72*b636d99dSDavid van Moolenbroek         { PPP_APPLE,	  "APPLE" },
73*b636d99dSDavid van Moolenbroek 	{ PPP_IPX,	  "IPX" },
74*b636d99dSDavid van Moolenbroek 	{ PPP_VJC,	  "VJC IP" },
75*b636d99dSDavid van Moolenbroek 	{ PPP_VJNC,	  "VJNC IP" },
76*b636d99dSDavid van Moolenbroek 	{ PPP_BRPDU,	  "BRPDU" },
77*b636d99dSDavid van Moolenbroek 	{ PPP_STII,	  "STII" },
78*b636d99dSDavid van Moolenbroek 	{ PPP_VINES,	  "VINES" },
79*b636d99dSDavid van Moolenbroek 	{ PPP_MPLS_UCAST, "MPLS" },
80*b636d99dSDavid van Moolenbroek 	{ PPP_MPLS_MCAST, "MPLS" },
81*b636d99dSDavid van Moolenbroek         { PPP_COMP,       "Compressed"},
82*b636d99dSDavid van Moolenbroek         { PPP_ML,         "MLPPP"},
83*b636d99dSDavid van Moolenbroek         { PPP_IPV6,       "IP6"},
84*b636d99dSDavid van Moolenbroek 
85*b636d99dSDavid van Moolenbroek 	{ PPP_HELLO,	  "HELLO" },
86*b636d99dSDavid van Moolenbroek 	{ PPP_LUXCOM,	  "LUXCOM" },
87*b636d99dSDavid van Moolenbroek 	{ PPP_SNS,	  "SNS" },
88*b636d99dSDavid van Moolenbroek 	{ PPP_IPCP,	  "IPCP" },
89*b636d99dSDavid van Moolenbroek 	{ PPP_OSICP,	  "OSICP" },
90*b636d99dSDavid van Moolenbroek 	{ PPP_NSCP,	  "NSCP" },
91*b636d99dSDavid van Moolenbroek 	{ PPP_DECNETCP,   "DECNETCP" },
92*b636d99dSDavid van Moolenbroek 	{ PPP_APPLECP,	  "APPLECP" },
93*b636d99dSDavid van Moolenbroek 	{ PPP_IPXCP,	  "IPXCP" },
94*b636d99dSDavid van Moolenbroek 	{ PPP_STIICP,	  "STIICP" },
95*b636d99dSDavid van Moolenbroek 	{ PPP_VINESCP,	  "VINESCP" },
96*b636d99dSDavid van Moolenbroek         { PPP_IPV6CP,     "IP6CP" },
97*b636d99dSDavid van Moolenbroek 	{ PPP_MPLSCP,	  "MPLSCP" },
98*b636d99dSDavid van Moolenbroek 
99*b636d99dSDavid van Moolenbroek 	{ PPP_LCP,	  "LCP" },
100*b636d99dSDavid van Moolenbroek 	{ PPP_PAP,	  "PAP" },
101*b636d99dSDavid van Moolenbroek 	{ PPP_LQM,	  "LQM" },
102*b636d99dSDavid van Moolenbroek 	{ PPP_CHAP,	  "CHAP" },
103*b636d99dSDavid van Moolenbroek 	{ PPP_EAP,	  "EAP" },
104*b636d99dSDavid van Moolenbroek 	{ PPP_SPAP,	  "SPAP" },
105*b636d99dSDavid van Moolenbroek 	{ PPP_SPAP_OLD,	  "Old-SPAP" },
106*b636d99dSDavid van Moolenbroek 	{ PPP_BACP,	  "BACP" },
107*b636d99dSDavid van Moolenbroek 	{ PPP_BAP,	  "BAP" },
108*b636d99dSDavid van Moolenbroek 	{ PPP_MPCP,	  "MLPPP-CP" },
109*b636d99dSDavid van Moolenbroek 	{ PPP_CCP,	  "CCP" },
110*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
111*b636d99dSDavid van Moolenbroek };
112*b636d99dSDavid van Moolenbroek 
113*b636d99dSDavid van Moolenbroek /* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */
114*b636d99dSDavid van Moolenbroek 
115*b636d99dSDavid van Moolenbroek #define CPCODES_VEXT		0	/* Vendor-Specific (RFC2153) */
116*b636d99dSDavid van Moolenbroek #define CPCODES_CONF_REQ	1	/* Configure-Request */
117*b636d99dSDavid van Moolenbroek #define CPCODES_CONF_ACK	2	/* Configure-Ack */
118*b636d99dSDavid van Moolenbroek #define CPCODES_CONF_NAK	3	/* Configure-Nak */
119*b636d99dSDavid van Moolenbroek #define CPCODES_CONF_REJ	4	/* Configure-Reject */
120*b636d99dSDavid van Moolenbroek #define CPCODES_TERM_REQ	5	/* Terminate-Request */
121*b636d99dSDavid van Moolenbroek #define CPCODES_TERM_ACK	6	/* Terminate-Ack */
122*b636d99dSDavid van Moolenbroek #define CPCODES_CODE_REJ	7	/* Code-Reject */
123*b636d99dSDavid van Moolenbroek #define CPCODES_PROT_REJ	8	/* Protocol-Reject (LCP only) */
124*b636d99dSDavid van Moolenbroek #define CPCODES_ECHO_REQ	9	/* Echo-Request (LCP only) */
125*b636d99dSDavid van Moolenbroek #define CPCODES_ECHO_RPL	10	/* Echo-Reply (LCP only) */
126*b636d99dSDavid van Moolenbroek #define CPCODES_DISC_REQ	11	/* Discard-Request (LCP only) */
127*b636d99dSDavid van Moolenbroek #define CPCODES_ID		12	/* Identification (LCP only) RFC1570 */
128*b636d99dSDavid van Moolenbroek #define CPCODES_TIME_REM	13	/* Time-Remaining (LCP only) RFC1570 */
129*b636d99dSDavid van Moolenbroek #define CPCODES_RESET_REQ	14	/* Reset-Request (CCP only) RFC1962 */
130*b636d99dSDavid van Moolenbroek #define CPCODES_RESET_REP	15	/* Reset-Reply (CCP only) */
131*b636d99dSDavid van Moolenbroek 
132*b636d99dSDavid van Moolenbroek static const struct tok cpcodes[] = {
133*b636d99dSDavid van Moolenbroek 	{CPCODES_VEXT,      "Vendor-Extension"}, /* RFC2153 */
134*b636d99dSDavid van Moolenbroek 	{CPCODES_CONF_REQ,  "Conf-Request"},
135*b636d99dSDavid van Moolenbroek         {CPCODES_CONF_ACK,  "Conf-Ack"},
136*b636d99dSDavid van Moolenbroek 	{CPCODES_CONF_NAK,  "Conf-Nack"},
137*b636d99dSDavid van Moolenbroek 	{CPCODES_CONF_REJ,  "Conf-Reject"},
138*b636d99dSDavid van Moolenbroek 	{CPCODES_TERM_REQ,  "Term-Request"},
139*b636d99dSDavid van Moolenbroek 	{CPCODES_TERM_ACK,  "Term-Ack"},
140*b636d99dSDavid van Moolenbroek 	{CPCODES_CODE_REJ,  "Code-Reject"},
141*b636d99dSDavid van Moolenbroek 	{CPCODES_PROT_REJ,  "Prot-Reject"},
142*b636d99dSDavid van Moolenbroek 	{CPCODES_ECHO_REQ,  "Echo-Request"},
143*b636d99dSDavid van Moolenbroek 	{CPCODES_ECHO_RPL,  "Echo-Reply"},
144*b636d99dSDavid van Moolenbroek 	{CPCODES_DISC_REQ,  "Disc-Req"},
145*b636d99dSDavid van Moolenbroek 	{CPCODES_ID,        "Ident"},            /* RFC1570 */
146*b636d99dSDavid van Moolenbroek 	{CPCODES_TIME_REM,  "Time-Rem"},         /* RFC1570 */
147*b636d99dSDavid van Moolenbroek 	{CPCODES_RESET_REQ, "Reset-Req"},        /* RFC1962 */
148*b636d99dSDavid van Moolenbroek 	{CPCODES_RESET_REP, "Reset-Ack"},        /* RFC1962 */
149*b636d99dSDavid van Moolenbroek         {0,                 NULL}
150*b636d99dSDavid van Moolenbroek };
151*b636d99dSDavid van Moolenbroek 
152*b636d99dSDavid van Moolenbroek /* LCP Config Options */
153*b636d99dSDavid van Moolenbroek 
154*b636d99dSDavid van Moolenbroek #define LCPOPT_VEXT	0
155*b636d99dSDavid van Moolenbroek #define LCPOPT_MRU	1
156*b636d99dSDavid van Moolenbroek #define LCPOPT_ACCM	2
157*b636d99dSDavid van Moolenbroek #define LCPOPT_AP	3
158*b636d99dSDavid van Moolenbroek #define LCPOPT_QP	4
159*b636d99dSDavid van Moolenbroek #define LCPOPT_MN	5
160*b636d99dSDavid van Moolenbroek #define LCPOPT_DEP6	6
161*b636d99dSDavid van Moolenbroek #define LCPOPT_PFC	7
162*b636d99dSDavid van Moolenbroek #define LCPOPT_ACFC	8
163*b636d99dSDavid van Moolenbroek #define LCPOPT_FCSALT	9
164*b636d99dSDavid van Moolenbroek #define LCPOPT_SDP	10
165*b636d99dSDavid van Moolenbroek #define LCPOPT_NUMMODE	11
166*b636d99dSDavid van Moolenbroek #define LCPOPT_DEP12	12
167*b636d99dSDavid van Moolenbroek #define LCPOPT_CBACK	13
168*b636d99dSDavid van Moolenbroek #define LCPOPT_DEP14	14
169*b636d99dSDavid van Moolenbroek #define LCPOPT_DEP15	15
170*b636d99dSDavid van Moolenbroek #define LCPOPT_DEP16	16
171*b636d99dSDavid van Moolenbroek #define LCPOPT_MLMRRU	17
172*b636d99dSDavid van Moolenbroek #define LCPOPT_MLSSNHF	18
173*b636d99dSDavid van Moolenbroek #define LCPOPT_MLED	19
174*b636d99dSDavid van Moolenbroek #define LCPOPT_PROP	20
175*b636d99dSDavid van Moolenbroek #define LCPOPT_DCEID	21
176*b636d99dSDavid van Moolenbroek #define LCPOPT_MPP	22
177*b636d99dSDavid van Moolenbroek #define LCPOPT_LD	23
178*b636d99dSDavid van Moolenbroek #define LCPOPT_LCPAOPT	24
179*b636d99dSDavid van Moolenbroek #define LCPOPT_COBS	25
180*b636d99dSDavid van Moolenbroek #define LCPOPT_PE	26
181*b636d99dSDavid van Moolenbroek #define LCPOPT_MLHF	27
182*b636d99dSDavid van Moolenbroek #define LCPOPT_I18N	28
183*b636d99dSDavid van Moolenbroek #define LCPOPT_SDLOS	29
184*b636d99dSDavid van Moolenbroek #define LCPOPT_PPPMUX	30
185*b636d99dSDavid van Moolenbroek 
186*b636d99dSDavid van Moolenbroek #define LCPOPT_MIN LCPOPT_VEXT
187*b636d99dSDavid van Moolenbroek #define LCPOPT_MAX LCPOPT_PPPMUX
188*b636d99dSDavid van Moolenbroek 
189*b636d99dSDavid van Moolenbroek static const char *lcpconfopts[] = {
190*b636d99dSDavid van Moolenbroek 	"Vend-Ext",		/* (0) */
191*b636d99dSDavid van Moolenbroek 	"MRU",			/* (1) */
192*b636d99dSDavid van Moolenbroek 	"ACCM",			/* (2) */
193*b636d99dSDavid van Moolenbroek 	"Auth-Prot",		/* (3) */
194*b636d99dSDavid van Moolenbroek 	"Qual-Prot",		/* (4) */
195*b636d99dSDavid van Moolenbroek 	"Magic-Num",		/* (5) */
196*b636d99dSDavid van Moolenbroek 	"deprecated(6)",	/* used to be a Quality Protocol */
197*b636d99dSDavid van Moolenbroek 	"PFC",			/* (7) */
198*b636d99dSDavid van Moolenbroek 	"ACFC",			/* (8) */
199*b636d99dSDavid van Moolenbroek 	"FCS-Alt",		/* (9) */
200*b636d99dSDavid van Moolenbroek 	"SDP",			/* (10) */
201*b636d99dSDavid van Moolenbroek 	"Num-Mode",		/* (11) */
202*b636d99dSDavid van Moolenbroek 	"deprecated(12)",	/* used to be a Multi-Link-Procedure*/
203*b636d99dSDavid van Moolenbroek 	"Call-Back",		/* (13) */
204*b636d99dSDavid van Moolenbroek 	"deprecated(14)",	/* used to be a Connect-Time */
205*b636d99dSDavid van Moolenbroek 	"deprecated(15)",	/* used to be a Compund-Frames */
206*b636d99dSDavid van Moolenbroek 	"deprecated(16)",	/* used to be a Nominal-Data-Encap */
207*b636d99dSDavid van Moolenbroek 	"MRRU",			/* (17) */
208*b636d99dSDavid van Moolenbroek 	"12-Bit seq #",		/* (18) */
209*b636d99dSDavid van Moolenbroek 	"End-Disc",		/* (19) */
210*b636d99dSDavid van Moolenbroek 	"Proprietary",		/* (20) */
211*b636d99dSDavid van Moolenbroek 	"DCE-Id",		/* (21) */
212*b636d99dSDavid van Moolenbroek 	"MP+",			/* (22) */
213*b636d99dSDavid van Moolenbroek 	"Link-Disc",		/* (23) */
214*b636d99dSDavid van Moolenbroek 	"LCP-Auth-Opt",		/* (24) */
215*b636d99dSDavid van Moolenbroek 	"COBS",			/* (25) */
216*b636d99dSDavid van Moolenbroek 	"Prefix-elision",	/* (26) */
217*b636d99dSDavid van Moolenbroek 	"Multilink-header-Form",/* (27) */
218*b636d99dSDavid van Moolenbroek 	"I18N",			/* (28) */
219*b636d99dSDavid van Moolenbroek 	"SDL-over-SONET/SDH",	/* (29) */
220*b636d99dSDavid van Moolenbroek 	"PPP-Muxing",		/* (30) */
221*b636d99dSDavid van Moolenbroek };
222*b636d99dSDavid van Moolenbroek 
223*b636d99dSDavid van Moolenbroek /* ECP - to be supported */
224*b636d99dSDavid van Moolenbroek 
225*b636d99dSDavid van Moolenbroek /* CCP Config Options */
226*b636d99dSDavid van Moolenbroek 
227*b636d99dSDavid van Moolenbroek #define CCPOPT_OUI	0	/* RFC1962 */
228*b636d99dSDavid van Moolenbroek #define CCPOPT_PRED1	1	/* RFC1962 */
229*b636d99dSDavid van Moolenbroek #define CCPOPT_PRED2	2	/* RFC1962 */
230*b636d99dSDavid van Moolenbroek #define CCPOPT_PJUMP	3	/* RFC1962 */
231*b636d99dSDavid van Moolenbroek /* 4-15 unassigned */
232*b636d99dSDavid van Moolenbroek #define CCPOPT_HPPPC	16	/* RFC1962 */
233*b636d99dSDavid van Moolenbroek #define CCPOPT_STACLZS	17	/* RFC1974 */
234*b636d99dSDavid van Moolenbroek #define CCPOPT_MPPC	18	/* RFC2118 */
235*b636d99dSDavid van Moolenbroek #define CCPOPT_GFZA	19	/* RFC1962 */
236*b636d99dSDavid van Moolenbroek #define CCPOPT_V42BIS	20	/* RFC1962 */
237*b636d99dSDavid van Moolenbroek #define CCPOPT_BSDCOMP	21	/* RFC1977 */
238*b636d99dSDavid van Moolenbroek /* 22 unassigned */
239*b636d99dSDavid van Moolenbroek #define CCPOPT_LZSDCP	23	/* RFC1967 */
240*b636d99dSDavid van Moolenbroek #define CCPOPT_MVRCA	24	/* RFC1975 */
241*b636d99dSDavid van Moolenbroek #define CCPOPT_DEC	25	/* RFC1976 */
242*b636d99dSDavid van Moolenbroek #define CCPOPT_DEFLATE	26	/* RFC1979 */
243*b636d99dSDavid van Moolenbroek /* 27-254 unassigned */
244*b636d99dSDavid van Moolenbroek #define CCPOPT_RESV	255	/* RFC1962 */
245*b636d99dSDavid van Moolenbroek 
246*b636d99dSDavid van Moolenbroek static const struct tok ccpconfopts_values[] = {
247*b636d99dSDavid van Moolenbroek         { CCPOPT_OUI, "OUI" },
248*b636d99dSDavid van Moolenbroek         { CCPOPT_PRED1, "Pred-1" },
249*b636d99dSDavid van Moolenbroek         { CCPOPT_PRED2, "Pred-2" },
250*b636d99dSDavid van Moolenbroek         { CCPOPT_PJUMP, "Puddle" },
251*b636d99dSDavid van Moolenbroek         { CCPOPT_HPPPC, "HP-PPC" },
252*b636d99dSDavid van Moolenbroek         { CCPOPT_STACLZS, "Stac-LZS" },
253*b636d99dSDavid van Moolenbroek         { CCPOPT_MPPC, "MPPC" },
254*b636d99dSDavid van Moolenbroek         { CCPOPT_GFZA, "Gand-FZA" },
255*b636d99dSDavid van Moolenbroek         { CCPOPT_V42BIS, "V.42bis" },
256*b636d99dSDavid van Moolenbroek         { CCPOPT_BSDCOMP, "BSD-Comp" },
257*b636d99dSDavid van Moolenbroek         { CCPOPT_LZSDCP, "LZS-DCP" },
258*b636d99dSDavid van Moolenbroek         { CCPOPT_MVRCA, "MVRCA" },
259*b636d99dSDavid van Moolenbroek         { CCPOPT_DEC, "DEC" },
260*b636d99dSDavid van Moolenbroek         { CCPOPT_DEFLATE, "Deflate" },
261*b636d99dSDavid van Moolenbroek         { CCPOPT_RESV, "Reserved"},
262*b636d99dSDavid van Moolenbroek         {0,                 NULL}
263*b636d99dSDavid van Moolenbroek };
264*b636d99dSDavid van Moolenbroek 
265*b636d99dSDavid van Moolenbroek /* BACP Config Options */
266*b636d99dSDavid van Moolenbroek 
267*b636d99dSDavid van Moolenbroek #define BACPOPT_FPEER	1	/* RFC2125 */
268*b636d99dSDavid van Moolenbroek 
269*b636d99dSDavid van Moolenbroek static const struct tok bacconfopts_values[] = {
270*b636d99dSDavid van Moolenbroek         { BACPOPT_FPEER, "Favored-Peer" },
271*b636d99dSDavid van Moolenbroek         {0,                 NULL}
272*b636d99dSDavid van Moolenbroek };
273*b636d99dSDavid van Moolenbroek 
274*b636d99dSDavid van Moolenbroek 
275*b636d99dSDavid van Moolenbroek /* SDCP - to be supported */
276*b636d99dSDavid van Moolenbroek 
277*b636d99dSDavid van Moolenbroek /* IPCP Config Options */
278*b636d99dSDavid van Moolenbroek #define IPCPOPT_2ADDR	1	/* RFC1172, RFC1332 (deprecated) */
279*b636d99dSDavid van Moolenbroek #define IPCPOPT_IPCOMP	2	/* RFC1332 */
280*b636d99dSDavid van Moolenbroek #define IPCPOPT_ADDR	3	/* RFC1332 */
281*b636d99dSDavid van Moolenbroek #define IPCPOPT_MOBILE4	4	/* RFC2290 */
282*b636d99dSDavid van Moolenbroek #define IPCPOPT_PRIDNS	129	/* RFC1877 */
283*b636d99dSDavid van Moolenbroek #define IPCPOPT_PRINBNS	130	/* RFC1877 */
284*b636d99dSDavid van Moolenbroek #define IPCPOPT_SECDNS	131	/* RFC1877 */
285*b636d99dSDavid van Moolenbroek #define IPCPOPT_SECNBNS	132	/* RFC1877 */
286*b636d99dSDavid van Moolenbroek 
287*b636d99dSDavid van Moolenbroek static const struct tok ipcpopt_values[] = {
288*b636d99dSDavid van Moolenbroek         { IPCPOPT_2ADDR, "IP-Addrs" },
289*b636d99dSDavid van Moolenbroek         { IPCPOPT_IPCOMP, "IP-Comp" },
290*b636d99dSDavid van Moolenbroek         { IPCPOPT_ADDR, "IP-Addr" },
291*b636d99dSDavid van Moolenbroek         { IPCPOPT_MOBILE4, "Home-Addr" },
292*b636d99dSDavid van Moolenbroek         { IPCPOPT_PRIDNS, "Pri-DNS" },
293*b636d99dSDavid van Moolenbroek         { IPCPOPT_PRINBNS, "Pri-NBNS" },
294*b636d99dSDavid van Moolenbroek         { IPCPOPT_SECDNS, "Sec-DNS" },
295*b636d99dSDavid van Moolenbroek         { IPCPOPT_SECNBNS, "Sec-NBNS" },
296*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
297*b636d99dSDavid van Moolenbroek };
298*b636d99dSDavid van Moolenbroek 
299*b636d99dSDavid van Moolenbroek #define IPCPOPT_IPCOMP_HDRCOMP 0x61  /* rfc3544 */
300*b636d99dSDavid van Moolenbroek #define IPCPOPT_IPCOMP_MINLEN    14
301*b636d99dSDavid van Moolenbroek 
302*b636d99dSDavid van Moolenbroek static const struct tok ipcpopt_compproto_values[] = {
303*b636d99dSDavid van Moolenbroek         { PPP_VJC, "VJ-Comp" },
304*b636d99dSDavid van Moolenbroek         { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" },
305*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
306*b636d99dSDavid van Moolenbroek };
307*b636d99dSDavid van Moolenbroek 
308*b636d99dSDavid van Moolenbroek static const struct tok ipcpopt_compproto_subopt_values[] = {
309*b636d99dSDavid van Moolenbroek         { 1, "RTP-Compression" },
310*b636d99dSDavid van Moolenbroek         { 2, "Enhanced RTP-Compression" },
311*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
312*b636d99dSDavid van Moolenbroek };
313*b636d99dSDavid van Moolenbroek 
314*b636d99dSDavid van Moolenbroek /* IP6CP Config Options */
315*b636d99dSDavid van Moolenbroek #define IP6CP_IFID      1
316*b636d99dSDavid van Moolenbroek 
317*b636d99dSDavid van Moolenbroek static const struct tok ip6cpopt_values[] = {
318*b636d99dSDavid van Moolenbroek         { IP6CP_IFID, "Interface-ID" },
319*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
320*b636d99dSDavid van Moolenbroek };
321*b636d99dSDavid van Moolenbroek 
322*b636d99dSDavid van Moolenbroek /* ATCP - to be supported */
323*b636d99dSDavid van Moolenbroek /* OSINLCP - to be supported */
324*b636d99dSDavid van Moolenbroek /* BVCP - to be supported */
325*b636d99dSDavid van Moolenbroek /* BCP - to be supported */
326*b636d99dSDavid van Moolenbroek /* IPXCP - to be supported */
327*b636d99dSDavid van Moolenbroek /* MPLSCP - to be supported */
328*b636d99dSDavid van Moolenbroek 
329*b636d99dSDavid van Moolenbroek /* Auth Algorithms */
330*b636d99dSDavid van Moolenbroek 
331*b636d99dSDavid van Moolenbroek /* 0-4 Reserved (RFC1994) */
332*b636d99dSDavid van Moolenbroek #define AUTHALG_CHAPMD5	5	/* RFC1994 */
333*b636d99dSDavid van Moolenbroek #define AUTHALG_MSCHAP1	128	/* RFC2433 */
334*b636d99dSDavid van Moolenbroek #define AUTHALG_MSCHAP2	129	/* RFC2795 */
335*b636d99dSDavid van Moolenbroek 
336*b636d99dSDavid van Moolenbroek static const struct tok authalg_values[] = {
337*b636d99dSDavid van Moolenbroek         { AUTHALG_CHAPMD5, "MD5" },
338*b636d99dSDavid van Moolenbroek         { AUTHALG_MSCHAP1, "MS-CHAPv1" },
339*b636d99dSDavid van Moolenbroek         { AUTHALG_MSCHAP2, "MS-CHAPv2" },
340*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
341*b636d99dSDavid van Moolenbroek };
342*b636d99dSDavid van Moolenbroek 
343*b636d99dSDavid van Moolenbroek /* FCS Alternatives - to be supported */
344*b636d99dSDavid van Moolenbroek 
345*b636d99dSDavid van Moolenbroek /* Multilink Endpoint Discriminator (RFC1717) */
346*b636d99dSDavid van Moolenbroek #define MEDCLASS_NULL	0	/* Null Class */
347*b636d99dSDavid van Moolenbroek #define MEDCLASS_LOCAL	1	/* Locally Assigned */
348*b636d99dSDavid van Moolenbroek #define MEDCLASS_IPV4	2	/* Internet Protocol (IPv4) */
349*b636d99dSDavid van Moolenbroek #define MEDCLASS_MAC	3	/* IEEE 802.1 global MAC address */
350*b636d99dSDavid van Moolenbroek #define MEDCLASS_MNB	4	/* PPP Magic Number Block */
351*b636d99dSDavid van Moolenbroek #define MEDCLASS_PSNDN	5	/* Public Switched Network Director Number */
352*b636d99dSDavid van Moolenbroek 
353*b636d99dSDavid van Moolenbroek /* PPP LCP Callback */
354*b636d99dSDavid van Moolenbroek #define CALLBACK_AUTH	0	/* Location determined by user auth */
355*b636d99dSDavid van Moolenbroek #define CALLBACK_DSTR	1	/* Dialing string */
356*b636d99dSDavid van Moolenbroek #define CALLBACK_LID	2	/* Location identifier */
357*b636d99dSDavid van Moolenbroek #define CALLBACK_E164	3	/* E.164 number */
358*b636d99dSDavid van Moolenbroek #define CALLBACK_X500	4	/* X.500 distinguished name */
359*b636d99dSDavid van Moolenbroek #define CALLBACK_CBCP	6	/* Location is determined during CBCP nego */
360*b636d99dSDavid van Moolenbroek 
361*b636d99dSDavid van Moolenbroek static const struct tok ppp_callback_values[] = {
362*b636d99dSDavid van Moolenbroek         { CALLBACK_AUTH, "UserAuth" },
363*b636d99dSDavid van Moolenbroek         { CALLBACK_DSTR, "DialString" },
364*b636d99dSDavid van Moolenbroek         { CALLBACK_LID, "LocalID" },
365*b636d99dSDavid van Moolenbroek         { CALLBACK_E164, "E.164" },
366*b636d99dSDavid van Moolenbroek         { CALLBACK_X500, "X.500" },
367*b636d99dSDavid van Moolenbroek         { CALLBACK_CBCP, "CBCP" },
368*b636d99dSDavid van Moolenbroek 	{ 0,		  NULL }
369*b636d99dSDavid van Moolenbroek };
370*b636d99dSDavid van Moolenbroek 
371*b636d99dSDavid van Moolenbroek /* CHAP */
372*b636d99dSDavid van Moolenbroek 
373*b636d99dSDavid van Moolenbroek #define CHAP_CHAL	1
374*b636d99dSDavid van Moolenbroek #define CHAP_RESP	2
375*b636d99dSDavid van Moolenbroek #define CHAP_SUCC	3
376*b636d99dSDavid van Moolenbroek #define CHAP_FAIL	4
377*b636d99dSDavid van Moolenbroek 
378*b636d99dSDavid van Moolenbroek static const struct tok chapcode_values[] = {
379*b636d99dSDavid van Moolenbroek 	{ CHAP_CHAL, "Challenge" },
380*b636d99dSDavid van Moolenbroek 	{ CHAP_RESP, "Response" },
381*b636d99dSDavid van Moolenbroek 	{ CHAP_SUCC, "Success" },
382*b636d99dSDavid van Moolenbroek 	{ CHAP_FAIL, "Fail" },
383*b636d99dSDavid van Moolenbroek         { 0, NULL}
384*b636d99dSDavid van Moolenbroek };
385*b636d99dSDavid van Moolenbroek 
386*b636d99dSDavid van Moolenbroek /* PAP */
387*b636d99dSDavid van Moolenbroek 
388*b636d99dSDavid van Moolenbroek #define PAP_AREQ	1
389*b636d99dSDavid van Moolenbroek #define PAP_AACK	2
390*b636d99dSDavid van Moolenbroek #define PAP_ANAK	3
391*b636d99dSDavid van Moolenbroek 
392*b636d99dSDavid van Moolenbroek static const struct tok papcode_values[] = {
393*b636d99dSDavid van Moolenbroek         { PAP_AREQ, "Auth-Req" },
394*b636d99dSDavid van Moolenbroek         { PAP_AACK, "Auth-ACK" },
395*b636d99dSDavid van Moolenbroek         { PAP_ANAK, "Auth-NACK" },
396*b636d99dSDavid van Moolenbroek         { 0, NULL }
397*b636d99dSDavid van Moolenbroek };
398*b636d99dSDavid van Moolenbroek 
399*b636d99dSDavid van Moolenbroek /* BAP */
400*b636d99dSDavid van Moolenbroek #define BAP_CALLREQ	1
401*b636d99dSDavid van Moolenbroek #define BAP_CALLRES	2
402*b636d99dSDavid van Moolenbroek #define BAP_CBREQ	3
403*b636d99dSDavid van Moolenbroek #define BAP_CBRES	4
404*b636d99dSDavid van Moolenbroek #define BAP_LDQREQ	5
405*b636d99dSDavid van Moolenbroek #define BAP_LDQRES	6
406*b636d99dSDavid van Moolenbroek #define BAP_CSIND	7
407*b636d99dSDavid van Moolenbroek #define BAP_CSRES	8
408*b636d99dSDavid van Moolenbroek 
409*b636d99dSDavid van Moolenbroek static int print_lcp_config_options(netdissect_options *, const u_char *p, int);
410*b636d99dSDavid van Moolenbroek static int print_ipcp_config_options(netdissect_options *, const u_char *p, int);
411*b636d99dSDavid van Moolenbroek static int print_ip6cp_config_options(netdissect_options *, const u_char *p, int);
412*b636d99dSDavid van Moolenbroek static int print_ccp_config_options(netdissect_options *, const u_char *p, int);
413*b636d99dSDavid van Moolenbroek static int print_bacp_config_options(netdissect_options *, const u_char *p, int);
414*b636d99dSDavid van Moolenbroek static void handle_ppp(netdissect_options *, u_int proto, const u_char *p, int length);
415*b636d99dSDavid van Moolenbroek 
416*b636d99dSDavid van Moolenbroek /* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
417*b636d99dSDavid van Moolenbroek static void
handle_ctrl_proto(netdissect_options * ndo,u_int proto,const u_char * pptr,int length)418*b636d99dSDavid van Moolenbroek handle_ctrl_proto(netdissect_options *ndo,
419*b636d99dSDavid van Moolenbroek                   u_int proto, const u_char *pptr, int length)
420*b636d99dSDavid van Moolenbroek {
421*b636d99dSDavid van Moolenbroek 	const char *typestr;
422*b636d99dSDavid van Moolenbroek 	u_int code, len;
423*b636d99dSDavid van Moolenbroek 	int (*pfunc)(netdissect_options *, const u_char *, int);
424*b636d99dSDavid van Moolenbroek 	int x, j;
425*b636d99dSDavid van Moolenbroek         const u_char *tptr;
426*b636d99dSDavid van Moolenbroek 
427*b636d99dSDavid van Moolenbroek         tptr=pptr;
428*b636d99dSDavid van Moolenbroek 
429*b636d99dSDavid van Moolenbroek         typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto);
430*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s, ", typestr));
431*b636d99dSDavid van Moolenbroek 
432*b636d99dSDavid van Moolenbroek 	if (length < 4) /* FIXME weak boundary checking */
433*b636d99dSDavid van Moolenbroek 		goto trunc;
434*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*tptr, 2);
435*b636d99dSDavid van Moolenbroek 
436*b636d99dSDavid van Moolenbroek 	code = *tptr++;
437*b636d99dSDavid van Moolenbroek 
438*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "%s (0x%02x), id %u, length %u",
439*b636d99dSDavid van Moolenbroek 	          tok2str(cpcodes, "Unknown Opcode",code),
440*b636d99dSDavid van Moolenbroek 	          code,
441*b636d99dSDavid van Moolenbroek 	          *tptr++, /* ID */
442*b636d99dSDavid van Moolenbroek 	          length + 2));
443*b636d99dSDavid van Moolenbroek 
444*b636d99dSDavid van Moolenbroek 	if (!ndo->ndo_vflag)
445*b636d99dSDavid van Moolenbroek 		return;
446*b636d99dSDavid van Moolenbroek 
447*b636d99dSDavid van Moolenbroek 	if (length <= 4)
448*b636d99dSDavid van Moolenbroek 		return;    /* there may be a NULL confreq etc. */
449*b636d99dSDavid van Moolenbroek 
450*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*tptr, 2);
451*b636d99dSDavid van Moolenbroek 	len = EXTRACT_16BITS(tptr);
452*b636d99dSDavid van Moolenbroek 	tptr += 2;
453*b636d99dSDavid van Moolenbroek 
454*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\n\tencoded length %u (=Option(s) length %u)", len, len - 4));
455*b636d99dSDavid van Moolenbroek 
456*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
457*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, pptr - 2, "\n\t", 6);
458*b636d99dSDavid van Moolenbroek 
459*b636d99dSDavid van Moolenbroek 
460*b636d99dSDavid van Moolenbroek 	switch (code) {
461*b636d99dSDavid van Moolenbroek 	case CPCODES_VEXT:
462*b636d99dSDavid van Moolenbroek 		if (length < 11)
463*b636d99dSDavid van Moolenbroek 			break;
464*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 4);
465*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  Magic-Num 0x%08x", EXTRACT_32BITS(tptr)));
466*b636d99dSDavid van Moolenbroek 		tptr += 4;
467*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 3);
468*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, " Vendor: %s (%u)",
469*b636d99dSDavid van Moolenbroek                        tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)),
470*b636d99dSDavid van Moolenbroek                        EXTRACT_24BITS(tptr)));
471*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Kind and Value(s)? */
472*b636d99dSDavid van Moolenbroek 		break;
473*b636d99dSDavid van Moolenbroek 	case CPCODES_CONF_REQ:
474*b636d99dSDavid van Moolenbroek 	case CPCODES_CONF_ACK:
475*b636d99dSDavid van Moolenbroek 	case CPCODES_CONF_NAK:
476*b636d99dSDavid van Moolenbroek 	case CPCODES_CONF_REJ:
477*b636d99dSDavid van Moolenbroek 		x = len - 4;	/* Code(1), Identifier(1) and Length(2) */
478*b636d99dSDavid van Moolenbroek 		do {
479*b636d99dSDavid van Moolenbroek 			switch (proto) {
480*b636d99dSDavid van Moolenbroek 			case PPP_LCP:
481*b636d99dSDavid van Moolenbroek 				pfunc = print_lcp_config_options;
482*b636d99dSDavid van Moolenbroek 				break;
483*b636d99dSDavid van Moolenbroek 			case PPP_IPCP:
484*b636d99dSDavid van Moolenbroek 				pfunc = print_ipcp_config_options;
485*b636d99dSDavid van Moolenbroek 				break;
486*b636d99dSDavid van Moolenbroek 			case PPP_IPV6CP:
487*b636d99dSDavid van Moolenbroek 				pfunc = print_ip6cp_config_options;
488*b636d99dSDavid van Moolenbroek 				break;
489*b636d99dSDavid van Moolenbroek 			case PPP_CCP:
490*b636d99dSDavid van Moolenbroek 				pfunc = print_ccp_config_options;
491*b636d99dSDavid van Moolenbroek 				break;
492*b636d99dSDavid van Moolenbroek 			case PPP_BACP:
493*b636d99dSDavid van Moolenbroek 				pfunc = print_bacp_config_options;
494*b636d99dSDavid van Moolenbroek 				break;
495*b636d99dSDavid van Moolenbroek 			default:
496*b636d99dSDavid van Moolenbroek 				/*
497*b636d99dSDavid van Moolenbroek 				 * No print routine for the options for
498*b636d99dSDavid van Moolenbroek 				 * this protocol.
499*b636d99dSDavid van Moolenbroek 				 */
500*b636d99dSDavid van Moolenbroek 				pfunc = NULL;
501*b636d99dSDavid van Moolenbroek 				break;
502*b636d99dSDavid van Moolenbroek 			}
503*b636d99dSDavid van Moolenbroek 
504*b636d99dSDavid van Moolenbroek 			if (pfunc == NULL) /* catch the above null pointer if unknown CP */
505*b636d99dSDavid van Moolenbroek 				break;
506*b636d99dSDavid van Moolenbroek 
507*b636d99dSDavid van Moolenbroek 			if ((j = (*pfunc)(ndo, tptr, len)) == 0)
508*b636d99dSDavid van Moolenbroek 				break;
509*b636d99dSDavid van Moolenbroek 			x -= j;
510*b636d99dSDavid van Moolenbroek 			tptr += j;
511*b636d99dSDavid van Moolenbroek 		} while (x > 0);
512*b636d99dSDavid van Moolenbroek 		break;
513*b636d99dSDavid van Moolenbroek 
514*b636d99dSDavid van Moolenbroek 	case CPCODES_TERM_REQ:
515*b636d99dSDavid van Moolenbroek 	case CPCODES_TERM_ACK:
516*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Data? */
517*b636d99dSDavid van Moolenbroek 		break;
518*b636d99dSDavid van Moolenbroek 	case CPCODES_CODE_REJ:
519*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Rejected-Packet? */
520*b636d99dSDavid van Moolenbroek 		break;
521*b636d99dSDavid van Moolenbroek 	case CPCODES_PROT_REJ:
522*b636d99dSDavid van Moolenbroek 		if (length < 6)
523*b636d99dSDavid van Moolenbroek 			break;
524*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 2);
525*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  Rejected %s Protocol (0x%04x)",
526*b636d99dSDavid van Moolenbroek 		       tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)),
527*b636d99dSDavid van Moolenbroek 		       EXTRACT_16BITS(tptr)));
528*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Rejected-Information? - hexdump for now */
529*b636d99dSDavid van Moolenbroek 		if (len > 6) {
530*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\t  Rejected Packet"));
531*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, tptr + 2, "\n\t    ", len - 2);
532*b636d99dSDavid van Moolenbroek 		}
533*b636d99dSDavid van Moolenbroek 		break;
534*b636d99dSDavid van Moolenbroek 	case CPCODES_ECHO_REQ:
535*b636d99dSDavid van Moolenbroek 	case CPCODES_ECHO_RPL:
536*b636d99dSDavid van Moolenbroek 	case CPCODES_DISC_REQ:
537*b636d99dSDavid van Moolenbroek 		if (length < 8)
538*b636d99dSDavid van Moolenbroek 			break;
539*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 4);
540*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  Magic-Num 0x%08x", EXTRACT_32BITS(tptr)));
541*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Data? - hexdump for now */
542*b636d99dSDavid van Moolenbroek 		if (len > 8) {
543*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\t  -----trailing data-----"));
544*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(tptr[4], len - 8);
545*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, tptr + 4, "\n\t  ", len - 8);
546*b636d99dSDavid van Moolenbroek 		}
547*b636d99dSDavid van Moolenbroek 		break;
548*b636d99dSDavid van Moolenbroek 	case CPCODES_ID:
549*b636d99dSDavid van Moolenbroek 		if (length < 8)
550*b636d99dSDavid van Moolenbroek 			break;
551*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 4);
552*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  Magic-Num 0x%08x", EXTRACT_32BITS(tptr)));
553*b636d99dSDavid van Moolenbroek 		/* RFC 1661 says this is intended to be human readable */
554*b636d99dSDavid van Moolenbroek 		if (len > 8) {
555*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\t  Message\n\t    "));
556*b636d99dSDavid van Moolenbroek 			if (fn_printn(ndo, tptr + 4, len - 4, ndo->ndo_snapend))
557*b636d99dSDavid van Moolenbroek 				goto trunc;
558*b636d99dSDavid van Moolenbroek 		}
559*b636d99dSDavid van Moolenbroek 		break;
560*b636d99dSDavid van Moolenbroek 	case CPCODES_TIME_REM:
561*b636d99dSDavid van Moolenbroek 		if (length < 12)
562*b636d99dSDavid van Moolenbroek 			break;
563*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*tptr, 4);
564*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  Magic-Num 0x%08x", EXTRACT_32BITS(tptr)));
565*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(tptr + 4), 4);
566*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4)));
567*b636d99dSDavid van Moolenbroek 		/* XXX: need to decode Message? */
568*b636d99dSDavid van Moolenbroek 		break;
569*b636d99dSDavid van Moolenbroek 	default:
570*b636d99dSDavid van Moolenbroek 		/* XXX this is dirty but we do not get the
571*b636d99dSDavid van Moolenbroek 		 * original pointer passed to the begin
572*b636d99dSDavid van Moolenbroek 		 * the PPP packet */
573*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag <= 1)
574*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, pptr - 2, "\n\t  ", length + 2);
575*b636d99dSDavid van Moolenbroek 		break;
576*b636d99dSDavid van Moolenbroek 	}
577*b636d99dSDavid van Moolenbroek 	return;
578*b636d99dSDavid van Moolenbroek 
579*b636d99dSDavid van Moolenbroek trunc:
580*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|%s]", typestr));
581*b636d99dSDavid van Moolenbroek }
582*b636d99dSDavid van Moolenbroek 
583*b636d99dSDavid van Moolenbroek /* LCP config options */
584*b636d99dSDavid van Moolenbroek static int
print_lcp_config_options(netdissect_options * ndo,const u_char * p,int length)585*b636d99dSDavid van Moolenbroek print_lcp_config_options(netdissect_options *ndo,
586*b636d99dSDavid van Moolenbroek                          const u_char *p, int length)
587*b636d99dSDavid van Moolenbroek {
588*b636d99dSDavid van Moolenbroek 	int len, opt;
589*b636d99dSDavid van Moolenbroek 
590*b636d99dSDavid van Moolenbroek 	if (length < 2)
591*b636d99dSDavid van Moolenbroek 		return 0;
592*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
593*b636d99dSDavid van Moolenbroek 	len = p[1];
594*b636d99dSDavid van Moolenbroek 	opt = p[0];
595*b636d99dSDavid van Moolenbroek 	if (length < len)
596*b636d99dSDavid van Moolenbroek 		return 0;
597*b636d99dSDavid van Moolenbroek 	if (len < 2) {
598*b636d99dSDavid van Moolenbroek 		if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
599*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
600*b636d99dSDavid van Moolenbroek 			          lcpconfopts[opt], opt, len));
601*b636d99dSDavid van Moolenbroek 		else
602*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt));
603*b636d99dSDavid van Moolenbroek 		return 0;
604*b636d99dSDavid van Moolenbroek 	}
605*b636d99dSDavid van Moolenbroek 	if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
606*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u", lcpconfopts[opt], opt, len));
607*b636d99dSDavid van Moolenbroek 	else {
608*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\tunknown LCP option 0x%02x", opt));
609*b636d99dSDavid van Moolenbroek 		return len;
610*b636d99dSDavid van Moolenbroek 	}
611*b636d99dSDavid van Moolenbroek 
612*b636d99dSDavid van Moolenbroek 	switch (opt) {
613*b636d99dSDavid van Moolenbroek 	case LCPOPT_VEXT:
614*b636d99dSDavid van Moolenbroek 		if (len < 6) {
615*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 6)"));
616*b636d99dSDavid van Moolenbroek 			return len;
617*b636d99dSDavid van Moolenbroek 		}
618*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 3);
619*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Vendor: %s (%u)",
620*b636d99dSDavid van Moolenbroek 			tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
621*b636d99dSDavid van Moolenbroek 			EXTRACT_24BITS(p + 2)));
622*b636d99dSDavid van Moolenbroek #if 0
623*b636d99dSDavid van Moolenbroek 		ND_TCHECK(p[5]);
624*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", kind: 0x%02x", p[5]));
625*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Value: 0x"));
626*b636d99dSDavid van Moolenbroek 		for (i = 0; i < len - 6; i++) {
627*b636d99dSDavid van Moolenbroek 			ND_TCHECK(p[6 + i]);
628*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x", p[6 + i]));
629*b636d99dSDavid van Moolenbroek 		}
630*b636d99dSDavid van Moolenbroek #endif
631*b636d99dSDavid van Moolenbroek 		break;
632*b636d99dSDavid van Moolenbroek 	case LCPOPT_MRU:
633*b636d99dSDavid van Moolenbroek 		if (len != 4) {
634*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
635*b636d99dSDavid van Moolenbroek 			return len;
636*b636d99dSDavid van Moolenbroek 		}
637*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
638*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
639*b636d99dSDavid van Moolenbroek 		break;
640*b636d99dSDavid van Moolenbroek 	case LCPOPT_ACCM:
641*b636d99dSDavid van Moolenbroek 		if (len != 6) {
642*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
643*b636d99dSDavid van Moolenbroek 			return len;
644*b636d99dSDavid van Moolenbroek 		}
645*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 4);
646*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
647*b636d99dSDavid van Moolenbroek 		break;
648*b636d99dSDavid van Moolenbroek 	case LCPOPT_AP:
649*b636d99dSDavid van Moolenbroek 		if (len < 4) {
650*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
651*b636d99dSDavid van Moolenbroek 			return len;
652*b636d99dSDavid van Moolenbroek 		}
653*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
654*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %s", tok2str(ppptype2str, "Unknown Auth Proto (0x04x)", EXTRACT_16BITS(p + 2))));
655*b636d99dSDavid van Moolenbroek 
656*b636d99dSDavid van Moolenbroek 		switch (EXTRACT_16BITS(p+2)) {
657*b636d99dSDavid van Moolenbroek 		case PPP_CHAP:
658*b636d99dSDavid van Moolenbroek 			ND_TCHECK(p[4]);
659*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ", %s", tok2str(authalg_values, "Unknown Auth Alg %u", p[4])));
660*b636d99dSDavid van Moolenbroek 			break;
661*b636d99dSDavid van Moolenbroek 		case PPP_PAP: /* fall through */
662*b636d99dSDavid van Moolenbroek 		case PPP_EAP:
663*b636d99dSDavid van Moolenbroek 		case PPP_SPAP:
664*b636d99dSDavid van Moolenbroek 		case PPP_SPAP_OLD:
665*b636d99dSDavid van Moolenbroek                         break;
666*b636d99dSDavid van Moolenbroek 		default:
667*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, p, "\n\t", len);
668*b636d99dSDavid van Moolenbroek 		}
669*b636d99dSDavid van Moolenbroek 		break;
670*b636d99dSDavid van Moolenbroek 	case LCPOPT_QP:
671*b636d99dSDavid van Moolenbroek 		if (len < 4) {
672*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
673*b636d99dSDavid van Moolenbroek 			return 0;
674*b636d99dSDavid van Moolenbroek 		}
675*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
676*b636d99dSDavid van Moolenbroek 		if (EXTRACT_16BITS(p+2) == PPP_LQM)
677*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": LQR"));
678*b636d99dSDavid van Moolenbroek 		else
679*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": unknown"));
680*b636d99dSDavid van Moolenbroek 		break;
681*b636d99dSDavid van Moolenbroek 	case LCPOPT_MN:
682*b636d99dSDavid van Moolenbroek 		if (len != 6) {
683*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
684*b636d99dSDavid van Moolenbroek 			return 0;
685*b636d99dSDavid van Moolenbroek 		}
686*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 4);
687*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": 0x%08x", EXTRACT_32BITS(p + 2)));
688*b636d99dSDavid van Moolenbroek 		break;
689*b636d99dSDavid van Moolenbroek 	case LCPOPT_PFC:
690*b636d99dSDavid van Moolenbroek 		break;
691*b636d99dSDavid van Moolenbroek 	case LCPOPT_ACFC:
692*b636d99dSDavid van Moolenbroek 		break;
693*b636d99dSDavid van Moolenbroek 	case LCPOPT_LD:
694*b636d99dSDavid van Moolenbroek 		if (len != 4) {
695*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
696*b636d99dSDavid van Moolenbroek 			return 0;
697*b636d99dSDavid van Moolenbroek 		}
698*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
699*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": 0x%04x", EXTRACT_16BITS(p + 2)));
700*b636d99dSDavid van Moolenbroek 		break;
701*b636d99dSDavid van Moolenbroek 	case LCPOPT_CBACK:
702*b636d99dSDavid van Moolenbroek 		if (len < 3) {
703*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
704*b636d99dSDavid van Moolenbroek 			return 0;
705*b636d99dSDavid van Moolenbroek 		}
706*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": "));
707*b636d99dSDavid van Moolenbroek 		ND_TCHECK(p[2]);
708*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Callback Operation %s (%u)",
709*b636d99dSDavid van Moolenbroek                        tok2str(ppp_callback_values, "Unknown", p[2]),
710*b636d99dSDavid van Moolenbroek                        p[2]));
711*b636d99dSDavid van Moolenbroek 		break;
712*b636d99dSDavid van Moolenbroek 	case LCPOPT_MLMRRU:
713*b636d99dSDavid van Moolenbroek 		if (len != 4) {
714*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 4)"));
715*b636d99dSDavid van Moolenbroek 			return 0;
716*b636d99dSDavid van Moolenbroek 		}
717*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
718*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %u", EXTRACT_16BITS(p + 2)));
719*b636d99dSDavid van Moolenbroek 		break;
720*b636d99dSDavid van Moolenbroek 	case LCPOPT_MLED:
721*b636d99dSDavid van Moolenbroek 		if (len < 3) {
722*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
723*b636d99dSDavid van Moolenbroek 			return 0;
724*b636d99dSDavid van Moolenbroek 		}
725*b636d99dSDavid van Moolenbroek 		ND_TCHECK(p[2]);
726*b636d99dSDavid van Moolenbroek 		switch (p[2]) {		/* class */
727*b636d99dSDavid van Moolenbroek 		case MEDCLASS_NULL:
728*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": Null"));
729*b636d99dSDavid van Moolenbroek 			break;
730*b636d99dSDavid van Moolenbroek 		case MEDCLASS_LOCAL:
731*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": Local")); /* XXX */
732*b636d99dSDavid van Moolenbroek 			break;
733*b636d99dSDavid van Moolenbroek 		case MEDCLASS_IPV4:
734*b636d99dSDavid van Moolenbroek 			if (len != 7) {
735*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " (length bogus, should be = 7)"));
736*b636d99dSDavid van Moolenbroek 				return 0;
737*b636d99dSDavid van Moolenbroek 			}
738*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(*(p + 3), 4);
739*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": IPv4 %s", ipaddr_string(ndo, p + 3)));
740*b636d99dSDavid van Moolenbroek 			break;
741*b636d99dSDavid van Moolenbroek 		case MEDCLASS_MAC:
742*b636d99dSDavid van Moolenbroek 			if (len != 9) {
743*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, " (length bogus, should be = 9)"));
744*b636d99dSDavid van Moolenbroek 				return 0;
745*b636d99dSDavid van Moolenbroek 			}
746*b636d99dSDavid van Moolenbroek 			ND_TCHECK2(*(p + 3), 6);
747*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": MAC %s", etheraddr_string(ndo, p + 3)));
748*b636d99dSDavid van Moolenbroek 			break;
749*b636d99dSDavid van Moolenbroek 		case MEDCLASS_MNB:
750*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": Magic-Num-Block")); /* XXX */
751*b636d99dSDavid van Moolenbroek 			break;
752*b636d99dSDavid van Moolenbroek 		case MEDCLASS_PSNDN:
753*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": PSNDN")); /* XXX */
754*b636d99dSDavid van Moolenbroek 			break;
755*b636d99dSDavid van Moolenbroek 		default:
756*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, ": Unknown class %u", p[2]));
757*b636d99dSDavid van Moolenbroek 			break;
758*b636d99dSDavid van Moolenbroek 		}
759*b636d99dSDavid van Moolenbroek 		break;
760*b636d99dSDavid van Moolenbroek 
761*b636d99dSDavid van Moolenbroek /* XXX: to be supported */
762*b636d99dSDavid van Moolenbroek #if 0
763*b636d99dSDavid van Moolenbroek 	case LCPOPT_DEP6:
764*b636d99dSDavid van Moolenbroek 	case LCPOPT_FCSALT:
765*b636d99dSDavid van Moolenbroek 	case LCPOPT_SDP:
766*b636d99dSDavid van Moolenbroek 	case LCPOPT_NUMMODE:
767*b636d99dSDavid van Moolenbroek 	case LCPOPT_DEP12:
768*b636d99dSDavid van Moolenbroek 	case LCPOPT_DEP14:
769*b636d99dSDavid van Moolenbroek 	case LCPOPT_DEP15:
770*b636d99dSDavid van Moolenbroek 	case LCPOPT_DEP16:
771*b636d99dSDavid van Moolenbroek         case LCPOPT_MLSSNHF:
772*b636d99dSDavid van Moolenbroek 	case LCPOPT_PROP:
773*b636d99dSDavid van Moolenbroek 	case LCPOPT_DCEID:
774*b636d99dSDavid van Moolenbroek 	case LCPOPT_MPP:
775*b636d99dSDavid van Moolenbroek 	case LCPOPT_LCPAOPT:
776*b636d99dSDavid van Moolenbroek 	case LCPOPT_COBS:
777*b636d99dSDavid van Moolenbroek 	case LCPOPT_PE:
778*b636d99dSDavid van Moolenbroek 	case LCPOPT_MLHF:
779*b636d99dSDavid van Moolenbroek 	case LCPOPT_I18N:
780*b636d99dSDavid van Moolenbroek 	case LCPOPT_SDLOS:
781*b636d99dSDavid van Moolenbroek 	case LCPOPT_PPPMUX:
782*b636d99dSDavid van Moolenbroek 		break;
783*b636d99dSDavid van Moolenbroek #endif
784*b636d99dSDavid van Moolenbroek 	default:
785*b636d99dSDavid van Moolenbroek 		/*
786*b636d99dSDavid van Moolenbroek 		 * Unknown option; dump it as raw bytes now if we're
787*b636d99dSDavid van Moolenbroek 		 * not going to do so below.
788*b636d99dSDavid van Moolenbroek 		 */
789*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag < 2)
790*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
791*b636d99dSDavid van Moolenbroek 		break;
792*b636d99dSDavid van Moolenbroek 	}
793*b636d99dSDavid van Moolenbroek 
794*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
795*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
796*b636d99dSDavid van Moolenbroek 
797*b636d99dSDavid van Moolenbroek 	return len;
798*b636d99dSDavid van Moolenbroek 
799*b636d99dSDavid van Moolenbroek trunc:
800*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|lcp]"));
801*b636d99dSDavid van Moolenbroek 	return 0;
802*b636d99dSDavid van Moolenbroek }
803*b636d99dSDavid van Moolenbroek 
804*b636d99dSDavid van Moolenbroek /* ML-PPP*/
805*b636d99dSDavid van Moolenbroek static const struct tok ppp_ml_flag_values[] = {
806*b636d99dSDavid van Moolenbroek     { 0x80, "begin" },
807*b636d99dSDavid van Moolenbroek     { 0x40, "end" },
808*b636d99dSDavid van Moolenbroek     { 0, NULL }
809*b636d99dSDavid van Moolenbroek };
810*b636d99dSDavid van Moolenbroek 
811*b636d99dSDavid van Moolenbroek static void
handle_mlppp(netdissect_options * ndo,const u_char * p,int length)812*b636d99dSDavid van Moolenbroek handle_mlppp(netdissect_options *ndo,
813*b636d99dSDavid van Moolenbroek              const u_char *p, int length)
814*b636d99dSDavid van Moolenbroek {
815*b636d99dSDavid van Moolenbroek     if (!ndo->ndo_eflag)
816*b636d99dSDavid van Moolenbroek         ND_PRINT((ndo, "MLPPP, "));
817*b636d99dSDavid van Moolenbroek 
818*b636d99dSDavid van Moolenbroek     ND_PRINT((ndo, "seq 0x%03x, Flags [%s], length %u",
819*b636d99dSDavid van Moolenbroek            (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
820*b636d99dSDavid van Moolenbroek            bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
821*b636d99dSDavid van Moolenbroek            length));
822*b636d99dSDavid van Moolenbroek }
823*b636d99dSDavid van Moolenbroek 
824*b636d99dSDavid van Moolenbroek /* CHAP */
825*b636d99dSDavid van Moolenbroek static void
handle_chap(netdissect_options * ndo,const u_char * p,int length)826*b636d99dSDavid van Moolenbroek handle_chap(netdissect_options *ndo,
827*b636d99dSDavid van Moolenbroek             const u_char *p, int length)
828*b636d99dSDavid van Moolenbroek {
829*b636d99dSDavid van Moolenbroek 	u_int code, len;
830*b636d99dSDavid van Moolenbroek 	int val_size, name_size, msg_size;
831*b636d99dSDavid van Moolenbroek 	const u_char *p0;
832*b636d99dSDavid van Moolenbroek 	int i;
833*b636d99dSDavid van Moolenbroek 
834*b636d99dSDavid van Moolenbroek 	p0 = p;
835*b636d99dSDavid van Moolenbroek 	if (length < 1) {
836*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|chap]"));
837*b636d99dSDavid van Moolenbroek 		return;
838*b636d99dSDavid van Moolenbroek 	} else if (length < 4) {
839*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
840*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|chap 0x%02x]", *p));
841*b636d99dSDavid van Moolenbroek 		return;
842*b636d99dSDavid van Moolenbroek 	}
843*b636d99dSDavid van Moolenbroek 
844*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*p);
845*b636d99dSDavid van Moolenbroek 	code = *p;
846*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "CHAP, %s (0x%02x)",
847*b636d99dSDavid van Moolenbroek                tok2str(chapcode_values,"unknown",code),
848*b636d99dSDavid van Moolenbroek                code));
849*b636d99dSDavid van Moolenbroek 	p++;
850*b636d99dSDavid van Moolenbroek 
851*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*p);
852*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, ", id %u", *p));		/* ID */
853*b636d99dSDavid van Moolenbroek 	p++;
854*b636d99dSDavid van Moolenbroek 
855*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
856*b636d99dSDavid van Moolenbroek 	len = EXTRACT_16BITS(p);
857*b636d99dSDavid van Moolenbroek 	p += 2;
858*b636d99dSDavid van Moolenbroek 
859*b636d99dSDavid van Moolenbroek 	/*
860*b636d99dSDavid van Moolenbroek 	 * Note that this is a generic CHAP decoding routine. Since we
861*b636d99dSDavid van Moolenbroek 	 * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
862*b636d99dSDavid van Moolenbroek 	 * MS-CHAPv2) is used at this point, we can't decode packet
863*b636d99dSDavid van Moolenbroek 	 * specifically to each algorithms. Instead, we simply decode
864*b636d99dSDavid van Moolenbroek 	 * the GCD (Gratest Common Denominator) for all algorithms.
865*b636d99dSDavid van Moolenbroek 	 */
866*b636d99dSDavid van Moolenbroek 	switch (code) {
867*b636d99dSDavid van Moolenbroek 	case CHAP_CHAL:
868*b636d99dSDavid van Moolenbroek 	case CHAP_RESP:
869*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < 1)
870*b636d99dSDavid van Moolenbroek 			return;
871*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
872*b636d99dSDavid van Moolenbroek 		val_size = *p;		/* value size */
873*b636d99dSDavid van Moolenbroek 		p++;
874*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < val_size)
875*b636d99dSDavid van Moolenbroek 			return;
876*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Value "));
877*b636d99dSDavid van Moolenbroek 		for (i = 0; i < val_size; i++) {
878*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
879*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x", *p++));
880*b636d99dSDavid van Moolenbroek 		}
881*b636d99dSDavid van Moolenbroek 		name_size = len - (p - p0);
882*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Name "));
883*b636d99dSDavid van Moolenbroek 		for (i = 0; i < name_size; i++) {
884*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
885*b636d99dSDavid van Moolenbroek 			safeputchar(ndo, *p++);
886*b636d99dSDavid van Moolenbroek 		}
887*b636d99dSDavid van Moolenbroek 		break;
888*b636d99dSDavid van Moolenbroek 	case CHAP_SUCC:
889*b636d99dSDavid van Moolenbroek 	case CHAP_FAIL:
890*b636d99dSDavid van Moolenbroek 		msg_size = len - (p - p0);
891*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Msg "));
892*b636d99dSDavid van Moolenbroek 		for (i = 0; i< msg_size; i++) {
893*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
894*b636d99dSDavid van Moolenbroek 			safeputchar(ndo, *p++);
895*b636d99dSDavid van Moolenbroek 		}
896*b636d99dSDavid van Moolenbroek 		break;
897*b636d99dSDavid van Moolenbroek 	}
898*b636d99dSDavid van Moolenbroek 	return;
899*b636d99dSDavid van Moolenbroek 
900*b636d99dSDavid van Moolenbroek trunc:
901*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|chap]"));
902*b636d99dSDavid van Moolenbroek }
903*b636d99dSDavid van Moolenbroek 
904*b636d99dSDavid van Moolenbroek /* PAP (see RFC 1334) */
905*b636d99dSDavid van Moolenbroek static void
handle_pap(netdissect_options * ndo,const u_char * p,int length)906*b636d99dSDavid van Moolenbroek handle_pap(netdissect_options *ndo,
907*b636d99dSDavid van Moolenbroek            const u_char *p, int length)
908*b636d99dSDavid van Moolenbroek {
909*b636d99dSDavid van Moolenbroek 	u_int code, len;
910*b636d99dSDavid van Moolenbroek 	int peerid_len, passwd_len, msg_len;
911*b636d99dSDavid van Moolenbroek 	const u_char *p0;
912*b636d99dSDavid van Moolenbroek 	int i;
913*b636d99dSDavid van Moolenbroek 
914*b636d99dSDavid van Moolenbroek 	p0 = p;
915*b636d99dSDavid van Moolenbroek 	if (length < 1) {
916*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|pap]"));
917*b636d99dSDavid van Moolenbroek 		return;
918*b636d99dSDavid van Moolenbroek 	} else if (length < 4) {
919*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
920*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|pap 0x%02x]", *p));
921*b636d99dSDavid van Moolenbroek 		return;
922*b636d99dSDavid van Moolenbroek 	}
923*b636d99dSDavid van Moolenbroek 
924*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*p);
925*b636d99dSDavid van Moolenbroek 	code = *p;
926*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "PAP, %s (0x%02x)",
927*b636d99dSDavid van Moolenbroek 	          tok2str(papcode_values, "unknown", code),
928*b636d99dSDavid van Moolenbroek 	          code));
929*b636d99dSDavid van Moolenbroek 	p++;
930*b636d99dSDavid van Moolenbroek 
931*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*p);
932*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, ", id %u", *p));		/* ID */
933*b636d99dSDavid van Moolenbroek 	p++;
934*b636d99dSDavid van Moolenbroek 
935*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
936*b636d99dSDavid van Moolenbroek 	len = EXTRACT_16BITS(p);
937*b636d99dSDavid van Moolenbroek 	p += 2;
938*b636d99dSDavid van Moolenbroek 
939*b636d99dSDavid van Moolenbroek 	if ((int)len > length) {
940*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", length %u > packet size", len));
941*b636d99dSDavid van Moolenbroek 		return;
942*b636d99dSDavid van Moolenbroek 	}
943*b636d99dSDavid van Moolenbroek 	length = len;
944*b636d99dSDavid van Moolenbroek 	if (length < (p - p0)) {
945*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", length %u < PAP header length", length));
946*b636d99dSDavid van Moolenbroek 		return;
947*b636d99dSDavid van Moolenbroek 	}
948*b636d99dSDavid van Moolenbroek 
949*b636d99dSDavid van Moolenbroek 	switch (code) {
950*b636d99dSDavid van Moolenbroek 	case PAP_AREQ:
951*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < 1)
952*b636d99dSDavid van Moolenbroek 			return;
953*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
954*b636d99dSDavid van Moolenbroek 		peerid_len = *p;	/* Peer-ID Length */
955*b636d99dSDavid van Moolenbroek 		p++;
956*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < peerid_len)
957*b636d99dSDavid van Moolenbroek 			return;
958*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Peer "));
959*b636d99dSDavid van Moolenbroek 		for (i = 0; i < peerid_len; i++) {
960*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
961*b636d99dSDavid van Moolenbroek 			safeputchar(ndo, *p++);
962*b636d99dSDavid van Moolenbroek 		}
963*b636d99dSDavid van Moolenbroek 
964*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < 1)
965*b636d99dSDavid van Moolenbroek 			return;
966*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
967*b636d99dSDavid van Moolenbroek 		passwd_len = *p;	/* Password Length */
968*b636d99dSDavid van Moolenbroek 		p++;
969*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < passwd_len)
970*b636d99dSDavid van Moolenbroek 			return;
971*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Name "));
972*b636d99dSDavid van Moolenbroek 		for (i = 0; i < passwd_len; i++) {
973*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
974*b636d99dSDavid van Moolenbroek 			safeputchar(ndo, *p++);
975*b636d99dSDavid van Moolenbroek 		}
976*b636d99dSDavid van Moolenbroek 		break;
977*b636d99dSDavid van Moolenbroek 	case PAP_AACK:
978*b636d99dSDavid van Moolenbroek 	case PAP_ANAK:
979*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < 1)
980*b636d99dSDavid van Moolenbroek 			return;
981*b636d99dSDavid van Moolenbroek 		ND_TCHECK(*p);
982*b636d99dSDavid van Moolenbroek 		msg_len = *p;		/* Msg-Length */
983*b636d99dSDavid van Moolenbroek 		p++;
984*b636d99dSDavid van Moolenbroek 		if (length - (p - p0) < msg_len)
985*b636d99dSDavid van Moolenbroek 			return;
986*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ", Msg "));
987*b636d99dSDavid van Moolenbroek 		for (i = 0; i< msg_len; i++) {
988*b636d99dSDavid van Moolenbroek 			ND_TCHECK(*p);
989*b636d99dSDavid van Moolenbroek 			safeputchar(ndo, *p++);
990*b636d99dSDavid van Moolenbroek 		}
991*b636d99dSDavid van Moolenbroek 		break;
992*b636d99dSDavid van Moolenbroek 	}
993*b636d99dSDavid van Moolenbroek 	return;
994*b636d99dSDavid van Moolenbroek 
995*b636d99dSDavid van Moolenbroek trunc:
996*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|pap]"));
997*b636d99dSDavid van Moolenbroek }
998*b636d99dSDavid van Moolenbroek 
999*b636d99dSDavid van Moolenbroek /* BAP */
1000*b636d99dSDavid van Moolenbroek static void
handle_bap(netdissect_options * ndo _U_,const u_char * p _U_,int length _U_)1001*b636d99dSDavid van Moolenbroek handle_bap(netdissect_options *ndo _U_,
1002*b636d99dSDavid van Moolenbroek            const u_char *p _U_, int length _U_)
1003*b636d99dSDavid van Moolenbroek {
1004*b636d99dSDavid van Moolenbroek 	/* XXX: to be supported!! */
1005*b636d99dSDavid van Moolenbroek }
1006*b636d99dSDavid van Moolenbroek 
1007*b636d99dSDavid van Moolenbroek 
1008*b636d99dSDavid van Moolenbroek /* IPCP config options */
1009*b636d99dSDavid van Moolenbroek static int
print_ipcp_config_options(netdissect_options * ndo,const u_char * p,int length)1010*b636d99dSDavid van Moolenbroek print_ipcp_config_options(netdissect_options *ndo,
1011*b636d99dSDavid van Moolenbroek                           const u_char *p, int length)
1012*b636d99dSDavid van Moolenbroek {
1013*b636d99dSDavid van Moolenbroek 	int len, opt;
1014*b636d99dSDavid van Moolenbroek         u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen;
1015*b636d99dSDavid van Moolenbroek 
1016*b636d99dSDavid van Moolenbroek 	if (length < 2)
1017*b636d99dSDavid van Moolenbroek 		return 0;
1018*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
1019*b636d99dSDavid van Moolenbroek 	len = p[1];
1020*b636d99dSDavid van Moolenbroek 	opt = p[0];
1021*b636d99dSDavid van Moolenbroek 	if (length < len)
1022*b636d99dSDavid van Moolenbroek 		return 0;
1023*b636d99dSDavid van Moolenbroek 	if (len < 2) {
1024*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
1025*b636d99dSDavid van Moolenbroek 		       tok2str(ipcpopt_values,"unknown",opt),
1026*b636d99dSDavid van Moolenbroek 		       opt,
1027*b636d99dSDavid van Moolenbroek 		       len));
1028*b636d99dSDavid van Moolenbroek 		return 0;
1029*b636d99dSDavid van Moolenbroek 	}
1030*b636d99dSDavid van Moolenbroek 
1031*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u",
1032*b636d99dSDavid van Moolenbroek 	       tok2str(ipcpopt_values,"unknown",opt),
1033*b636d99dSDavid van Moolenbroek 	       opt,
1034*b636d99dSDavid van Moolenbroek 	       len));
1035*b636d99dSDavid van Moolenbroek 
1036*b636d99dSDavid van Moolenbroek 	switch (opt) {
1037*b636d99dSDavid van Moolenbroek 	case IPCPOPT_2ADDR:		/* deprecated */
1038*b636d99dSDavid van Moolenbroek 		if (len != 10) {
1039*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 10)"));
1040*b636d99dSDavid van Moolenbroek 			return len;
1041*b636d99dSDavid van Moolenbroek 		}
1042*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 6), 4);
1043*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": src %s, dst %s",
1044*b636d99dSDavid van Moolenbroek 		       ipaddr_string(ndo, p + 2),
1045*b636d99dSDavid van Moolenbroek 		       ipaddr_string(ndo, p + 6)));
1046*b636d99dSDavid van Moolenbroek 		break;
1047*b636d99dSDavid van Moolenbroek 	case IPCPOPT_IPCOMP:
1048*b636d99dSDavid van Moolenbroek 		if (len < 4) {
1049*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
1050*b636d99dSDavid van Moolenbroek 			return 0;
1051*b636d99dSDavid van Moolenbroek 		}
1052*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 2);
1053*b636d99dSDavid van Moolenbroek 		compproto = EXTRACT_16BITS(p+2);
1054*b636d99dSDavid van Moolenbroek 
1055*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %s (0x%02x):",
1056*b636d99dSDavid van Moolenbroek 		          tok2str(ipcpopt_compproto_values, "Unknown", compproto),
1057*b636d99dSDavid van Moolenbroek 		          compproto));
1058*b636d99dSDavid van Moolenbroek 
1059*b636d99dSDavid van Moolenbroek 		switch (compproto) {
1060*b636d99dSDavid van Moolenbroek                 case PPP_VJC:
1061*b636d99dSDavid van Moolenbroek 			/* XXX: VJ-Comp parameters should be decoded */
1062*b636d99dSDavid van Moolenbroek                         break;
1063*b636d99dSDavid van Moolenbroek                 case IPCPOPT_IPCOMP_HDRCOMP:
1064*b636d99dSDavid van Moolenbroek                         if (len < IPCPOPT_IPCOMP_MINLEN) {
1065*b636d99dSDavid van Moolenbroek                         	ND_PRINT((ndo, " (length bogus, should be >= %u)",
1066*b636d99dSDavid van Moolenbroek                         		IPCPOPT_IPCOMP_MINLEN));
1067*b636d99dSDavid van Moolenbroek                         	return 0;
1068*b636d99dSDavid van Moolenbroek                         }
1069*b636d99dSDavid van Moolenbroek 
1070*b636d99dSDavid van Moolenbroek                         ND_TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN);
1071*b636d99dSDavid van Moolenbroek                         ND_PRINT((ndo, "\n\t    TCP Space %u, non-TCP Space %u" \
1072*b636d99dSDavid van Moolenbroek                                ", maxPeriod %u, maxTime %u, maxHdr %u",
1073*b636d99dSDavid van Moolenbroek                                EXTRACT_16BITS(p+4),
1074*b636d99dSDavid van Moolenbroek                                EXTRACT_16BITS(p+6),
1075*b636d99dSDavid van Moolenbroek                                EXTRACT_16BITS(p+8),
1076*b636d99dSDavid van Moolenbroek                                EXTRACT_16BITS(p+10),
1077*b636d99dSDavid van Moolenbroek                                EXTRACT_16BITS(p+12)));
1078*b636d99dSDavid van Moolenbroek 
1079*b636d99dSDavid van Moolenbroek                         /* suboptions present ? */
1080*b636d99dSDavid van Moolenbroek                         if (len > IPCPOPT_IPCOMP_MINLEN) {
1081*b636d99dSDavid van Moolenbroek                                 ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN;
1082*b636d99dSDavid van Moolenbroek                                 p += IPCPOPT_IPCOMP_MINLEN;
1083*b636d99dSDavid van Moolenbroek 
1084*b636d99dSDavid van Moolenbroek                                 ND_PRINT((ndo, "\n\t      Suboptions, length %u", ipcomp_subopttotallen));
1085*b636d99dSDavid van Moolenbroek 
1086*b636d99dSDavid van Moolenbroek                                 while (ipcomp_subopttotallen >= 2) {
1087*b636d99dSDavid van Moolenbroek                                         ND_TCHECK2(*p, 2);
1088*b636d99dSDavid van Moolenbroek                                         ipcomp_subopt = *p;
1089*b636d99dSDavid van Moolenbroek                                         ipcomp_suboptlen = *(p+1);
1090*b636d99dSDavid van Moolenbroek 
1091*b636d99dSDavid van Moolenbroek                                         /* sanity check */
1092*b636d99dSDavid van Moolenbroek                                         if (ipcomp_subopt == 0 ||
1093*b636d99dSDavid van Moolenbroek                                             ipcomp_suboptlen == 0 )
1094*b636d99dSDavid van Moolenbroek                                                 break;
1095*b636d99dSDavid van Moolenbroek 
1096*b636d99dSDavid van Moolenbroek                                         /* XXX: just display the suboptions for now */
1097*b636d99dSDavid van Moolenbroek                                         ND_PRINT((ndo, "\n\t\t%s Suboption #%u, length %u",
1098*b636d99dSDavid van Moolenbroek                                                tok2str(ipcpopt_compproto_subopt_values,
1099*b636d99dSDavid van Moolenbroek                                                        "Unknown",
1100*b636d99dSDavid van Moolenbroek                                                        ipcomp_subopt),
1101*b636d99dSDavid van Moolenbroek                                                ipcomp_subopt,
1102*b636d99dSDavid van Moolenbroek                                                ipcomp_suboptlen));
1103*b636d99dSDavid van Moolenbroek 
1104*b636d99dSDavid van Moolenbroek                                         ipcomp_subopttotallen -= ipcomp_suboptlen;
1105*b636d99dSDavid van Moolenbroek                                         p += ipcomp_suboptlen;
1106*b636d99dSDavid van Moolenbroek                                 }
1107*b636d99dSDavid van Moolenbroek                         }
1108*b636d99dSDavid van Moolenbroek                         break;
1109*b636d99dSDavid van Moolenbroek                 default:
1110*b636d99dSDavid van Moolenbroek                         break;
1111*b636d99dSDavid van Moolenbroek 		}
1112*b636d99dSDavid van Moolenbroek 		break;
1113*b636d99dSDavid van Moolenbroek 
1114*b636d99dSDavid van Moolenbroek 	case IPCPOPT_ADDR:     /* those options share the same format - fall through */
1115*b636d99dSDavid van Moolenbroek 	case IPCPOPT_MOBILE4:
1116*b636d99dSDavid van Moolenbroek 	case IPCPOPT_PRIDNS:
1117*b636d99dSDavid van Moolenbroek 	case IPCPOPT_PRINBNS:
1118*b636d99dSDavid van Moolenbroek 	case IPCPOPT_SECDNS:
1119*b636d99dSDavid van Moolenbroek 	case IPCPOPT_SECNBNS:
1120*b636d99dSDavid van Moolenbroek 		if (len != 6) {
1121*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
1122*b636d99dSDavid van Moolenbroek 			return 0;
1123*b636d99dSDavid van Moolenbroek 		}
1124*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 4);
1125*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %s", ipaddr_string(ndo, p + 2)));
1126*b636d99dSDavid van Moolenbroek 		break;
1127*b636d99dSDavid van Moolenbroek 	default:
1128*b636d99dSDavid van Moolenbroek 		/*
1129*b636d99dSDavid van Moolenbroek 		 * Unknown option; dump it as raw bytes now if we're
1130*b636d99dSDavid van Moolenbroek 		 * not going to do so below.
1131*b636d99dSDavid van Moolenbroek 		 */
1132*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag < 2)
1133*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
1134*b636d99dSDavid van Moolenbroek 		break;
1135*b636d99dSDavid van Moolenbroek 	}
1136*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
1137*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
1138*b636d99dSDavid van Moolenbroek 	return len;
1139*b636d99dSDavid van Moolenbroek 
1140*b636d99dSDavid van Moolenbroek trunc:
1141*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|ipcp]"));
1142*b636d99dSDavid van Moolenbroek 	return 0;
1143*b636d99dSDavid van Moolenbroek }
1144*b636d99dSDavid van Moolenbroek 
1145*b636d99dSDavid van Moolenbroek /* IP6CP config options */
1146*b636d99dSDavid van Moolenbroek static int
print_ip6cp_config_options(netdissect_options * ndo,const u_char * p,int length)1147*b636d99dSDavid van Moolenbroek print_ip6cp_config_options(netdissect_options *ndo,
1148*b636d99dSDavid van Moolenbroek                            const u_char *p, int length)
1149*b636d99dSDavid van Moolenbroek {
1150*b636d99dSDavid van Moolenbroek 	int len, opt;
1151*b636d99dSDavid van Moolenbroek 
1152*b636d99dSDavid van Moolenbroek 	if (length < 2)
1153*b636d99dSDavid van Moolenbroek 		return 0;
1154*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
1155*b636d99dSDavid van Moolenbroek 	len = p[1];
1156*b636d99dSDavid van Moolenbroek 	opt = p[0];
1157*b636d99dSDavid van Moolenbroek 	if (length < len)
1158*b636d99dSDavid van Moolenbroek 		return 0;
1159*b636d99dSDavid van Moolenbroek 	if (len < 2) {
1160*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
1161*b636d99dSDavid van Moolenbroek 		       tok2str(ip6cpopt_values,"unknown",opt),
1162*b636d99dSDavid van Moolenbroek 		       opt,
1163*b636d99dSDavid van Moolenbroek 		       len));
1164*b636d99dSDavid van Moolenbroek 		return 0;
1165*b636d99dSDavid van Moolenbroek 	}
1166*b636d99dSDavid van Moolenbroek 
1167*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u",
1168*b636d99dSDavid van Moolenbroek 	       tok2str(ip6cpopt_values,"unknown",opt),
1169*b636d99dSDavid van Moolenbroek 	       opt,
1170*b636d99dSDavid van Moolenbroek 	       len));
1171*b636d99dSDavid van Moolenbroek 
1172*b636d99dSDavid van Moolenbroek 	switch (opt) {
1173*b636d99dSDavid van Moolenbroek 	case IP6CP_IFID:
1174*b636d99dSDavid van Moolenbroek 		if (len != 10) {
1175*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 10)"));
1176*b636d99dSDavid van Moolenbroek 			return len;
1177*b636d99dSDavid van Moolenbroek 		}
1178*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 8);
1179*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": %04x:%04x:%04x:%04x",
1180*b636d99dSDavid van Moolenbroek 		       EXTRACT_16BITS(p + 2),
1181*b636d99dSDavid van Moolenbroek 		       EXTRACT_16BITS(p + 4),
1182*b636d99dSDavid van Moolenbroek 		       EXTRACT_16BITS(p + 6),
1183*b636d99dSDavid van Moolenbroek 		       EXTRACT_16BITS(p + 8)));
1184*b636d99dSDavid van Moolenbroek 		break;
1185*b636d99dSDavid van Moolenbroek 	default:
1186*b636d99dSDavid van Moolenbroek 		/*
1187*b636d99dSDavid van Moolenbroek 		 * Unknown option; dump it as raw bytes now if we're
1188*b636d99dSDavid van Moolenbroek 		 * not going to do so below.
1189*b636d99dSDavid van Moolenbroek 		 */
1190*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag < 2)
1191*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
1192*b636d99dSDavid van Moolenbroek 		break;
1193*b636d99dSDavid van Moolenbroek 	}
1194*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
1195*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
1196*b636d99dSDavid van Moolenbroek 
1197*b636d99dSDavid van Moolenbroek 	return len;
1198*b636d99dSDavid van Moolenbroek 
1199*b636d99dSDavid van Moolenbroek trunc:
1200*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|ip6cp]"));
1201*b636d99dSDavid van Moolenbroek 	return 0;
1202*b636d99dSDavid van Moolenbroek }
1203*b636d99dSDavid van Moolenbroek 
1204*b636d99dSDavid van Moolenbroek 
1205*b636d99dSDavid van Moolenbroek /* CCP config options */
1206*b636d99dSDavid van Moolenbroek static int
print_ccp_config_options(netdissect_options * ndo,const u_char * p,int length)1207*b636d99dSDavid van Moolenbroek print_ccp_config_options(netdissect_options *ndo,
1208*b636d99dSDavid van Moolenbroek                          const u_char *p, int length)
1209*b636d99dSDavid van Moolenbroek {
1210*b636d99dSDavid van Moolenbroek 	int len, opt;
1211*b636d99dSDavid van Moolenbroek 
1212*b636d99dSDavid van Moolenbroek 	if (length < 2)
1213*b636d99dSDavid van Moolenbroek 		return 0;
1214*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
1215*b636d99dSDavid van Moolenbroek 	len = p[1];
1216*b636d99dSDavid van Moolenbroek 	opt = p[0];
1217*b636d99dSDavid van Moolenbroek 	if (length < len)
1218*b636d99dSDavid van Moolenbroek 		return 0;
1219*b636d99dSDavid van Moolenbroek 	if (len < 2) {
1220*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
1221*b636d99dSDavid van Moolenbroek 		          tok2str(ccpconfopts_values, "Unknown", opt),
1222*b636d99dSDavid van Moolenbroek 		          opt,
1223*b636d99dSDavid van Moolenbroek 		          len));
1224*b636d99dSDavid van Moolenbroek 		return 0;
1225*b636d99dSDavid van Moolenbroek 	}
1226*b636d99dSDavid van Moolenbroek 
1227*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u",
1228*b636d99dSDavid van Moolenbroek 	          tok2str(ccpconfopts_values, "Unknown", opt),
1229*b636d99dSDavid van Moolenbroek 	          opt,
1230*b636d99dSDavid van Moolenbroek 	          len));
1231*b636d99dSDavid van Moolenbroek 
1232*b636d99dSDavid van Moolenbroek 	switch (opt) {
1233*b636d99dSDavid van Moolenbroek 	case CCPOPT_BSDCOMP:
1234*b636d99dSDavid van Moolenbroek 		if (len < 3) {
1235*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 3)"));
1236*b636d99dSDavid van Moolenbroek 			return len;
1237*b636d99dSDavid van Moolenbroek 		}
1238*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 1);
1239*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Version: %u, Dictionary Bits: %u",
1240*b636d99dSDavid van Moolenbroek 			p[2] >> 5, p[2] & 0x1f));
1241*b636d99dSDavid van Moolenbroek 		break;
1242*b636d99dSDavid van Moolenbroek 	case CCPOPT_MVRCA:
1243*b636d99dSDavid van Moolenbroek 		if (len < 4) {
1244*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
1245*b636d99dSDavid van Moolenbroek 			return len;
1246*b636d99dSDavid van Moolenbroek 		}
1247*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 1);
1248*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Features: %u, PxP: %s, History: %u, #CTX-ID: %u",
1249*b636d99dSDavid van Moolenbroek 				(p[2] & 0xc0) >> 6,
1250*b636d99dSDavid van Moolenbroek 				(p[2] & 0x20) ? "Enabled" : "Disabled",
1251*b636d99dSDavid van Moolenbroek 				p[2] & 0x1f, p[3]));
1252*b636d99dSDavid van Moolenbroek 		break;
1253*b636d99dSDavid van Moolenbroek 	case CCPOPT_DEFLATE:
1254*b636d99dSDavid van Moolenbroek 		if (len < 4) {
1255*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be >= 4)"));
1256*b636d99dSDavid van Moolenbroek 			return len;
1257*b636d99dSDavid van Moolenbroek 		}
1258*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 1);
1259*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Window: %uK, Method: %s (0x%x), MBZ: %u, CHK: %u",
1260*b636d99dSDavid van Moolenbroek 			(p[2] & 0xf0) >> 4,
1261*b636d99dSDavid van Moolenbroek 			((p[2] & 0x0f) == 8) ? "zlib" : "unkown",
1262*b636d99dSDavid van Moolenbroek 			p[2] & 0x0f, (p[3] & 0xfc) >> 2, p[3] & 0x03));
1263*b636d99dSDavid van Moolenbroek 		break;
1264*b636d99dSDavid van Moolenbroek 
1265*b636d99dSDavid van Moolenbroek /* XXX: to be supported */
1266*b636d99dSDavid van Moolenbroek #if 0
1267*b636d99dSDavid van Moolenbroek 	case CCPOPT_OUI:
1268*b636d99dSDavid van Moolenbroek 	case CCPOPT_PRED1:
1269*b636d99dSDavid van Moolenbroek 	case CCPOPT_PRED2:
1270*b636d99dSDavid van Moolenbroek 	case CCPOPT_PJUMP:
1271*b636d99dSDavid van Moolenbroek 	case CCPOPT_HPPPC:
1272*b636d99dSDavid van Moolenbroek 	case CCPOPT_STACLZS:
1273*b636d99dSDavid van Moolenbroek 	case CCPOPT_MPPC:
1274*b636d99dSDavid van Moolenbroek 	case CCPOPT_GFZA:
1275*b636d99dSDavid van Moolenbroek 	case CCPOPT_V42BIS:
1276*b636d99dSDavid van Moolenbroek 	case CCPOPT_LZSDCP:
1277*b636d99dSDavid van Moolenbroek 	case CCPOPT_DEC:
1278*b636d99dSDavid van Moolenbroek 	case CCPOPT_RESV:
1279*b636d99dSDavid van Moolenbroek 		break;
1280*b636d99dSDavid van Moolenbroek #endif
1281*b636d99dSDavid van Moolenbroek 	default:
1282*b636d99dSDavid van Moolenbroek 		/*
1283*b636d99dSDavid van Moolenbroek 		 * Unknown option; dump it as raw bytes now if we're
1284*b636d99dSDavid van Moolenbroek 		 * not going to do so below.
1285*b636d99dSDavid van Moolenbroek 		 */
1286*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag < 2)
1287*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
1288*b636d99dSDavid van Moolenbroek 		break;
1289*b636d99dSDavid van Moolenbroek 	}
1290*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
1291*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
1292*b636d99dSDavid van Moolenbroek 
1293*b636d99dSDavid van Moolenbroek 	return len;
1294*b636d99dSDavid van Moolenbroek 
1295*b636d99dSDavid van Moolenbroek trunc:
1296*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|ccp]"));
1297*b636d99dSDavid van Moolenbroek 	return 0;
1298*b636d99dSDavid van Moolenbroek }
1299*b636d99dSDavid van Moolenbroek 
1300*b636d99dSDavid van Moolenbroek /* BACP config options */
1301*b636d99dSDavid van Moolenbroek static int
print_bacp_config_options(netdissect_options * ndo,const u_char * p,int length)1302*b636d99dSDavid van Moolenbroek print_bacp_config_options(netdissect_options *ndo,
1303*b636d99dSDavid van Moolenbroek                           const u_char *p, int length)
1304*b636d99dSDavid van Moolenbroek {
1305*b636d99dSDavid van Moolenbroek 	int len, opt;
1306*b636d99dSDavid van Moolenbroek 
1307*b636d99dSDavid van Moolenbroek 	if (length < 2)
1308*b636d99dSDavid van Moolenbroek 		return 0;
1309*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
1310*b636d99dSDavid van Moolenbroek 	len = p[1];
1311*b636d99dSDavid van Moolenbroek 	opt = p[0];
1312*b636d99dSDavid van Moolenbroek 	if (length < len)
1313*b636d99dSDavid van Moolenbroek 		return 0;
1314*b636d99dSDavid van Moolenbroek 	if (len < 2) {
1315*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u (length bogus, should be >= 2)",
1316*b636d99dSDavid van Moolenbroek 		          tok2str(bacconfopts_values, "Unknown", opt),
1317*b636d99dSDavid van Moolenbroek 		          opt,
1318*b636d99dSDavid van Moolenbroek 		          len));
1319*b636d99dSDavid van Moolenbroek 		return 0;
1320*b636d99dSDavid van Moolenbroek 	}
1321*b636d99dSDavid van Moolenbroek 
1322*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "\n\t  %s Option (0x%02x), length %u",
1323*b636d99dSDavid van Moolenbroek 	          tok2str(bacconfopts_values, "Unknown", opt),
1324*b636d99dSDavid van Moolenbroek 	          opt,
1325*b636d99dSDavid van Moolenbroek 	          len));
1326*b636d99dSDavid van Moolenbroek 
1327*b636d99dSDavid van Moolenbroek 	switch (opt) {
1328*b636d99dSDavid van Moolenbroek 	case BACPOPT_FPEER:
1329*b636d99dSDavid van Moolenbroek 		if (len != 6) {
1330*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, " (length bogus, should be = 6)"));
1331*b636d99dSDavid van Moolenbroek 			return len;
1332*b636d99dSDavid van Moolenbroek 		}
1333*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*(p + 2), 4);
1334*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, ": Magic-Num 0x%08x", EXTRACT_32BITS(p + 2)));
1335*b636d99dSDavid van Moolenbroek 		break;
1336*b636d99dSDavid van Moolenbroek 	default:
1337*b636d99dSDavid van Moolenbroek 		/*
1338*b636d99dSDavid van Moolenbroek 		 * Unknown option; dump it as raw bytes now if we're
1339*b636d99dSDavid van Moolenbroek 		 * not going to do so below.
1340*b636d99dSDavid van Moolenbroek 		 */
1341*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_vflag < 2)
1342*b636d99dSDavid van Moolenbroek 			print_unknown_data(ndo, &p[2], "\n\t    ", len - 2);
1343*b636d99dSDavid van Moolenbroek 		break;
1344*b636d99dSDavid van Moolenbroek 	}
1345*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_vflag > 1)
1346*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, &p[2], "\n\t    ", len - 2); /* exclude TLV header */
1347*b636d99dSDavid van Moolenbroek 
1348*b636d99dSDavid van Moolenbroek 	return len;
1349*b636d99dSDavid van Moolenbroek 
1350*b636d99dSDavid van Moolenbroek trunc:
1351*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|bacp]"));
1352*b636d99dSDavid van Moolenbroek 	return 0;
1353*b636d99dSDavid van Moolenbroek }
1354*b636d99dSDavid van Moolenbroek 
1355*b636d99dSDavid van Moolenbroek static void
ppp_hdlc(netdissect_options * ndo,const u_char * p,int length)1356*b636d99dSDavid van Moolenbroek ppp_hdlc(netdissect_options *ndo,
1357*b636d99dSDavid van Moolenbroek          const u_char *p, int length)
1358*b636d99dSDavid van Moolenbroek {
1359*b636d99dSDavid van Moolenbroek 	u_char *b, *t, c;
1360*b636d99dSDavid van Moolenbroek 	const u_char *s;
1361*b636d99dSDavid van Moolenbroek 	int i, proto;
1362*b636d99dSDavid van Moolenbroek 	const void *se;
1363*b636d99dSDavid van Moolenbroek 
1364*b636d99dSDavid van Moolenbroek         if (length <= 0)
1365*b636d99dSDavid van Moolenbroek                 return;
1366*b636d99dSDavid van Moolenbroek 
1367*b636d99dSDavid van Moolenbroek 	b = (u_char *)malloc(length);
1368*b636d99dSDavid van Moolenbroek 	if (b == NULL)
1369*b636d99dSDavid van Moolenbroek 		return;
1370*b636d99dSDavid van Moolenbroek 
1371*b636d99dSDavid van Moolenbroek 	/*
1372*b636d99dSDavid van Moolenbroek 	 * Unescape all the data into a temporary, private, buffer.
1373*b636d99dSDavid van Moolenbroek 	 * Do this so that we dont overwrite the original packet
1374*b636d99dSDavid van Moolenbroek 	 * contents.
1375*b636d99dSDavid van Moolenbroek 	 */
1376*b636d99dSDavid van Moolenbroek 	for (s = p, t = b, i = length; i > 0 && ND_TTEST(*s); i--) {
1377*b636d99dSDavid van Moolenbroek 		c = *s++;
1378*b636d99dSDavid van Moolenbroek 		if (c == 0x7d) {
1379*b636d99dSDavid van Moolenbroek 			if (i <= 1 || !ND_TTEST(*s))
1380*b636d99dSDavid van Moolenbroek 				break;
1381*b636d99dSDavid van Moolenbroek 			i--;
1382*b636d99dSDavid van Moolenbroek 			c = *s++ ^ 0x20;
1383*b636d99dSDavid van Moolenbroek 		}
1384*b636d99dSDavid van Moolenbroek 		*t++ = c;
1385*b636d99dSDavid van Moolenbroek 	}
1386*b636d99dSDavid van Moolenbroek 
1387*b636d99dSDavid van Moolenbroek 	se = ndo->ndo_snapend;
1388*b636d99dSDavid van Moolenbroek 	ndo->ndo_snapend = t;
1389*b636d99dSDavid van Moolenbroek 	length = t - b;
1390*b636d99dSDavid van Moolenbroek 
1391*b636d99dSDavid van Moolenbroek         /* now lets guess about the payload codepoint format */
1392*b636d99dSDavid van Moolenbroek         if (length < 1)
1393*b636d99dSDavid van Moolenbroek                 goto trunc;
1394*b636d99dSDavid van Moolenbroek         proto = *b; /* start with a one-octet codepoint guess */
1395*b636d99dSDavid van Moolenbroek 
1396*b636d99dSDavid van Moolenbroek         switch (proto) {
1397*b636d99dSDavid van Moolenbroek         case PPP_IP:
1398*b636d99dSDavid van Moolenbroek 		ip_print(ndo, b + 1, length - 1);
1399*b636d99dSDavid van Moolenbroek 		goto cleanup;
1400*b636d99dSDavid van Moolenbroek         case PPP_IPV6:
1401*b636d99dSDavid van Moolenbroek 		ip6_print(ndo, b + 1, length - 1);
1402*b636d99dSDavid van Moolenbroek 		goto cleanup;
1403*b636d99dSDavid van Moolenbroek         default: /* no luck - try next guess */
1404*b636d99dSDavid van Moolenbroek 		break;
1405*b636d99dSDavid van Moolenbroek         }
1406*b636d99dSDavid van Moolenbroek 
1407*b636d99dSDavid van Moolenbroek         if (length < 2)
1408*b636d99dSDavid van Moolenbroek                 goto trunc;
1409*b636d99dSDavid van Moolenbroek         proto = EXTRACT_16BITS(b); /* next guess - load two octets */
1410*b636d99dSDavid van Moolenbroek 
1411*b636d99dSDavid van Moolenbroek         switch (proto) {
1412*b636d99dSDavid van Moolenbroek         case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */
1413*b636d99dSDavid van Moolenbroek             if (length < 4)
1414*b636d99dSDavid van Moolenbroek                 goto trunc;
1415*b636d99dSDavid van Moolenbroek             proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */
1416*b636d99dSDavid van Moolenbroek             handle_ppp(ndo, proto, b + 4, length - 4);
1417*b636d99dSDavid van Moolenbroek             break;
1418*b636d99dSDavid van Moolenbroek         default: /* last guess - proto must be a PPP proto-id */
1419*b636d99dSDavid van Moolenbroek             handle_ppp(ndo, proto, b + 2, length - 2);
1420*b636d99dSDavid van Moolenbroek             break;
1421*b636d99dSDavid van Moolenbroek         }
1422*b636d99dSDavid van Moolenbroek 
1423*b636d99dSDavid van Moolenbroek cleanup:
1424*b636d99dSDavid van Moolenbroek 	ndo->ndo_snapend = se;
1425*b636d99dSDavid van Moolenbroek 	free(b);
1426*b636d99dSDavid van Moolenbroek         return;
1427*b636d99dSDavid van Moolenbroek 
1428*b636d99dSDavid van Moolenbroek trunc:
1429*b636d99dSDavid van Moolenbroek 	ndo->ndo_snapend = se;
1430*b636d99dSDavid van Moolenbroek 	free(b);
1431*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|ppp]"));
1432*b636d99dSDavid van Moolenbroek }
1433*b636d99dSDavid van Moolenbroek 
1434*b636d99dSDavid van Moolenbroek 
1435*b636d99dSDavid van Moolenbroek /* PPP */
1436*b636d99dSDavid van Moolenbroek static void
handle_ppp(netdissect_options * ndo,u_int proto,const u_char * p,int length)1437*b636d99dSDavid van Moolenbroek handle_ppp(netdissect_options *ndo,
1438*b636d99dSDavid van Moolenbroek            u_int proto, const u_char *p, int length)
1439*b636d99dSDavid van Moolenbroek {
1440*b636d99dSDavid van Moolenbroek 	if ((proto & 0xff00) == 0x7e00) { /* is this an escape code ? */
1441*b636d99dSDavid van Moolenbroek 		ppp_hdlc(ndo, p - 1, length);
1442*b636d99dSDavid van Moolenbroek 		return;
1443*b636d99dSDavid van Moolenbroek 	}
1444*b636d99dSDavid van Moolenbroek 
1445*b636d99dSDavid van Moolenbroek 	switch (proto) {
1446*b636d99dSDavid van Moolenbroek 	case PPP_LCP: /* fall through */
1447*b636d99dSDavid van Moolenbroek 	case PPP_IPCP:
1448*b636d99dSDavid van Moolenbroek 	case PPP_OSICP:
1449*b636d99dSDavid van Moolenbroek 	case PPP_MPLSCP:
1450*b636d99dSDavid van Moolenbroek 	case PPP_IPV6CP:
1451*b636d99dSDavid van Moolenbroek 	case PPP_CCP:
1452*b636d99dSDavid van Moolenbroek 	case PPP_BACP:
1453*b636d99dSDavid van Moolenbroek 		handle_ctrl_proto(ndo, proto, p, length);
1454*b636d99dSDavid van Moolenbroek 		break;
1455*b636d99dSDavid van Moolenbroek 	case PPP_ML:
1456*b636d99dSDavid van Moolenbroek 		handle_mlppp(ndo, p, length);
1457*b636d99dSDavid van Moolenbroek 		break;
1458*b636d99dSDavid van Moolenbroek 	case PPP_CHAP:
1459*b636d99dSDavid van Moolenbroek 		handle_chap(ndo, p, length);
1460*b636d99dSDavid van Moolenbroek 		break;
1461*b636d99dSDavid van Moolenbroek 	case PPP_PAP:
1462*b636d99dSDavid van Moolenbroek 		handle_pap(ndo, p, length);
1463*b636d99dSDavid van Moolenbroek 		break;
1464*b636d99dSDavid van Moolenbroek 	case PPP_BAP:		/* XXX: not yet completed */
1465*b636d99dSDavid van Moolenbroek 		handle_bap(ndo, p, length);
1466*b636d99dSDavid van Moolenbroek 		break;
1467*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IP:	/*XXX*/
1468*b636d99dSDavid van Moolenbroek         case PPP_VJNC:
1469*b636d99dSDavid van Moolenbroek 	case PPP_IP:
1470*b636d99dSDavid van Moolenbroek 		ip_print(ndo, p, length);
1471*b636d99dSDavid van Moolenbroek 		break;
1472*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPV6:	/*XXX*/
1473*b636d99dSDavid van Moolenbroek 	case PPP_IPV6:
1474*b636d99dSDavid van Moolenbroek 		ip6_print(ndo, p, length);
1475*b636d99dSDavid van Moolenbroek 		break;
1476*b636d99dSDavid van Moolenbroek 	case ETHERTYPE_IPX:	/*XXX*/
1477*b636d99dSDavid van Moolenbroek 	case PPP_IPX:
1478*b636d99dSDavid van Moolenbroek 		ipx_print(ndo, p, length);
1479*b636d99dSDavid van Moolenbroek 		break;
1480*b636d99dSDavid van Moolenbroek 	case PPP_OSI:
1481*b636d99dSDavid van Moolenbroek 		isoclns_print(ndo, p, length, length);
1482*b636d99dSDavid van Moolenbroek 		break;
1483*b636d99dSDavid van Moolenbroek 	case PPP_MPLS_UCAST:
1484*b636d99dSDavid van Moolenbroek 	case PPP_MPLS_MCAST:
1485*b636d99dSDavid van Moolenbroek 		mpls_print(ndo, p, length);
1486*b636d99dSDavid van Moolenbroek 		break;
1487*b636d99dSDavid van Moolenbroek 	case PPP_COMP:
1488*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "compressed PPP data"));
1489*b636d99dSDavid van Moolenbroek 		break;
1490*b636d99dSDavid van Moolenbroek 	default:
1491*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)));
1492*b636d99dSDavid van Moolenbroek 		print_unknown_data(ndo, p, "\n\t", length);
1493*b636d99dSDavid van Moolenbroek 		break;
1494*b636d99dSDavid van Moolenbroek 	}
1495*b636d99dSDavid van Moolenbroek }
1496*b636d99dSDavid van Moolenbroek 
1497*b636d99dSDavid van Moolenbroek /* Standard PPP printer */
1498*b636d99dSDavid van Moolenbroek u_int
ppp_print(netdissect_options * ndo,register const u_char * p,u_int length)1499*b636d99dSDavid van Moolenbroek ppp_print(netdissect_options *ndo,
1500*b636d99dSDavid van Moolenbroek           register const u_char *p, u_int length)
1501*b636d99dSDavid van Moolenbroek {
1502*b636d99dSDavid van Moolenbroek 	u_int proto,ppp_header;
1503*b636d99dSDavid van Moolenbroek         u_int olen = length; /* _o_riginal length */
1504*b636d99dSDavid van Moolenbroek 	u_int hdr_len = 0;
1505*b636d99dSDavid van Moolenbroek 
1506*b636d99dSDavid van Moolenbroek 	/*
1507*b636d99dSDavid van Moolenbroek 	 * Here, we assume that p points to the Address and Control
1508*b636d99dSDavid van Moolenbroek 	 * field (if they present).
1509*b636d99dSDavid van Moolenbroek 	 */
1510*b636d99dSDavid van Moolenbroek 	if (length < 2)
1511*b636d99dSDavid van Moolenbroek 		goto trunc;
1512*b636d99dSDavid van Moolenbroek 	ND_TCHECK2(*p, 2);
1513*b636d99dSDavid van Moolenbroek         ppp_header = EXTRACT_16BITS(p);
1514*b636d99dSDavid van Moolenbroek 
1515*b636d99dSDavid van Moolenbroek         switch(ppp_header) {
1516*b636d99dSDavid van Moolenbroek         case (PPP_WITHDIRECTION_IN  << 8 | PPP_CONTROL):
1517*b636d99dSDavid van Moolenbroek             if (ndo->ndo_eflag) ND_PRINT((ndo, "In  "));
1518*b636d99dSDavid van Moolenbroek             p += 2;
1519*b636d99dSDavid van Moolenbroek             length -= 2;
1520*b636d99dSDavid van Moolenbroek             hdr_len += 2;
1521*b636d99dSDavid van Moolenbroek             break;
1522*b636d99dSDavid van Moolenbroek         case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
1523*b636d99dSDavid van Moolenbroek             if (ndo->ndo_eflag) ND_PRINT((ndo, "Out "));
1524*b636d99dSDavid van Moolenbroek             p += 2;
1525*b636d99dSDavid van Moolenbroek             length -= 2;
1526*b636d99dSDavid van Moolenbroek             hdr_len += 2;
1527*b636d99dSDavid van Moolenbroek             break;
1528*b636d99dSDavid van Moolenbroek         case (PPP_ADDRESS << 8 | PPP_CONTROL):
1529*b636d99dSDavid van Moolenbroek             p += 2;			/* ACFC not used */
1530*b636d99dSDavid van Moolenbroek             length -= 2;
1531*b636d99dSDavid van Moolenbroek             hdr_len += 2;
1532*b636d99dSDavid van Moolenbroek             break;
1533*b636d99dSDavid van Moolenbroek 
1534*b636d99dSDavid van Moolenbroek         default:
1535*b636d99dSDavid van Moolenbroek             break;
1536*b636d99dSDavid van Moolenbroek         }
1537*b636d99dSDavid van Moolenbroek 
1538*b636d99dSDavid van Moolenbroek 	if (length < 2)
1539*b636d99dSDavid van Moolenbroek 		goto trunc;
1540*b636d99dSDavid van Moolenbroek 	ND_TCHECK(*p);
1541*b636d99dSDavid van Moolenbroek 	if (*p % 2) {
1542*b636d99dSDavid van Moolenbroek 		proto = *p;		/* PFC is used */
1543*b636d99dSDavid van Moolenbroek 		p++;
1544*b636d99dSDavid van Moolenbroek 		length--;
1545*b636d99dSDavid van Moolenbroek 		hdr_len++;
1546*b636d99dSDavid van Moolenbroek 	} else {
1547*b636d99dSDavid van Moolenbroek 		ND_TCHECK2(*p, 2);
1548*b636d99dSDavid van Moolenbroek 		proto = EXTRACT_16BITS(p);
1549*b636d99dSDavid van Moolenbroek 		p += 2;
1550*b636d99dSDavid van Moolenbroek 		length -= 2;
1551*b636d99dSDavid van Moolenbroek 		hdr_len += 2;
1552*b636d99dSDavid van Moolenbroek 	}
1553*b636d99dSDavid van Moolenbroek 
1554*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag)
1555*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s (0x%04x), length %u: ",
1556*b636d99dSDavid van Moolenbroek 		          tok2str(ppptype2str, "unknown", proto),
1557*b636d99dSDavid van Moolenbroek 		          proto,
1558*b636d99dSDavid van Moolenbroek 		          olen));
1559*b636d99dSDavid van Moolenbroek 
1560*b636d99dSDavid van Moolenbroek 	handle_ppp(ndo, proto, p, length);
1561*b636d99dSDavid van Moolenbroek 	return (hdr_len);
1562*b636d99dSDavid van Moolenbroek trunc:
1563*b636d99dSDavid van Moolenbroek 	ND_PRINT((ndo, "[|ppp]"));
1564*b636d99dSDavid van Moolenbroek 	return (0);
1565*b636d99dSDavid van Moolenbroek }
1566*b636d99dSDavid van Moolenbroek 
1567*b636d99dSDavid van Moolenbroek 
1568*b636d99dSDavid van Moolenbroek /* PPP I/F printer */
1569*b636d99dSDavid van Moolenbroek u_int
ppp_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,register const u_char * p)1570*b636d99dSDavid van Moolenbroek ppp_if_print(netdissect_options *ndo,
1571*b636d99dSDavid van Moolenbroek              const struct pcap_pkthdr *h, register const u_char *p)
1572*b636d99dSDavid van Moolenbroek {
1573*b636d99dSDavid van Moolenbroek 	register u_int length = h->len;
1574*b636d99dSDavid van Moolenbroek 	register u_int caplen = h->caplen;
1575*b636d99dSDavid van Moolenbroek 
1576*b636d99dSDavid van Moolenbroek 	if (caplen < PPP_HDRLEN) {
1577*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|ppp]"));
1578*b636d99dSDavid van Moolenbroek 		return (caplen);
1579*b636d99dSDavid van Moolenbroek 	}
1580*b636d99dSDavid van Moolenbroek 
1581*b636d99dSDavid van Moolenbroek #if 0
1582*b636d99dSDavid van Moolenbroek 	/*
1583*b636d99dSDavid van Moolenbroek 	 * XXX: seems to assume that there are 2 octets prepended to an
1584*b636d99dSDavid van Moolenbroek 	 * actual PPP frame. The 1st octet looks like Input/Output flag
1585*b636d99dSDavid van Moolenbroek 	 * while 2nd octet is unknown, at least to me
1586*b636d99dSDavid van Moolenbroek 	 * (mshindo@mshindo.net).
1587*b636d99dSDavid van Moolenbroek 	 *
1588*b636d99dSDavid van Moolenbroek 	 * That was what the original tcpdump code did.
1589*b636d99dSDavid van Moolenbroek 	 *
1590*b636d99dSDavid van Moolenbroek 	 * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
1591*b636d99dSDavid van Moolenbroek 	 * packets and 0 for inbound packets - but only if the
1592*b636d99dSDavid van Moolenbroek 	 * protocol field has the 0x8000 bit set (i.e., it's a network
1593*b636d99dSDavid van Moolenbroek 	 * control protocol); it does so before running the packet through
1594*b636d99dSDavid van Moolenbroek 	 * "bpf_filter" to see if it should be discarded, and to see
1595*b636d99dSDavid van Moolenbroek 	 * if we should update the time we sent the most recent packet...
1596*b636d99dSDavid van Moolenbroek 	 *
1597*b636d99dSDavid van Moolenbroek 	 * ...but it puts the original address field back after doing
1598*b636d99dSDavid van Moolenbroek 	 * so.
1599*b636d99dSDavid van Moolenbroek 	 *
1600*b636d99dSDavid van Moolenbroek 	 * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
1601*b636d99dSDavid van Moolenbroek 	 *
1602*b636d99dSDavid van Moolenbroek 	 * I don't know if any PPP implementation handed up to a BPF
1603*b636d99dSDavid van Moolenbroek 	 * device packets with the first octet being 1 for outbound and
1604*b636d99dSDavid van Moolenbroek 	 * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
1605*b636d99dSDavid van Moolenbroek 	 * whether that ever needs to be checked or not.
1606*b636d99dSDavid van Moolenbroek 	 *
1607*b636d99dSDavid van Moolenbroek 	 * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
1608*b636d99dSDavid van Moolenbroek 	 * and its tcpdump appears to assume that the frame always
1609*b636d99dSDavid van Moolenbroek 	 * begins with an address field and a control field, and that
1610*b636d99dSDavid van Moolenbroek 	 * the address field might be 0x0f or 0x8f, for Cisco
1611*b636d99dSDavid van Moolenbroek 	 * point-to-point with HDLC framing as per section 4.3.1 of RFC
1612*b636d99dSDavid van Moolenbroek 	 * 1547, as well as 0xff, for PPP in HDLC-like framing as per
1613*b636d99dSDavid van Moolenbroek 	 * RFC 1662.
1614*b636d99dSDavid van Moolenbroek 	 *
1615*b636d99dSDavid van Moolenbroek 	 * (Is the Cisco framing in question what DLT_C_HDLC, in
1616*b636d99dSDavid van Moolenbroek 	 * BSD/OS, is?)
1617*b636d99dSDavid van Moolenbroek 	 */
1618*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag)
1619*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]));
1620*b636d99dSDavid van Moolenbroek #endif
1621*b636d99dSDavid van Moolenbroek 
1622*b636d99dSDavid van Moolenbroek 	ppp_print(ndo, p, length);
1623*b636d99dSDavid van Moolenbroek 
1624*b636d99dSDavid van Moolenbroek 	return (0);
1625*b636d99dSDavid van Moolenbroek }
1626*b636d99dSDavid van Moolenbroek 
1627*b636d99dSDavid van Moolenbroek /*
1628*b636d99dSDavid van Moolenbroek  * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
1629*b636d99dSDavid van Moolenbroek  * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
1630*b636d99dSDavid van Moolenbroek  * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
1631*b636d99dSDavid van Moolenbroek  * discard them *if* those are the first two octets, and parse the remaining
1632*b636d99dSDavid van Moolenbroek  * packet as a PPP packet, as "ppp_print()" does).
1633*b636d99dSDavid van Moolenbroek  *
1634*b636d99dSDavid van Moolenbroek  * This handles, for example, DLT_PPP_SERIAL in NetBSD.
1635*b636d99dSDavid van Moolenbroek  */
1636*b636d99dSDavid van Moolenbroek u_int
ppp_hdlc_if_print(netdissect_options * ndo,const struct pcap_pkthdr * h,register const u_char * p)1637*b636d99dSDavid van Moolenbroek ppp_hdlc_if_print(netdissect_options *ndo,
1638*b636d99dSDavid van Moolenbroek                   const struct pcap_pkthdr *h, register const u_char *p)
1639*b636d99dSDavid van Moolenbroek {
1640*b636d99dSDavid van Moolenbroek 	register u_int length = h->len;
1641*b636d99dSDavid van Moolenbroek 	register u_int caplen = h->caplen;
1642*b636d99dSDavid van Moolenbroek 	u_int proto;
1643*b636d99dSDavid van Moolenbroek 	u_int hdrlen = 0;
1644*b636d99dSDavid van Moolenbroek 
1645*b636d99dSDavid van Moolenbroek 	if (caplen < 2) {
1646*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|ppp]"));
1647*b636d99dSDavid van Moolenbroek 		return (caplen);
1648*b636d99dSDavid van Moolenbroek 	}
1649*b636d99dSDavid van Moolenbroek 
1650*b636d99dSDavid van Moolenbroek 	switch (p[0]) {
1651*b636d99dSDavid van Moolenbroek 
1652*b636d99dSDavid van Moolenbroek 	case PPP_ADDRESS:
1653*b636d99dSDavid van Moolenbroek 		if (caplen < 4) {
1654*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "[|ppp]"));
1655*b636d99dSDavid van Moolenbroek 			return (caplen);
1656*b636d99dSDavid van Moolenbroek 		}
1657*b636d99dSDavid van Moolenbroek 
1658*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag)
1659*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length));
1660*b636d99dSDavid van Moolenbroek 		p += 2;
1661*b636d99dSDavid van Moolenbroek 		length -= 2;
1662*b636d99dSDavid van Moolenbroek 		hdrlen += 2;
1663*b636d99dSDavid van Moolenbroek 
1664*b636d99dSDavid van Moolenbroek 		proto = EXTRACT_16BITS(p);
1665*b636d99dSDavid van Moolenbroek 		p += 2;
1666*b636d99dSDavid van Moolenbroek 		length -= 2;
1667*b636d99dSDavid van Moolenbroek 		hdrlen += 2;
1668*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto)));
1669*b636d99dSDavid van Moolenbroek 
1670*b636d99dSDavid van Moolenbroek 		handle_ppp(ndo, proto, p, length);
1671*b636d99dSDavid van Moolenbroek 		break;
1672*b636d99dSDavid van Moolenbroek 
1673*b636d99dSDavid van Moolenbroek 	case CHDLC_UNICAST:
1674*b636d99dSDavid van Moolenbroek 	case CHDLC_BCAST:
1675*b636d99dSDavid van Moolenbroek 		return (chdlc_if_print(ndo, h, p));
1676*b636d99dSDavid van Moolenbroek 
1677*b636d99dSDavid van Moolenbroek 	default:
1678*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag)
1679*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x %02x %d ", p[0], p[1], length));
1680*b636d99dSDavid van Moolenbroek 		p += 2;
1681*b636d99dSDavid van Moolenbroek 		hdrlen += 2;
1682*b636d99dSDavid van Moolenbroek 
1683*b636d99dSDavid van Moolenbroek 		/*
1684*b636d99dSDavid van Moolenbroek 		 * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
1685*b636d99dSDavid van Moolenbroek 		 * the next two octets as an Ethernet type; does that
1686*b636d99dSDavid van Moolenbroek 		 * ever happen?
1687*b636d99dSDavid van Moolenbroek 		 */
1688*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "unknown addr %02x; ctrl %02x", p[0], p[1]));
1689*b636d99dSDavid van Moolenbroek 		break;
1690*b636d99dSDavid van Moolenbroek 	}
1691*b636d99dSDavid van Moolenbroek 
1692*b636d99dSDavid van Moolenbroek 	return (hdrlen);
1693*b636d99dSDavid van Moolenbroek }
1694*b636d99dSDavid van Moolenbroek 
1695*b636d99dSDavid van Moolenbroek #define PPP_BSDI_HDRLEN 24
1696*b636d99dSDavid van Moolenbroek 
1697*b636d99dSDavid van Moolenbroek /* BSD/OS specific PPP printer */
1698*b636d99dSDavid van Moolenbroek u_int
ppp_bsdos_if_print(netdissect_options * ndo _U_,const struct pcap_pkthdr * h _U_,register const u_char * p _U_)1699*b636d99dSDavid van Moolenbroek ppp_bsdos_if_print(netdissect_options *ndo _U_,
1700*b636d99dSDavid van Moolenbroek                    const struct pcap_pkthdr *h _U_, register const u_char *p _U_)
1701*b636d99dSDavid van Moolenbroek {
1702*b636d99dSDavid van Moolenbroek 	register int hdrlength;
1703*b636d99dSDavid van Moolenbroek #ifdef __bsdi__
1704*b636d99dSDavid van Moolenbroek 	register u_int length = h->len;
1705*b636d99dSDavid van Moolenbroek 	register u_int caplen = h->caplen;
1706*b636d99dSDavid van Moolenbroek 	uint16_t ptype;
1707*b636d99dSDavid van Moolenbroek 	const u_char *q;
1708*b636d99dSDavid van Moolenbroek 	int i;
1709*b636d99dSDavid van Moolenbroek 
1710*b636d99dSDavid van Moolenbroek 	if (caplen < PPP_BSDI_HDRLEN) {
1711*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "[|ppp]"));
1712*b636d99dSDavid van Moolenbroek 		return (caplen)
1713*b636d99dSDavid van Moolenbroek 	}
1714*b636d99dSDavid van Moolenbroek 
1715*b636d99dSDavid van Moolenbroek 	hdrlength = 0;
1716*b636d99dSDavid van Moolenbroek 
1717*b636d99dSDavid van Moolenbroek #if 0
1718*b636d99dSDavid van Moolenbroek 	if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
1719*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag)
1720*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x %02x ", p[0], p[1]));
1721*b636d99dSDavid van Moolenbroek 		p += 2;
1722*b636d99dSDavid van Moolenbroek 		hdrlength = 2;
1723*b636d99dSDavid van Moolenbroek 	}
1724*b636d99dSDavid van Moolenbroek 
1725*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag)
1726*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%d ", length));
1727*b636d99dSDavid van Moolenbroek 	/* Retrieve the protocol type */
1728*b636d99dSDavid van Moolenbroek 	if (*p & 01) {
1729*b636d99dSDavid van Moolenbroek 		/* Compressed protocol field */
1730*b636d99dSDavid van Moolenbroek 		ptype = *p;
1731*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag)
1732*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%02x ", ptype));
1733*b636d99dSDavid van Moolenbroek 		p++;
1734*b636d99dSDavid van Moolenbroek 		hdrlength += 1;
1735*b636d99dSDavid van Moolenbroek 	} else {
1736*b636d99dSDavid van Moolenbroek 		/* Un-compressed protocol field */
1737*b636d99dSDavid van Moolenbroek 		ptype = EXTRACT_16BITS(p);
1738*b636d99dSDavid van Moolenbroek 		if (ndo->ndo_eflag)
1739*b636d99dSDavid van Moolenbroek 			ND_PRINT((ndo, "%04x ", ptype));
1740*b636d99dSDavid van Moolenbroek 		p += 2;
1741*b636d99dSDavid van Moolenbroek 		hdrlength += 2;
1742*b636d99dSDavid van Moolenbroek 	}
1743*b636d99dSDavid van Moolenbroek #else
1744*b636d99dSDavid van Moolenbroek 	ptype = 0;	/*XXX*/
1745*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag)
1746*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%c ", p[SLC_DIR] ? 'O' : 'I'));
1747*b636d99dSDavid van Moolenbroek 	if (p[SLC_LLHL]) {
1748*b636d99dSDavid van Moolenbroek 		/* link level header */
1749*b636d99dSDavid van Moolenbroek 		struct ppp_header *ph;
1750*b636d99dSDavid van Moolenbroek 
1751*b636d99dSDavid van Moolenbroek 		q = p + SLC_BPFHDRLEN;
1752*b636d99dSDavid van Moolenbroek 		ph = (struct ppp_header *)q;
1753*b636d99dSDavid van Moolenbroek 		if (ph->phdr_addr == PPP_ADDRESS
1754*b636d99dSDavid van Moolenbroek 		 && ph->phdr_ctl == PPP_CONTROL) {
1755*b636d99dSDavid van Moolenbroek 			if (ndo->ndo_eflag)
1756*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%02x %02x ", q[0], q[1]));
1757*b636d99dSDavid van Moolenbroek 			ptype = EXTRACT_16BITS(&ph->phdr_type);
1758*b636d99dSDavid van Moolenbroek 			if (ndo->ndo_eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
1759*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "%s ", tok2str(ppptype2str,
1760*b636d99dSDavid van Moolenbroek 						"proto-#%d", ptype)));
1761*b636d99dSDavid van Moolenbroek 			}
1762*b636d99dSDavid van Moolenbroek 		} else {
1763*b636d99dSDavid van Moolenbroek 			if (ndo->ndo_eflag) {
1764*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "LLH=["));
1765*b636d99dSDavid van Moolenbroek 				for (i = 0; i < p[SLC_LLHL]; i++)
1766*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, "%02x", q[i]));
1767*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "] "));
1768*b636d99dSDavid van Moolenbroek 			}
1769*b636d99dSDavid van Moolenbroek 		}
1770*b636d99dSDavid van Moolenbroek 	}
1771*b636d99dSDavid van Moolenbroek 	if (ndo->ndo_eflag)
1772*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%d ", length));
1773*b636d99dSDavid van Moolenbroek 	if (p[SLC_CHL]) {
1774*b636d99dSDavid van Moolenbroek 		q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
1775*b636d99dSDavid van Moolenbroek 
1776*b636d99dSDavid van Moolenbroek 		switch (ptype) {
1777*b636d99dSDavid van Moolenbroek 		case PPP_VJC:
1778*b636d99dSDavid van Moolenbroek 			ptype = vjc_print(ndo, q, ptype);
1779*b636d99dSDavid van Moolenbroek 			hdrlength = PPP_BSDI_HDRLEN;
1780*b636d99dSDavid van Moolenbroek 			p += hdrlength;
1781*b636d99dSDavid van Moolenbroek 			switch (ptype) {
1782*b636d99dSDavid van Moolenbroek 			case PPP_IP:
1783*b636d99dSDavid van Moolenbroek 				ip_print(ndo, p, length);
1784*b636d99dSDavid van Moolenbroek 				break;
1785*b636d99dSDavid van Moolenbroek 			case PPP_IPV6:
1786*b636d99dSDavid van Moolenbroek 				ip6_print(ndo, p, length);
1787*b636d99dSDavid van Moolenbroek 				break;
1788*b636d99dSDavid van Moolenbroek 			case PPP_MPLS_UCAST:
1789*b636d99dSDavid van Moolenbroek 			case PPP_MPLS_MCAST:
1790*b636d99dSDavid van Moolenbroek 				mpls_print(ndo, p, length);
1791*b636d99dSDavid van Moolenbroek 				break;
1792*b636d99dSDavid van Moolenbroek 			}
1793*b636d99dSDavid van Moolenbroek 			goto printx;
1794*b636d99dSDavid van Moolenbroek 		case PPP_VJNC:
1795*b636d99dSDavid van Moolenbroek 			ptype = vjc_print(ndo, q, ptype);
1796*b636d99dSDavid van Moolenbroek 			hdrlength = PPP_BSDI_HDRLEN;
1797*b636d99dSDavid van Moolenbroek 			p += hdrlength;
1798*b636d99dSDavid van Moolenbroek 			switch (ptype) {
1799*b636d99dSDavid van Moolenbroek 			case PPP_IP:
1800*b636d99dSDavid van Moolenbroek 				ip_print(ndo, p, length);
1801*b636d99dSDavid van Moolenbroek 				break;
1802*b636d99dSDavid van Moolenbroek 			case PPP_IPV6:
1803*b636d99dSDavid van Moolenbroek 				ip6_print(ndo, p, length);
1804*b636d99dSDavid van Moolenbroek 				break;
1805*b636d99dSDavid van Moolenbroek 			case PPP_MPLS_UCAST:
1806*b636d99dSDavid van Moolenbroek 			case PPP_MPLS_MCAST:
1807*b636d99dSDavid van Moolenbroek 				mpls_print(ndo, p, length);
1808*b636d99dSDavid van Moolenbroek 				break;
1809*b636d99dSDavid van Moolenbroek 			}
1810*b636d99dSDavid van Moolenbroek 			goto printx;
1811*b636d99dSDavid van Moolenbroek 		default:
1812*b636d99dSDavid van Moolenbroek 			if (ndo->ndo_eflag) {
1813*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "CH=["));
1814*b636d99dSDavid van Moolenbroek 				for (i = 0; i < p[SLC_LLHL]; i++)
1815*b636d99dSDavid van Moolenbroek 					ND_PRINT((ndo, "%02x", q[i]));
1816*b636d99dSDavid van Moolenbroek 				ND_PRINT((ndo, "] "));
1817*b636d99dSDavid van Moolenbroek 			}
1818*b636d99dSDavid van Moolenbroek 			break;
1819*b636d99dSDavid van Moolenbroek 		}
1820*b636d99dSDavid van Moolenbroek 	}
1821*b636d99dSDavid van Moolenbroek 
1822*b636d99dSDavid van Moolenbroek 	hdrlength = PPP_BSDI_HDRLEN;
1823*b636d99dSDavid van Moolenbroek #endif
1824*b636d99dSDavid van Moolenbroek 
1825*b636d99dSDavid van Moolenbroek 	length -= hdrlength;
1826*b636d99dSDavid van Moolenbroek 	p += hdrlength;
1827*b636d99dSDavid van Moolenbroek 
1828*b636d99dSDavid van Moolenbroek 	switch (ptype) {
1829*b636d99dSDavid van Moolenbroek 	case PPP_IP:
1830*b636d99dSDavid van Moolenbroek 		ip_print(p, length);
1831*b636d99dSDavid van Moolenbroek 		break;
1832*b636d99dSDavid van Moolenbroek 	case PPP_IPV6:
1833*b636d99dSDavid van Moolenbroek 		ip6_print(ndo, p, length);
1834*b636d99dSDavid van Moolenbroek 		break;
1835*b636d99dSDavid van Moolenbroek 	case PPP_MPLS_UCAST:
1836*b636d99dSDavid van Moolenbroek 	case PPP_MPLS_MCAST:
1837*b636d99dSDavid van Moolenbroek 		mpls_print(ndo, p, length);
1838*b636d99dSDavid van Moolenbroek 		break;
1839*b636d99dSDavid van Moolenbroek 	default:
1840*b636d99dSDavid van Moolenbroek 		ND_PRINT((ndo, "%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype)));
1841*b636d99dSDavid van Moolenbroek 	}
1842*b636d99dSDavid van Moolenbroek 
1843*b636d99dSDavid van Moolenbroek printx:
1844*b636d99dSDavid van Moolenbroek #else /* __bsdi */
1845*b636d99dSDavid van Moolenbroek 	hdrlength = 0;
1846*b636d99dSDavid van Moolenbroek #endif /* __bsdi__ */
1847*b636d99dSDavid van Moolenbroek 	return (hdrlength);
1848*b636d99dSDavid van Moolenbroek }
1849*b636d99dSDavid van Moolenbroek 
1850*b636d99dSDavid van Moolenbroek 
1851*b636d99dSDavid van Moolenbroek /*
1852*b636d99dSDavid van Moolenbroek  * Local Variables:
1853*b636d99dSDavid van Moolenbroek  * c-style: whitesmith
1854*b636d99dSDavid van Moolenbroek  * c-basic-offset: 8
1855*b636d99dSDavid van Moolenbroek  * End:
1856*b636d99dSDavid van Moolenbroek  */
1857