xref: /onnv-gate/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_ppp.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2001-2002 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <stdio.h>
30*0Sstevel@tonic-gate #include <stdlib.h>
31*0Sstevel@tonic-gate #include <string.h>
32*0Sstevel@tonic-gate #include <sys/types.h>
33*0Sstevel@tonic-gate #include <sys/socket.h>
34*0Sstevel@tonic-gate #include <sys/sysmacros.h>
35*0Sstevel@tonic-gate #include <net/ppp_defs.h>
36*0Sstevel@tonic-gate #include <net/ppp-comp.h>
37*0Sstevel@tonic-gate #include <net/if.h>
38*0Sstevel@tonic-gate #include <netinet/in.h>
39*0Sstevel@tonic-gate #include <netinet/if_ether.h>
40*0Sstevel@tonic-gate #include <arpa/inet.h>
41*0Sstevel@tonic-gate #include "snoop.h"
42*0Sstevel@tonic-gate #include "snoop_ppp.h"
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate static int interpret_ppp_cp(int, uchar_t *, int, ppp_protoinfo_t *);
45*0Sstevel@tonic-gate static int interpret_cp_options(uchar_t *, int, ppp_protoinfo_t *);
46*0Sstevel@tonic-gate static int interpret_ppp_chap(int, uchar_t *, int, ppp_protoinfo_t *);
47*0Sstevel@tonic-gate static int interpret_ppp_pap(int, uchar_t *, int, ppp_protoinfo_t *);
48*0Sstevel@tonic-gate static int interpret_ppp_lqr(int, uchar_t *, int, ppp_protoinfo_t *);
49*0Sstevel@tonic-gate static ppp_protoinfo_t *ppp_getprotoinfo(uint16_t);
50*0Sstevel@tonic-gate static cp_optinfo_t *ppp_getoptinfo(cp_optinfo_t *, uint16_t);
51*0Sstevel@tonic-gate static optformat_func_t opt_format_vendor;
52*0Sstevel@tonic-gate static optformat_func_t opt_format_mru;
53*0Sstevel@tonic-gate static optformat_func_t opt_format_accm;
54*0Sstevel@tonic-gate static optformat_func_t opt_format_authproto;
55*0Sstevel@tonic-gate static optformat_func_t opt_format_qualproto;
56*0Sstevel@tonic-gate static optformat_func_t opt_format_magicnum;
57*0Sstevel@tonic-gate static optformat_func_t opt_format_fcs;
58*0Sstevel@tonic-gate static optformat_func_t opt_format_sdp;
59*0Sstevel@tonic-gate static optformat_func_t opt_format_nummode;
60*0Sstevel@tonic-gate static optformat_func_t opt_format_callback;
61*0Sstevel@tonic-gate static optformat_func_t opt_format_mrru;
62*0Sstevel@tonic-gate static optformat_func_t opt_format_epdisc;
63*0Sstevel@tonic-gate static optformat_func_t opt_format_dce;
64*0Sstevel@tonic-gate static optformat_func_t opt_format_linkdisc;
65*0Sstevel@tonic-gate static optformat_func_t opt_format_i18n;
66*0Sstevel@tonic-gate static optformat_func_t opt_format_ipaddresses;
67*0Sstevel@tonic-gate static optformat_func_t opt_format_ipcompproto;
68*0Sstevel@tonic-gate static optformat_func_t opt_format_ipaddress;
69*0Sstevel@tonic-gate static optformat_func_t opt_format_mobileipv4;
70*0Sstevel@tonic-gate static optformat_func_t opt_format_ifaceid;
71*0Sstevel@tonic-gate static optformat_func_t opt_format_ipv6compproto;
72*0Sstevel@tonic-gate static optformat_func_t opt_format_compoui;
73*0Sstevel@tonic-gate static optformat_func_t opt_format_bsdcomp;
74*0Sstevel@tonic-gate static optformat_func_t opt_format_staclzs;
75*0Sstevel@tonic-gate static optformat_func_t opt_format_mppc;
76*0Sstevel@tonic-gate static optformat_func_t opt_format_gandalf;
77*0Sstevel@tonic-gate static optformat_func_t opt_format_lzsdcp;
78*0Sstevel@tonic-gate static optformat_func_t opt_format_magnalink;
79*0Sstevel@tonic-gate static optformat_func_t opt_format_deflate;
80*0Sstevel@tonic-gate static optformat_func_t opt_format_encroui;
81*0Sstevel@tonic-gate static optformat_func_t opt_format_dese;
82*0Sstevel@tonic-gate static optformat_func_t opt_format_muxpid;
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate /*
85*0Sstevel@tonic-gate  * Many strings below are initialized with "Unknown".
86*0Sstevel@tonic-gate  */
87*0Sstevel@tonic-gate static char unknown_string[] = "Unknown";
88*0Sstevel@tonic-gate 
89*0Sstevel@tonic-gate /*
90*0Sstevel@tonic-gate  * Each known PPP protocol has an associated ppp_protoinfo_t in this array.
91*0Sstevel@tonic-gate  * Even if we can't decode the protocol (interpret_proto() == NULL),
92*0Sstevel@tonic-gate  * interpret_ppp() will at least print the protocol's name.  There is no
93*0Sstevel@tonic-gate  * dependency on the ordering of the entries in this array.  They have been
94*0Sstevel@tonic-gate  * ordered such that the most commonly used protocols are near the front.
95*0Sstevel@tonic-gate  * The array is delimited by a last entry of protocol of type
96*0Sstevel@tonic-gate  * PPP_PROTO_UNKNOWN.
97*0Sstevel@tonic-gate  */
98*0Sstevel@tonic-gate static ppp_protoinfo_t protoinfo_array[] = {
99*0Sstevel@tonic-gate 	{ PPP_IP,	"IP",		interpret_ip,	NULL,	NULL },
100*0Sstevel@tonic-gate 	{ PPP_IPV6,	"IPv6",		interpret_ipv6,	NULL,	NULL },
101*0Sstevel@tonic-gate 	{ PPP_COMP,	"Compressed Data",	NULL,	NULL,	NULL },
102*0Sstevel@tonic-gate 	{ PPP_OSI,	"OSI",			NULL,	NULL,	NULL },
103*0Sstevel@tonic-gate 	{ PPP_AT,	"AppleTalk",		NULL,	NULL,	NULL },
104*0Sstevel@tonic-gate 	{ PPP_IPX,	"IPX",			NULL,	NULL,	NULL },
105*0Sstevel@tonic-gate 	{ PPP_VJC_COMP,	"VJ Compressed TCP",    NULL,	NULL,	NULL },
106*0Sstevel@tonic-gate 	{ PPP_VJC_UNCOMP, "VJ Uncompressed TCP", NULL,	NULL,	NULL },
107*0Sstevel@tonic-gate 	{ PPP_BRIDGE,	"Bridging",		NULL,	NULL,	NULL },
108*0Sstevel@tonic-gate 	{ PPP_802HELLO,	"802.1d Hello",		NULL,	NULL,	NULL },
109*0Sstevel@tonic-gate 	{ PPP_MP,	"MP",			NULL,	NULL,	NULL },
110*0Sstevel@tonic-gate 	{ PPP_ENCRYPT,	"Encryption",		NULL,	NULL,	NULL },
111*0Sstevel@tonic-gate 	{ PPP_ENCRYPTFRAG, "Individual Link Encryption", NULL,	NULL,	NULL },
112*0Sstevel@tonic-gate 	{ PPP_MUX,	"PPP Muxing",		NULL,	NULL,	NULL },
113*0Sstevel@tonic-gate 	{ PPP_COMPFRAG,	"Single Link Compressed Data",	NULL,	NULL,	NULL },
114*0Sstevel@tonic-gate 	{ PPP_FULLHDR,	"IP Compression",	NULL,	NULL,	NULL },
115*0Sstevel@tonic-gate 	{ PPP_COMPTCP,	"IP Compression",	NULL,	NULL,	NULL },
116*0Sstevel@tonic-gate 	{ PPP_COMPNONTCP, "IP Compression",	NULL,	NULL,	NULL },
117*0Sstevel@tonic-gate 	{ PPP_COMPUDP8,	"IP Compression",	NULL,	NULL,	NULL },
118*0Sstevel@tonic-gate 	{ PPP_COMPRTP8,	"IP Compression",	NULL,	NULL,	NULL },
119*0Sstevel@tonic-gate 	{ PPP_COMPTCPND, "IP Compression",	NULL,	NULL,	NULL },
120*0Sstevel@tonic-gate 	{ PPP_COMPSTATE, "IP Compression",	NULL,	NULL,	NULL },
121*0Sstevel@tonic-gate 	{ PPP_COMPUDP16, "IP Compression",	NULL,	NULL,	NULL },
122*0Sstevel@tonic-gate 	{ PPP_COMPRTP16, "IP Compression",	NULL,	NULL,	NULL },
123*0Sstevel@tonic-gate 	{ PPP_MPLS,	"MPLS",			NULL,	NULL,	NULL },
124*0Sstevel@tonic-gate 	{ PPP_MPLSMC,	"MPLS M/C",		NULL,	NULL,	NULL },
125*0Sstevel@tonic-gate 	{ PPP_LQR,	"LQR",		interpret_ppp_lqr,	"PPP-LQR:  ",
126*0Sstevel@tonic-gate 	    "Link Quality Report" },
127*0Sstevel@tonic-gate 	{ PPP_LCP,	"LCP",		interpret_ppp_cp,	"PPP-LCP:  ",
128*0Sstevel@tonic-gate 	    "Link Control Protocol" },
129*0Sstevel@tonic-gate 	{ PPP_IPCP,	"IPCP",		interpret_ppp_cp,	"PPP-IPCP: ",
130*0Sstevel@tonic-gate 	    "IP Control Protocol" },
131*0Sstevel@tonic-gate 	{ PPP_IPV6CP,	"IPV6CP",	interpret_ppp_cp,	"PPP-IPV6CP:  ",
132*0Sstevel@tonic-gate 	    "IPv6 Control Protocol" },
133*0Sstevel@tonic-gate 	{ PPP_CCP,	"CCP",		interpret_ppp_cp,	"PPP-CCP:  ",
134*0Sstevel@tonic-gate 	    "Compression Control Protocol" },
135*0Sstevel@tonic-gate 	{ PPP_CCPFRAG,	"CCP-Link",	interpret_ppp_cp, "PPP-CCP-Link:  ",
136*0Sstevel@tonic-gate 	    "Per-Link Compression Control Protocol" },
137*0Sstevel@tonic-gate 	{ PPP_ECP,	"ECP",		interpret_ppp_cp,	"PPP-ECP:  ",
138*0Sstevel@tonic-gate 	    "Encryption Control Protocol" },
139*0Sstevel@tonic-gate 	{ PPP_ECPFRAG,	"ECP-Link",	interpret_ppp_cp, "PPP-ECP-Link:  ",
140*0Sstevel@tonic-gate 	    "Per-Link Encryption Control Protocol" },
141*0Sstevel@tonic-gate 	{ PPP_MPLSCP,	"MPLSCP",		NULL,	NULL,	NULL },
142*0Sstevel@tonic-gate 	{ PPP_OSINLCP,	"OSINLCP",		NULL,	NULL,	NULL },
143*0Sstevel@tonic-gate 	{ PPP_ATCP,	"ATCP",			NULL,	NULL,	NULL },
144*0Sstevel@tonic-gate 	{ PPP_IPXCP,	"IPXCP",		NULL,	NULL,	NULL },
145*0Sstevel@tonic-gate 	{ PPP_BACP,	"BACP",			NULL,	NULL,	NULL },
146*0Sstevel@tonic-gate 	{ PPP_BCP,	"BCP",			NULL,	NULL,	NULL },
147*0Sstevel@tonic-gate 	{ PPP_CBCP,	"CBCP",			NULL,	NULL,	NULL },
148*0Sstevel@tonic-gate 	{ PPP_BAP,	"BAP",			NULL,	NULL,	NULL },
149*0Sstevel@tonic-gate 	{ PPP_CHAP,	"CHAP",		interpret_ppp_chap,	"CHAP:  ",
150*0Sstevel@tonic-gate 	    "Challenge Handshake Authentication Protocl" },
151*0Sstevel@tonic-gate 	{ PPP_PAP,	"PAP",		interpret_ppp_pap,	"PAP:   ",
152*0Sstevel@tonic-gate 	    "Password Authentication Protocol" },
153*0Sstevel@tonic-gate 	{ PPP_EAP,	"EAP",			NULL,	NULL,	NULL },
154*0Sstevel@tonic-gate 	{ 0,		unknown_string,		NULL,	NULL,	NULL }
155*0Sstevel@tonic-gate };
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate static cp_optinfo_t lcp_optinfo[] = {
158*0Sstevel@tonic-gate 	{ OPT_LCP_VENDOR,	"Vendor-Specific",		6,
159*0Sstevel@tonic-gate 	    opt_format_vendor },
160*0Sstevel@tonic-gate 	{ OPT_LCP_MRU,		"Maximum-Receive-Unit",		4,
161*0Sstevel@tonic-gate 	    opt_format_mru },
162*0Sstevel@tonic-gate 	{ OPT_LCP_ASYNCMAP,	"Async-Control-Character-Map",	6,
163*0Sstevel@tonic-gate 	    opt_format_accm },
164*0Sstevel@tonic-gate 	{ OPT_LCP_AUTHTYPE,	"Authentication-Protocol",	4,
165*0Sstevel@tonic-gate 	    opt_format_authproto },
166*0Sstevel@tonic-gate 	{ OPT_LCP_QUALITY,	"Quality-Protocol",		4,
167*0Sstevel@tonic-gate 	    opt_format_qualproto },
168*0Sstevel@tonic-gate 	{ OPT_LCP_MAGICNUMBER,	"Magic-Number",			6,
169*0Sstevel@tonic-gate 	    opt_format_magicnum },
170*0Sstevel@tonic-gate 	{ OPT_LCP_PCOMPRESSION,	"Protocol-Field-Compression",	2,	NULL },
171*0Sstevel@tonic-gate 	{ OPT_LCP_ACCOMPRESSION, "Address-and-Control-Field-Compression", 2,
172*0Sstevel@tonic-gate 	    NULL },
173*0Sstevel@tonic-gate 	{ OPT_LCP_FCSALTERN,	"FCS-Alternative",		3,
174*0Sstevel@tonic-gate 	    opt_format_fcs },
175*0Sstevel@tonic-gate 	{ OPT_LCP_SELFDESCPAD,	"Self-Describing-Padding",	3,
176*0Sstevel@tonic-gate 	    opt_format_sdp },
177*0Sstevel@tonic-gate 	{ OPT_LCP_NUMBERED,	"Numbered-Mode",		3,
178*0Sstevel@tonic-gate 	    opt_format_nummode },
179*0Sstevel@tonic-gate 	{ OPT_LCP_MULTILINKPROC, "Multi-Link-Procedure",	2,	NULL },
180*0Sstevel@tonic-gate 	{ OPT_LCP_CALLBACK,	"Callback",			3,
181*0Sstevel@tonic-gate 	    opt_format_callback },
182*0Sstevel@tonic-gate 	{ OPT_LCP_CONNECTTIME,	"Connect-Time",			2,	NULL },
183*0Sstevel@tonic-gate 	{ OPT_LCP_COMPOUNDFRAMES, "Compound-Frames",		2,	NULL },
184*0Sstevel@tonic-gate 	{ OPT_LCP_DATAENCAP,	"Nominal-Data-Encapsulation",	2,	NULL },
185*0Sstevel@tonic-gate 	{ OPT_LCP_MRRU,		"Multilink-MRRU",		4,
186*0Sstevel@tonic-gate 	    opt_format_mrru },
187*0Sstevel@tonic-gate 	{ OPT_LCP_SSNHF,	"Multilink-Short-Sequence-Number-Header-Format",
188*0Sstevel@tonic-gate 	    2, NULL },
189*0Sstevel@tonic-gate 	{ OPT_LCP_EPDISC,	"Multilink-Endpoint-Discriminator",	3,
190*0Sstevel@tonic-gate 	    opt_format_epdisc },
191*0Sstevel@tonic-gate 	{ OPT_LCP_DCEIDENT,	"DCE-Identifier",		3,
192*0Sstevel@tonic-gate 	    opt_format_dce },
193*0Sstevel@tonic-gate 	{ OPT_LCP_MLPLUSPROC,	"Multi-Link-Plus-Procedure",	2,	NULL },
194*0Sstevel@tonic-gate 	{ OPT_LCP_LINKDISC,	"Link Discriminator for BACP",	4,
195*0Sstevel@tonic-gate 	    opt_format_linkdisc },
196*0Sstevel@tonic-gate 	{ OPT_LCP_AUTH,		"LCP-Authentication-Option",	2,	NULL },
197*0Sstevel@tonic-gate 	{ OPT_LCP_COBS,		"COBS",				2,	NULL },
198*0Sstevel@tonic-gate 	{ OPT_LCP_PFXELISION,	"Prefix elision",		2,	NULL },
199*0Sstevel@tonic-gate 	{ OPT_LCP_MPHDRFMT,	"Multilink header format",	2,	NULL },
200*0Sstevel@tonic-gate 	{ OPT_LCP_I18N,		"Internationalization",		6,
201*0Sstevel@tonic-gate 	    opt_format_i18n },
202*0Sstevel@tonic-gate 	{ OPT_LCP_SDL,		"Simple Data Link on SONET/SDH", 2,	NULL },
203*0Sstevel@tonic-gate 	{ OPT_LCP_MUXING,	"Old PPP Multiplexing",		2,	NULL },
204*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
205*0Sstevel@tonic-gate };
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate static cp_optinfo_t ipcp_optinfo[] = {
208*0Sstevel@tonic-gate 	{ OPT_IPCP_ADDRS,	"IP-Addresses",			10,
209*0Sstevel@tonic-gate 	    opt_format_ipaddresses },
210*0Sstevel@tonic-gate 	{ OPT_IPCP_COMPRESSTYPE, "IP-Compression-Protocol",	4,
211*0Sstevel@tonic-gate 	    opt_format_ipcompproto },
212*0Sstevel@tonic-gate 	{ OPT_IPCP_ADDR,	"IP-Address",			6,
213*0Sstevel@tonic-gate 	    opt_format_ipaddress },
214*0Sstevel@tonic-gate 	{ OPT_IPCP_MOBILEIPV4,	"Mobile-IPv4",			6,
215*0Sstevel@tonic-gate 	    opt_format_mobileipv4 },
216*0Sstevel@tonic-gate 	{ OPT_IPCP_DNS1,	"Primary DNS Address",		6,
217*0Sstevel@tonic-gate 	    opt_format_ipaddress },
218*0Sstevel@tonic-gate 	{ OPT_IPCP_NBNS1,	"Primary NBNS Address",		6,
219*0Sstevel@tonic-gate 	    opt_format_ipaddress },
220*0Sstevel@tonic-gate 	{ OPT_IPCP_DNS2,	"Secondary DNS Address", 	6,
221*0Sstevel@tonic-gate 	    opt_format_ipaddress },
222*0Sstevel@tonic-gate 	{ OPT_IPCP_NBNS2,	"Secondary NBNS Address",	6,
223*0Sstevel@tonic-gate 	    opt_format_ipaddress },
224*0Sstevel@tonic-gate 	{ OPT_IPCP_SUBNET,	"IP-Subnet",			6,
225*0Sstevel@tonic-gate 	    opt_format_ipaddress },
226*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
227*0Sstevel@tonic-gate };
228*0Sstevel@tonic-gate 
229*0Sstevel@tonic-gate static cp_optinfo_t ipv6cp_optinfo[] = {
230*0Sstevel@tonic-gate 	{ OPT_IPV6CP_IFACEID,	"Interface-Identifier",		10,
231*0Sstevel@tonic-gate 	    opt_format_ifaceid },
232*0Sstevel@tonic-gate 	{ OPT_IPV6CP_COMPRESSTYPE, "IPv6-Compression-Protocol",	4,
233*0Sstevel@tonic-gate 	    opt_format_ipv6compproto },
234*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
235*0Sstevel@tonic-gate };
236*0Sstevel@tonic-gate 
237*0Sstevel@tonic-gate static cp_optinfo_t ccp_optinfo[] = {
238*0Sstevel@tonic-gate 	{ OPT_CCP_PROPRIETARY,	"Proprietary Compression OUI",	6,
239*0Sstevel@tonic-gate 	    opt_format_compoui },
240*0Sstevel@tonic-gate 	{ OPT_CCP_PREDICTOR1,	"Predictor type 1",		2,	NULL },
241*0Sstevel@tonic-gate 	{ OPT_CCP_PREDICTOR2,	"Predictor type 2",		2,	NULL },
242*0Sstevel@tonic-gate 	{ OPT_CCP_PUDDLEJUMP,	"Puddle Jumper",		2,	NULL },
243*0Sstevel@tonic-gate 	{ OPT_CCP_HPPPC,	"Hewlett-Packard PPC",		2,	NULL },
244*0Sstevel@tonic-gate 	{ OPT_CCP_STACLZS,	"Stac Electronics LZS",		5,
245*0Sstevel@tonic-gate 	    opt_format_staclzs },
246*0Sstevel@tonic-gate 	{ OPT_CCP_MPPC,		"Microsoft PPC",		6,
247*0Sstevel@tonic-gate 	    opt_format_mppc },
248*0Sstevel@tonic-gate 	{ OPT_CCP_GANDALFFZA,	"Gandalf FZA",			3,
249*0Sstevel@tonic-gate 	    opt_format_gandalf },
250*0Sstevel@tonic-gate 	{ OPT_CCP_V42BIS,	"V.42bis compression",		2,
251*0Sstevel@tonic-gate 	    NULL },
252*0Sstevel@tonic-gate 	{ OPT_CCP_BSDCOMP,	"BSD LZW Compress",		3,
253*0Sstevel@tonic-gate 	    opt_format_bsdcomp },
254*0Sstevel@tonic-gate 	{ OPT_CCP_LZSDCP,	"LZS-DCP",			6,
255*0Sstevel@tonic-gate 	    opt_format_lzsdcp },
256*0Sstevel@tonic-gate 	{ OPT_CCP_MAGNALINK,	"Magnalink",			4,
257*0Sstevel@tonic-gate 	    opt_format_magnalink },
258*0Sstevel@tonic-gate 	{ OPT_CCP_DEFLATE,	"Deflate",			4,
259*0Sstevel@tonic-gate 	    opt_format_deflate },
260*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
261*0Sstevel@tonic-gate };
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate static cp_optinfo_t ecp_optinfo[] = {
264*0Sstevel@tonic-gate 	{ OPT_ECP_PROPRIETARY,	"Proprietary Encryption OUI",	6,
265*0Sstevel@tonic-gate 	    opt_format_encroui },
266*0Sstevel@tonic-gate 	{ OPT_ECP_DESE,		"DESE",				10,
267*0Sstevel@tonic-gate 	    opt_format_dese },
268*0Sstevel@tonic-gate 	{ OPT_ECP_3DESE,	"3DESE",			10,
269*0Sstevel@tonic-gate 	    opt_format_dese },
270*0Sstevel@tonic-gate 	{ OPT_ECP_DESEBIS,	"DESE-bis",			10,
271*0Sstevel@tonic-gate 	    opt_format_dese },
272*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
273*0Sstevel@tonic-gate };
274*0Sstevel@tonic-gate 
275*0Sstevel@tonic-gate static cp_optinfo_t muxcp_optinfo[] = {
276*0Sstevel@tonic-gate 	{ OPT_MUXCP_DEFAULTPID,	"Default PID",			4,
277*0Sstevel@tonic-gate 	    opt_format_muxpid },
278*0Sstevel@tonic-gate 	{ 0,			unknown_string,			0,	NULL }
279*0Sstevel@tonic-gate };
280*0Sstevel@tonic-gate 
281*0Sstevel@tonic-gate static char *cp_codearray[] = {
282*0Sstevel@tonic-gate 	"(Vendor Specific)",
283*0Sstevel@tonic-gate 	"(Configure-Request)",
284*0Sstevel@tonic-gate 	"(Configure-Ack)",
285*0Sstevel@tonic-gate 	"(Configure-Nak)",
286*0Sstevel@tonic-gate 	"(Configure-Reject)",
287*0Sstevel@tonic-gate 	"(Terminate-Request)",
288*0Sstevel@tonic-gate 	"(Terminate-Ack)",
289*0Sstevel@tonic-gate 	"(Code-Reject)",
290*0Sstevel@tonic-gate 	"(Protocol-Reject)",
291*0Sstevel@tonic-gate 	"(Echo-Request)",
292*0Sstevel@tonic-gate 	"(Echo-Reply)",
293*0Sstevel@tonic-gate 	"(Discard-Request)",
294*0Sstevel@tonic-gate 	"(Identification)",
295*0Sstevel@tonic-gate 	"(Time-Remaining)",
296*0Sstevel@tonic-gate 	"(Reset-Request)",
297*0Sstevel@tonic-gate 	"(Reset-Ack)"
298*0Sstevel@tonic-gate };
299*0Sstevel@tonic-gate #define	MAX_CPCODE	((sizeof (cp_codearray) / sizeof (char *)) - 1)
300*0Sstevel@tonic-gate 
301*0Sstevel@tonic-gate static char *pap_codearray[] = {
302*0Sstevel@tonic-gate 	"(Unknown)",
303*0Sstevel@tonic-gate 	"(Authenticate-Request)",
304*0Sstevel@tonic-gate 	"(Authenticate-Ack)",
305*0Sstevel@tonic-gate 	"(Authenticate-Nak)"
306*0Sstevel@tonic-gate };
307*0Sstevel@tonic-gate #define	MAX_PAPCODE	((sizeof (pap_codearray) / sizeof (char *)) - 1)
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate static char *chap_codearray[] = {
310*0Sstevel@tonic-gate 	"(Unknown)",
311*0Sstevel@tonic-gate 	"(Challenge)",
312*0Sstevel@tonic-gate 	"(Response)",
313*0Sstevel@tonic-gate 	"(Success)",
314*0Sstevel@tonic-gate 	"(Failure)"
315*0Sstevel@tonic-gate };
316*0Sstevel@tonic-gate #define	MAX_CHAPCODE	((sizeof (chap_codearray) / sizeof (char *)) - 1)
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 
319*0Sstevel@tonic-gate int
interpret_ppp(int flags,uchar_t * data,int len)320*0Sstevel@tonic-gate interpret_ppp(int flags, uchar_t *data, int len)
321*0Sstevel@tonic-gate {
322*0Sstevel@tonic-gate 	uint16_t protocol;
323*0Sstevel@tonic-gate 	ppp_protoinfo_t *protoinfo;
324*0Sstevel@tonic-gate 	uchar_t *payload = data;
325*0Sstevel@tonic-gate 
326*0Sstevel@tonic-gate 	if (len < 2)
327*0Sstevel@tonic-gate 		return (len);
328*0Sstevel@tonic-gate 
329*0Sstevel@tonic-gate 	GETINT16(protocol, payload);
330*0Sstevel@tonic-gate 	len -= sizeof (uint16_t);
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	protoinfo = ppp_getprotoinfo(protocol);
333*0Sstevel@tonic-gate 
334*0Sstevel@tonic-gate 	if (flags & F_SUM) {
335*0Sstevel@tonic-gate 		(void) sprintf(get_sum_line(),
336*0Sstevel@tonic-gate 		    "PPP Protocol=0x%x (%s)", protocol, protoinfo->name);
337*0Sstevel@tonic-gate 	} else { /* F_DTAIL */
338*0Sstevel@tonic-gate 		show_header("PPP:    ", "Point-to-Point Protocol", len);
339*0Sstevel@tonic-gate 		show_space();
340*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Protocol = 0x%x (%s)",
341*0Sstevel@tonic-gate 		    protocol, protoinfo->name);
342*0Sstevel@tonic-gate 		show_space();
343*0Sstevel@tonic-gate 	}
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate 	if (protoinfo->interpret_proto != NULL) {
346*0Sstevel@tonic-gate 		len = protoinfo->interpret_proto(flags, payload, len,
347*0Sstevel@tonic-gate 		    protoinfo);
348*0Sstevel@tonic-gate 	}
349*0Sstevel@tonic-gate 
350*0Sstevel@tonic-gate 	return (len);
351*0Sstevel@tonic-gate }
352*0Sstevel@tonic-gate 
353*0Sstevel@tonic-gate /*
354*0Sstevel@tonic-gate  * interpret_ppp_cp() - Interpret PPP control protocols.  It is convenient
355*0Sstevel@tonic-gate  * to do some of the decoding of these protocols in a common function since
356*0Sstevel@tonic-gate  * they share packet formats.  This function expects to receive data
357*0Sstevel@tonic-gate  * starting with the code field.
358*0Sstevel@tonic-gate  */
359*0Sstevel@tonic-gate static int
interpret_ppp_cp(int flags,uchar_t * data,int len,ppp_protoinfo_t * protoinfo)360*0Sstevel@tonic-gate interpret_ppp_cp(int flags, uchar_t *data, int len, ppp_protoinfo_t *protoinfo)
361*0Sstevel@tonic-gate {
362*0Sstevel@tonic-gate 	uint8_t code;
363*0Sstevel@tonic-gate 	uint8_t id;
364*0Sstevel@tonic-gate 	char *codestr;
365*0Sstevel@tonic-gate 	uint16_t length;
366*0Sstevel@tonic-gate 	uchar_t *datap = data;
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 	if (len < sizeof (ppp_pkt_t))
369*0Sstevel@tonic-gate 		return (len);
370*0Sstevel@tonic-gate 
371*0Sstevel@tonic-gate 	GETINT8(code, datap);
372*0Sstevel@tonic-gate 	GETINT8(id, datap);
373*0Sstevel@tonic-gate 	GETINT16(length, datap);
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 	len -= sizeof (ppp_pkt_t);
376*0Sstevel@tonic-gate 
377*0Sstevel@tonic-gate 	if (code <= MAX_CPCODE)
378*0Sstevel@tonic-gate 		codestr = cp_codearray[code];
379*0Sstevel@tonic-gate 	else
380*0Sstevel@tonic-gate 		codestr = "";
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate 	if (flags & F_SUM) {
383*0Sstevel@tonic-gate 		(void) sprintf(get_sum_line(),
384*0Sstevel@tonic-gate 		    "%s%s", protoinfo->prefix, codestr);
385*0Sstevel@tonic-gate 	} else { /* (flags & F_DTAIL) */
386*0Sstevel@tonic-gate 		show_header(protoinfo->prefix, protoinfo->description, len);
387*0Sstevel@tonic-gate 		show_space();
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Code = %d %s", code, codestr);
390*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Identifier = %d", id);
391*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Length = %d", length);
392*0Sstevel@tonic-gate 
393*0Sstevel@tonic-gate 		show_space();
394*0Sstevel@tonic-gate 
395*0Sstevel@tonic-gate 		len = MIN(len, length - sizeof (ppp_pkt_t));
396*0Sstevel@tonic-gate 		if (len == 0)
397*0Sstevel@tonic-gate 			return (len);
398*0Sstevel@tonic-gate 
399*0Sstevel@tonic-gate 		switch (code) {
400*0Sstevel@tonic-gate 		case CODE_VENDOR: {
401*0Sstevel@tonic-gate 			uint32_t magicnum;
402*0Sstevel@tonic-gate 			uint32_t oui;
403*0Sstevel@tonic-gate 			char *ouistr;
404*0Sstevel@tonic-gate 			uint8_t kind;
405*0Sstevel@tonic-gate 
406*0Sstevel@tonic-gate 			if (len < sizeof (magicnum) + sizeof (oui))
407*0Sstevel@tonic-gate 				return (len);
408*0Sstevel@tonic-gate 
409*0Sstevel@tonic-gate 			GETINT32(magicnum, datap);
410*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Magic-Number = 0x%08x",
411*0Sstevel@tonic-gate 			    magicnum);
412*0Sstevel@tonic-gate 
413*0Sstevel@tonic-gate 			GETINT32(oui, datap);
414*0Sstevel@tonic-gate 			kind = oui & 0x000000ff;
415*0Sstevel@tonic-gate 			oui >>= 8;
416*0Sstevel@tonic-gate 
417*0Sstevel@tonic-gate 			ouistr = ether_ouiname(oui);
418*0Sstevel@tonic-gate 			if (ouistr == NULL)
419*0Sstevel@tonic-gate 				ouistr = unknown_string;
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "OUI = 0x%06x (%s)",
422*0Sstevel@tonic-gate 			    oui, ouistr);
423*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Kind = %d", kind);
424*0Sstevel@tonic-gate 			show_space();
425*0Sstevel@tonic-gate 			break;
426*0Sstevel@tonic-gate 		}
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate 		case CODE_CONFREQ:
429*0Sstevel@tonic-gate 		case CODE_CONFACK:
430*0Sstevel@tonic-gate 		case CODE_CONFNAK:
431*0Sstevel@tonic-gate 		case CODE_CONFREJ:
432*0Sstevel@tonic-gate 			/*
433*0Sstevel@tonic-gate 			 * The above all contain protocol specific
434*0Sstevel@tonic-gate 			 * configuration options.  Parse these options.
435*0Sstevel@tonic-gate 			 */
436*0Sstevel@tonic-gate 			interpret_cp_options(datap, len, protoinfo);
437*0Sstevel@tonic-gate 			break;
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 		case CODE_TERMREQ:
440*0Sstevel@tonic-gate 		case CODE_TERMACK:
441*0Sstevel@tonic-gate 			/*
442*0Sstevel@tonic-gate 			 * The arbitrary data in these two packet types
443*0Sstevel@tonic-gate 			 * is almost always plain text.  Print it as such.
444*0Sstevel@tonic-gate 			 */
445*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Data = %.*s",
446*0Sstevel@tonic-gate 			    length - sizeof (ppp_pkt_t), datap);
447*0Sstevel@tonic-gate 			show_space();
448*0Sstevel@tonic-gate 			break;
449*0Sstevel@tonic-gate 
450*0Sstevel@tonic-gate 		case CODE_CODEREJ:
451*0Sstevel@tonic-gate 			/*
452*0Sstevel@tonic-gate 			 * What follows is the rejected control protocol
453*0Sstevel@tonic-gate 			 * packet, starting with the code field.
454*0Sstevel@tonic-gate 			 * Conveniently, we can call interpret_ppp_cp() to
455*0Sstevel@tonic-gate 			 * decode this.
456*0Sstevel@tonic-gate 			 */
457*0Sstevel@tonic-gate 			prot_nest_prefix = protoinfo->prefix;
458*0Sstevel@tonic-gate 			interpret_ppp_cp(flags, datap, len, protoinfo);
459*0Sstevel@tonic-gate 			prot_nest_prefix = "";
460*0Sstevel@tonic-gate 			break;
461*0Sstevel@tonic-gate 
462*0Sstevel@tonic-gate 		case CODE_PROTREJ:
463*0Sstevel@tonic-gate 			/*
464*0Sstevel@tonic-gate 			 * We don't print the rejected-protocol field
465*0Sstevel@tonic-gate 			 * explicitely.  Instead, we cheat and pretend that
466*0Sstevel@tonic-gate 			 * the rejected-protocol field is actually the
467*0Sstevel@tonic-gate 			 * protocol field in the included PPP packet.  This
468*0Sstevel@tonic-gate 			 * way, we can invoke interpret_ppp() and have it
469*0Sstevel@tonic-gate 			 * treat the included packet normally.
470*0Sstevel@tonic-gate 			 */
471*0Sstevel@tonic-gate 			prot_nest_prefix = protoinfo->prefix;
472*0Sstevel@tonic-gate 			interpret_ppp(flags, datap, len);
473*0Sstevel@tonic-gate 			prot_nest_prefix = "";
474*0Sstevel@tonic-gate 			break;
475*0Sstevel@tonic-gate 
476*0Sstevel@tonic-gate 		case CODE_ECHOREQ:
477*0Sstevel@tonic-gate 		case CODE_ECHOREP:
478*0Sstevel@tonic-gate 		case CODE_DISCREQ:
479*0Sstevel@tonic-gate 		case CODE_IDENT:
480*0Sstevel@tonic-gate 		case CODE_TIMEREMAIN: {
481*0Sstevel@tonic-gate 			uint32_t magicnum;
482*0Sstevel@tonic-gate 			char *message_label = "Identification = %.*s";
483*0Sstevel@tonic-gate 
484*0Sstevel@tonic-gate 			if (len < sizeof (uint32_t))
485*0Sstevel@tonic-gate 				break;
486*0Sstevel@tonic-gate 
487*0Sstevel@tonic-gate 			GETINT32(magicnum, datap);
488*0Sstevel@tonic-gate 			len -= sizeof (uint32_t);
489*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Magic-Number = 0x%08x",
490*0Sstevel@tonic-gate 			    magicnum);
491*0Sstevel@tonic-gate 			/*
492*0Sstevel@tonic-gate 			 * Unless this is an identification or
493*0Sstevel@tonic-gate 			 * time-remaining packet, arbitrary data follows
494*0Sstevel@tonic-gate 			 * the magic number field.  The user can take a
495*0Sstevel@tonic-gate 			 * look at the hex dump for enlightenment.
496*0Sstevel@tonic-gate 			 */
497*0Sstevel@tonic-gate 			if (code == CODE_TIMEREMAIN) {
498*0Sstevel@tonic-gate 				uint32_t timeremaining;
499*0Sstevel@tonic-gate 
500*0Sstevel@tonic-gate 				if (len < sizeof (uint32_t))
501*0Sstevel@tonic-gate 					break;
502*0Sstevel@tonic-gate 
503*0Sstevel@tonic-gate 				message_label = "Message = %.*s";
504*0Sstevel@tonic-gate 
505*0Sstevel@tonic-gate 				GETINT32(timeremaining, datap);
506*0Sstevel@tonic-gate 				len -= sizeof (uint32_t);
507*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0),
508*0Sstevel@tonic-gate 				    "Seconds Remaining = %d", timeremaining);
509*0Sstevel@tonic-gate 			}
510*0Sstevel@tonic-gate 
511*0Sstevel@tonic-gate 			if (code == CODE_IDENT || code == CODE_TIMEREMAIN) {
512*0Sstevel@tonic-gate 				if (len == 0)
513*0Sstevel@tonic-gate 					break;
514*0Sstevel@tonic-gate 
515*0Sstevel@tonic-gate 				(void) sprintf(get_line(0, 0), message_label,
516*0Sstevel@tonic-gate 				    len, datap);
517*0Sstevel@tonic-gate 			}
518*0Sstevel@tonic-gate 			show_space();
519*0Sstevel@tonic-gate 			break;
520*0Sstevel@tonic-gate 		}
521*0Sstevel@tonic-gate 
522*0Sstevel@tonic-gate 		/*
523*0Sstevel@tonic-gate 		 * Reset-Request and Reset-Ack contain arbitrary data which
524*0Sstevel@tonic-gate 		 * the user can sift through using the -x option.
525*0Sstevel@tonic-gate 		 */
526*0Sstevel@tonic-gate 		case CODE_RESETREQ:
527*0Sstevel@tonic-gate 		case CODE_RESETACK:
528*0Sstevel@tonic-gate 		default:
529*0Sstevel@tonic-gate 			break;
530*0Sstevel@tonic-gate 		}
531*0Sstevel@tonic-gate 	}
532*0Sstevel@tonic-gate 	return (len);
533*0Sstevel@tonic-gate }
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate 
536*0Sstevel@tonic-gate /*
537*0Sstevel@tonic-gate  * interpret_cp_options() decodes control protocol configuration options.
538*0Sstevel@tonic-gate  * Since each control protocol has a different set of options whose type
539*0Sstevel@tonic-gate  * numbers overlap, the protoinfo parameter is used to get a handle on
540*0Sstevel@tonic-gate  * which option set to use for decoding.
541*0Sstevel@tonic-gate  */
542*0Sstevel@tonic-gate static int
interpret_cp_options(uchar_t * optptr,int len,ppp_protoinfo_t * protoinfo)543*0Sstevel@tonic-gate interpret_cp_options(uchar_t *optptr, int len, ppp_protoinfo_t *protoinfo)
544*0Sstevel@tonic-gate {
545*0Sstevel@tonic-gate 	cp_optinfo_t *optinfo;
546*0Sstevel@tonic-gate 	cp_optinfo_t *optinfo_ptr;
547*0Sstevel@tonic-gate 	uint8_t optlen;
548*0Sstevel@tonic-gate 	uint8_t opttype;
549*0Sstevel@tonic-gate 
550*0Sstevel@tonic-gate 	switch (protoinfo->proto) {
551*0Sstevel@tonic-gate 	case PPP_LCP:
552*0Sstevel@tonic-gate 		optinfo = lcp_optinfo;
553*0Sstevel@tonic-gate 		break;
554*0Sstevel@tonic-gate 	case PPP_IPCP:
555*0Sstevel@tonic-gate 		optinfo = ipcp_optinfo;
556*0Sstevel@tonic-gate 		break;
557*0Sstevel@tonic-gate 	case PPP_IPV6CP:
558*0Sstevel@tonic-gate 		optinfo = ipv6cp_optinfo;
559*0Sstevel@tonic-gate 		break;
560*0Sstevel@tonic-gate 	case PPP_CCP:
561*0Sstevel@tonic-gate 		optinfo = ccp_optinfo;
562*0Sstevel@tonic-gate 		break;
563*0Sstevel@tonic-gate 	case PPP_ECP:
564*0Sstevel@tonic-gate 		optinfo = ecp_optinfo;
565*0Sstevel@tonic-gate 		break;
566*0Sstevel@tonic-gate 	case PPP_MUXCP:
567*0Sstevel@tonic-gate 		optinfo = muxcp_optinfo;
568*0Sstevel@tonic-gate 		break;
569*0Sstevel@tonic-gate 	default:
570*0Sstevel@tonic-gate 		return (len);
571*0Sstevel@tonic-gate 		break;
572*0Sstevel@tonic-gate 	}
573*0Sstevel@tonic-gate 
574*0Sstevel@tonic-gate 	if (len >= 2) {
575*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "%s Configuration Options",
576*0Sstevel@tonic-gate 		    protoinfo->name);
577*0Sstevel@tonic-gate 		show_space();
578*0Sstevel@tonic-gate 	}
579*0Sstevel@tonic-gate 
580*0Sstevel@tonic-gate 	while (len >= 2) {
581*0Sstevel@tonic-gate 		GETINT8(opttype, optptr);
582*0Sstevel@tonic-gate 		GETINT8(optlen, optptr);
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 		optinfo_ptr = ppp_getoptinfo(optinfo, opttype);
585*0Sstevel@tonic-gate 
586*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Option Type = %d (%s)", opttype,
587*0Sstevel@tonic-gate 		    optinfo_ptr->opt_name);
588*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Option Length = %d", optlen);
589*0Sstevel@tonic-gate 
590*0Sstevel@tonic-gate 		/*
591*0Sstevel@tonic-gate 		 * Don't continue if there isn't enough data to
592*0Sstevel@tonic-gate 		 * contain this option, or if this type of option
593*0Sstevel@tonic-gate 		 * should contain more data than the length field
594*0Sstevel@tonic-gate 		 * claims there is.
595*0Sstevel@tonic-gate 		 */
596*0Sstevel@tonic-gate 		if (optlen > len || optlen < optinfo_ptr->opt_minsize) {
597*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0),
598*0Sstevel@tonic-gate 			    "Warning: Incomplete Option");
599*0Sstevel@tonic-gate 			show_space();
600*0Sstevel@tonic-gate 			break;
601*0Sstevel@tonic-gate 		}
602*0Sstevel@tonic-gate 
603*0Sstevel@tonic-gate 		if (optinfo_ptr->opt_formatdata != NULL) {
604*0Sstevel@tonic-gate 			optinfo_ptr->opt_formatdata(optptr,
605*0Sstevel@tonic-gate 			    MIN(optlen - 2, len - 2));
606*0Sstevel@tonic-gate 		}
607*0Sstevel@tonic-gate 
608*0Sstevel@tonic-gate 		len -= optlen;
609*0Sstevel@tonic-gate 		optptr += optlen - 2;
610*0Sstevel@tonic-gate 
611*0Sstevel@tonic-gate 		show_space();
612*0Sstevel@tonic-gate 	}
613*0Sstevel@tonic-gate 
614*0Sstevel@tonic-gate 	return (len);
615*0Sstevel@tonic-gate }
616*0Sstevel@tonic-gate 
617*0Sstevel@tonic-gate static int
interpret_ppp_chap(int flags,uchar_t * data,int len,ppp_protoinfo_t * protoinfo)618*0Sstevel@tonic-gate interpret_ppp_chap(int flags, uchar_t *data, int len,
619*0Sstevel@tonic-gate     ppp_protoinfo_t *protoinfo)
620*0Sstevel@tonic-gate {
621*0Sstevel@tonic-gate 	uint8_t code;
622*0Sstevel@tonic-gate 	uint8_t id;
623*0Sstevel@tonic-gate 	char *codestr;
624*0Sstevel@tonic-gate 	uint16_t length;
625*0Sstevel@tonic-gate 	int lengthleft;
626*0Sstevel@tonic-gate 	uchar_t *datap = data;
627*0Sstevel@tonic-gate 
628*0Sstevel@tonic-gate 
629*0Sstevel@tonic-gate 	if (len < sizeof (ppp_pkt_t))
630*0Sstevel@tonic-gate 		return (len);
631*0Sstevel@tonic-gate 
632*0Sstevel@tonic-gate 	GETINT8(code, datap);
633*0Sstevel@tonic-gate 	GETINT8(id, datap);
634*0Sstevel@tonic-gate 	GETINT8(length, datap);
635*0Sstevel@tonic-gate 
636*0Sstevel@tonic-gate 	if (code <= MAX_CHAPCODE)
637*0Sstevel@tonic-gate 		codestr = chap_codearray[code];
638*0Sstevel@tonic-gate 	else
639*0Sstevel@tonic-gate 		codestr = "";
640*0Sstevel@tonic-gate 
641*0Sstevel@tonic-gate 	if (flags & F_SUM) {
642*0Sstevel@tonic-gate 		(void) sprintf(get_sum_line(),
643*0Sstevel@tonic-gate 		    "%s%s", protoinfo->prefix, codestr);
644*0Sstevel@tonic-gate 	} else { /* (flags & F_DTAIL) */
645*0Sstevel@tonic-gate 		show_header(protoinfo->prefix, protoinfo->description, len);
646*0Sstevel@tonic-gate 		show_space();
647*0Sstevel@tonic-gate 
648*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Code = %d %s", code, codestr);
649*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Identifier = %d", id);
650*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Length = %d", length);
651*0Sstevel@tonic-gate 
652*0Sstevel@tonic-gate 		show_space();
653*0Sstevel@tonic-gate 
654*0Sstevel@tonic-gate 		if (len < length)
655*0Sstevel@tonic-gate 			return (len);
656*0Sstevel@tonic-gate 
657*0Sstevel@tonic-gate 		lengthleft = len - sizeof (ppp_pkt_t);
658*0Sstevel@tonic-gate 
659*0Sstevel@tonic-gate 		switch (code) {
660*0Sstevel@tonic-gate 		case CODE_CHALLENGE:
661*0Sstevel@tonic-gate 		case CODE_RESPONSE: {
662*0Sstevel@tonic-gate 			uint8_t value_size;
663*0Sstevel@tonic-gate 			uint16_t peername_size;
664*0Sstevel@tonic-gate 
665*0Sstevel@tonic-gate 			if (lengthleft < sizeof (value_size))
666*0Sstevel@tonic-gate 				break;
667*0Sstevel@tonic-gate 
668*0Sstevel@tonic-gate 			GETINT8(value_size, datap);
669*0Sstevel@tonic-gate 			lengthleft -= sizeof (value_size);
670*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Value-Size = %d",
671*0Sstevel@tonic-gate 			    value_size);
672*0Sstevel@tonic-gate 
673*0Sstevel@tonic-gate 			if (lengthleft < sizeof (peername_size))
674*0Sstevel@tonic-gate 				break;
675*0Sstevel@tonic-gate 			peername_size = MIN(length - sizeof (ppp_pkt_t) -
676*0Sstevel@tonic-gate 			    value_size, lengthleft);
677*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Name = %.*s",
678*0Sstevel@tonic-gate 			    peername_size, datap + value_size);
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate 			break;
681*0Sstevel@tonic-gate 		}
682*0Sstevel@tonic-gate 		case CODE_SUCCESS:
683*0Sstevel@tonic-gate 		case CODE_FAILURE: {
684*0Sstevel@tonic-gate 			uint16_t message_size = MIN(length - sizeof (ppp_pkt_t),
685*0Sstevel@tonic-gate 			    lengthleft);
686*0Sstevel@tonic-gate 
687*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Message = %.*s",
688*0Sstevel@tonic-gate 			    message_size, datap);
689*0Sstevel@tonic-gate 			break;
690*0Sstevel@tonic-gate 		}
691*0Sstevel@tonic-gate 		default:
692*0Sstevel@tonic-gate 			break;
693*0Sstevel@tonic-gate 		}
694*0Sstevel@tonic-gate 	}
695*0Sstevel@tonic-gate 
696*0Sstevel@tonic-gate 	show_space();
697*0Sstevel@tonic-gate 	len -= length;
698*0Sstevel@tonic-gate 	return (len);
699*0Sstevel@tonic-gate }
700*0Sstevel@tonic-gate 
701*0Sstevel@tonic-gate static int
interpret_ppp_pap(int flags,uchar_t * data,int len,ppp_protoinfo_t * protoinfo)702*0Sstevel@tonic-gate interpret_ppp_pap(int flags, uchar_t *data, int len,
703*0Sstevel@tonic-gate     ppp_protoinfo_t *protoinfo)
704*0Sstevel@tonic-gate {
705*0Sstevel@tonic-gate 	uint8_t code;
706*0Sstevel@tonic-gate 	uint8_t id;
707*0Sstevel@tonic-gate 	char *codestr;
708*0Sstevel@tonic-gate 	uint16_t length;
709*0Sstevel@tonic-gate 	int lengthleft;
710*0Sstevel@tonic-gate 	uchar_t *datap = data;
711*0Sstevel@tonic-gate 
712*0Sstevel@tonic-gate 	if (len < sizeof (ppp_pkt_t))
713*0Sstevel@tonic-gate 		return (len);
714*0Sstevel@tonic-gate 
715*0Sstevel@tonic-gate 	GETINT8(code, datap);
716*0Sstevel@tonic-gate 	GETINT8(id, datap);
717*0Sstevel@tonic-gate 	GETINT16(length, datap);
718*0Sstevel@tonic-gate 
719*0Sstevel@tonic-gate 	lengthleft = len - sizeof (ppp_pkt_t);
720*0Sstevel@tonic-gate 
721*0Sstevel@tonic-gate 	if (code <= MAX_PAPCODE)
722*0Sstevel@tonic-gate 		codestr = pap_codearray[code];
723*0Sstevel@tonic-gate 	else
724*0Sstevel@tonic-gate 		codestr = "";
725*0Sstevel@tonic-gate 
726*0Sstevel@tonic-gate 	if (flags & F_SUM) {
727*0Sstevel@tonic-gate 		(void) sprintf(get_sum_line(),
728*0Sstevel@tonic-gate 		    "%s%s", protoinfo->prefix, codestr);
729*0Sstevel@tonic-gate 	} else { /* (flags & F_DTAIL) */
730*0Sstevel@tonic-gate 		show_header(protoinfo->prefix, protoinfo->description, len);
731*0Sstevel@tonic-gate 		show_space();
732*0Sstevel@tonic-gate 
733*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Code = %d %s", code, codestr);
734*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Identifier = %d", id);
735*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Length = %d", length);
736*0Sstevel@tonic-gate 
737*0Sstevel@tonic-gate 		show_space();
738*0Sstevel@tonic-gate 
739*0Sstevel@tonic-gate 		if (len < length)
740*0Sstevel@tonic-gate 			return (len);
741*0Sstevel@tonic-gate 
742*0Sstevel@tonic-gate 		switch (code) {
743*0Sstevel@tonic-gate 		case CODE_AUTHREQ: {
744*0Sstevel@tonic-gate 			uint8_t fieldlen;
745*0Sstevel@tonic-gate 
746*0Sstevel@tonic-gate 			if (lengthleft < sizeof (fieldlen))
747*0Sstevel@tonic-gate 				break;
748*0Sstevel@tonic-gate 			GETINT8(fieldlen, datap);
749*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Peer-Id Length = %d",
750*0Sstevel@tonic-gate 			    fieldlen);
751*0Sstevel@tonic-gate 			lengthleft -= sizeof (fieldlen);
752*0Sstevel@tonic-gate 
753*0Sstevel@tonic-gate 			if (lengthleft < fieldlen)
754*0Sstevel@tonic-gate 				break;
755*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Peer-Id = %.*s",
756*0Sstevel@tonic-gate 			    fieldlen, datap);
757*0Sstevel@tonic-gate 			lengthleft -= fieldlen;
758*0Sstevel@tonic-gate 
759*0Sstevel@tonic-gate 			datap += fieldlen;
760*0Sstevel@tonic-gate 
761*0Sstevel@tonic-gate 			if (lengthleft < sizeof (fieldlen))
762*0Sstevel@tonic-gate 				break;
763*0Sstevel@tonic-gate 			GETINT8(fieldlen, datap);
764*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Password Length = %d",
765*0Sstevel@tonic-gate 			    fieldlen);
766*0Sstevel@tonic-gate 			lengthleft -= sizeof (fieldlen);
767*0Sstevel@tonic-gate 
768*0Sstevel@tonic-gate 			if (lengthleft < fieldlen)
769*0Sstevel@tonic-gate 				break;
770*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Password = %.*s",
771*0Sstevel@tonic-gate 			    fieldlen, datap);
772*0Sstevel@tonic-gate 
773*0Sstevel@tonic-gate 			break;
774*0Sstevel@tonic-gate 		}
775*0Sstevel@tonic-gate 		case CODE_AUTHACK:
776*0Sstevel@tonic-gate 		case CODE_AUTHNAK: {
777*0Sstevel@tonic-gate 			uint8_t msglen;
778*0Sstevel@tonic-gate 
779*0Sstevel@tonic-gate 			if (lengthleft < sizeof (msglen))
780*0Sstevel@tonic-gate 				break;
781*0Sstevel@tonic-gate 			GETINT8(msglen, datap);
782*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Msg-Length = %d",
783*0Sstevel@tonic-gate 			    msglen);
784*0Sstevel@tonic-gate 			lengthleft -= sizeof (msglen);
785*0Sstevel@tonic-gate 
786*0Sstevel@tonic-gate 			if (lengthleft < msglen)
787*0Sstevel@tonic-gate 				break;
788*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Message = %.*s",
789*0Sstevel@tonic-gate 			    msglen, datap);
790*0Sstevel@tonic-gate 
791*0Sstevel@tonic-gate 			break;
792*0Sstevel@tonic-gate 		}
793*0Sstevel@tonic-gate 		default:
794*0Sstevel@tonic-gate 			break;
795*0Sstevel@tonic-gate 		}
796*0Sstevel@tonic-gate 	}
797*0Sstevel@tonic-gate 
798*0Sstevel@tonic-gate 	show_space();
799*0Sstevel@tonic-gate 	len -= length;
800*0Sstevel@tonic-gate 	return (len);
801*0Sstevel@tonic-gate }
802*0Sstevel@tonic-gate 
803*0Sstevel@tonic-gate 
804*0Sstevel@tonic-gate static int
interpret_ppp_lqr(int flags,uchar_t * data,int len,ppp_protoinfo_t * protoinfo)805*0Sstevel@tonic-gate interpret_ppp_lqr(int flags, uchar_t *data, int len,
806*0Sstevel@tonic-gate     ppp_protoinfo_t *protoinfo)
807*0Sstevel@tonic-gate {
808*0Sstevel@tonic-gate 	lqr_pkt_t lqr_pkt;
809*0Sstevel@tonic-gate 	if (len < sizeof (lqr_pkt_t))
810*0Sstevel@tonic-gate 		return (len);
811*0Sstevel@tonic-gate 
812*0Sstevel@tonic-gate 	(void) memcpy(&lqr_pkt, data, sizeof (lqr_pkt_t));
813*0Sstevel@tonic-gate 
814*0Sstevel@tonic-gate 	if (flags & F_SUM) {
815*0Sstevel@tonic-gate 		(void) sprintf(get_sum_line(), protoinfo->prefix);
816*0Sstevel@tonic-gate 	} else { /* (flags & F_DTAIL) */
817*0Sstevel@tonic-gate 		show_header(protoinfo->prefix, protoinfo->description, len);
818*0Sstevel@tonic-gate 		show_space();
819*0Sstevel@tonic-gate 
820*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Magic-Number =   0x%08x",
821*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_magic));
822*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "LastOutLQRs =    %d",
823*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_lastoutlqrs));
824*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "LastOutPackets = %d",
825*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_lastoutpackets));
826*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "LastOutOctets =  %d",
827*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_lastoutoctets));
828*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerInLQRs =     %d",
829*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peerinlqrs));
830*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerInPackets =  %d",
831*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peerinpackets));
832*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerInDiscards = %d",
833*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peerindiscards));
834*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerInErrors =   %d",
835*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peerinerrors));
836*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerInOctets =   %d",
837*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peerinoctets));
838*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerOutLQRs =    %d",
839*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peeroutlqrs));
840*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerOutPackets = %d",
841*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peeroutpackets));
842*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "PeerOutOctets =  %d",
843*0Sstevel@tonic-gate 		    ntohl(lqr_pkt.lqr_peeroutoctets));
844*0Sstevel@tonic-gate 
845*0Sstevel@tonic-gate 		show_space();
846*0Sstevel@tonic-gate 	}
847*0Sstevel@tonic-gate 
848*0Sstevel@tonic-gate 	len -= sizeof (lqr_pkt_t);
849*0Sstevel@tonic-gate 	return (len);
850*0Sstevel@tonic-gate }
851*0Sstevel@tonic-gate 
852*0Sstevel@tonic-gate static ppp_protoinfo_t *
ppp_getprotoinfo(uint16_t proto)853*0Sstevel@tonic-gate ppp_getprotoinfo(uint16_t proto)
854*0Sstevel@tonic-gate {
855*0Sstevel@tonic-gate 	ppp_protoinfo_t *protoinfo_ptr = &protoinfo_array[0];
856*0Sstevel@tonic-gate 
857*0Sstevel@tonic-gate 	while (protoinfo_ptr->proto != proto && protoinfo_ptr->proto != 0) {
858*0Sstevel@tonic-gate 		protoinfo_ptr++;
859*0Sstevel@tonic-gate 	}
860*0Sstevel@tonic-gate 
861*0Sstevel@tonic-gate 	return (protoinfo_ptr);
862*0Sstevel@tonic-gate }
863*0Sstevel@tonic-gate 
864*0Sstevel@tonic-gate 
865*0Sstevel@tonic-gate static cp_optinfo_t *
ppp_getoptinfo(cp_optinfo_t optinfo_list[],uint16_t opt_type)866*0Sstevel@tonic-gate ppp_getoptinfo(cp_optinfo_t optinfo_list[], uint16_t opt_type)
867*0Sstevel@tonic-gate {
868*0Sstevel@tonic-gate 	cp_optinfo_t *optinfo_ptr = &optinfo_list[0];
869*0Sstevel@tonic-gate 
870*0Sstevel@tonic-gate 	while (optinfo_ptr->opt_type != opt_type &&
871*0Sstevel@tonic-gate 	    optinfo_ptr->opt_name != unknown_string) {
872*0Sstevel@tonic-gate 		optinfo_ptr++;
873*0Sstevel@tonic-gate 	}
874*0Sstevel@tonic-gate 
875*0Sstevel@tonic-gate 	return (optinfo_ptr);
876*0Sstevel@tonic-gate }
877*0Sstevel@tonic-gate 
878*0Sstevel@tonic-gate 
879*0Sstevel@tonic-gate /*
880*0Sstevel@tonic-gate  * Below are the functions which parse control protocol configuration
881*0Sstevel@tonic-gate  * options.  The first argument to these functions (optdata) points to the
882*0Sstevel@tonic-gate  * first byte of the option after the length field.  The second argument
883*0Sstevel@tonic-gate  * (size) is the number of bytes in the option after the length field
884*0Sstevel@tonic-gate  * (length - 2).
885*0Sstevel@tonic-gate  */
886*0Sstevel@tonic-gate 
887*0Sstevel@tonic-gate /*
888*0Sstevel@tonic-gate  * The format of the Vendor-Specific option (rfc2153) is:
889*0Sstevel@tonic-gate  *
890*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
891*0Sstevel@tonic-gate  * |     Type      |    Length     |              OUI
892*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
893*0Sstevel@tonic-gate  *        ...      |     Kind      |  Value(s) ...
894*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
895*0Sstevel@tonic-gate  */
896*0Sstevel@tonic-gate /*ARGSUSED1*/
897*0Sstevel@tonic-gate static void
opt_format_vendor(uchar_t * optdata,uint8_t size)898*0Sstevel@tonic-gate opt_format_vendor(uchar_t *optdata, uint8_t size)
899*0Sstevel@tonic-gate {
900*0Sstevel@tonic-gate 	uint32_t oui;
901*0Sstevel@tonic-gate 	char *ouistr;
902*0Sstevel@tonic-gate 	uint8_t kind;
903*0Sstevel@tonic-gate 
904*0Sstevel@tonic-gate 	GETINT32(oui, optdata);
905*0Sstevel@tonic-gate 	kind = oui & 0x000000ff;
906*0Sstevel@tonic-gate 	oui >>= 8;
907*0Sstevel@tonic-gate 
908*0Sstevel@tonic-gate 	ouistr = ether_ouiname(oui);
909*0Sstevel@tonic-gate 	if (ouistr == NULL)
910*0Sstevel@tonic-gate 		ouistr = unknown_string;
911*0Sstevel@tonic-gate 
912*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "OUI = 0x%06x (%s)", oui, ouistr);
913*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Kind = %d", kind);
914*0Sstevel@tonic-gate }
915*0Sstevel@tonic-gate 
916*0Sstevel@tonic-gate /*
917*0Sstevel@tonic-gate  * The format of the MRU option (rfc1661) is:
918*0Sstevel@tonic-gate  *
919*0Sstevel@tonic-gate  *  0                   1                   2                   3
920*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
921*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
922*0Sstevel@tonic-gate  * |     Type      |    Length     |      Maximum-Receive-Unit     |
923*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
924*0Sstevel@tonic-gate  */
925*0Sstevel@tonic-gate /*ARGSUSED1*/
926*0Sstevel@tonic-gate static void
opt_format_mru(uchar_t * optdata,uint8_t size)927*0Sstevel@tonic-gate opt_format_mru(uchar_t *optdata, uint8_t size)
928*0Sstevel@tonic-gate {
929*0Sstevel@tonic-gate 	uint16_t mru;
930*0Sstevel@tonic-gate 
931*0Sstevel@tonic-gate 	GETINT16(mru, optdata);
932*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "MRU = %d", mru);
933*0Sstevel@tonic-gate }
934*0Sstevel@tonic-gate 
935*0Sstevel@tonic-gate /*
936*0Sstevel@tonic-gate  * The format of the accm option (rfc1662) is:
937*0Sstevel@tonic-gate  *
938*0Sstevel@tonic-gate  *  0                   1                   2                   3
939*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
940*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
941*0Sstevel@tonic-gate  * |     Type      |    Length     |               ACCM
942*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
943*0Sstevel@tonic-gate  *           ACCM (cont)           |
944*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
945*0Sstevel@tonic-gate  */
946*0Sstevel@tonic-gate /*ARGSUSED1*/
947*0Sstevel@tonic-gate static void
opt_format_accm(uchar_t * optdata,uint8_t size)948*0Sstevel@tonic-gate opt_format_accm(uchar_t *optdata, uint8_t size)
949*0Sstevel@tonic-gate {
950*0Sstevel@tonic-gate 	uint32_t accm;
951*0Sstevel@tonic-gate 
952*0Sstevel@tonic-gate 	GETINT32(accm, optdata);
953*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "ACCM = 0x%08x", accm);
954*0Sstevel@tonic-gate }
955*0Sstevel@tonic-gate 
956*0Sstevel@tonic-gate /*
957*0Sstevel@tonic-gate  * The format of the Authentication-Protocol option (rfc1661) is:
958*0Sstevel@tonic-gate  *
959*0Sstevel@tonic-gate  *  0                   1                   2                   3
960*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
961*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
962*0Sstevel@tonic-gate  * |     Type      |    Length     |     Authentication-Protocol   |
963*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
964*0Sstevel@tonic-gate  * |    Data ...
965*0Sstevel@tonic-gate  * +-+-+-+-+
966*0Sstevel@tonic-gate  *
967*0Sstevel@tonic-gate  * For PAP (rfc1334), there is no data.  For CHAP (rfc1994), there is one
968*0Sstevel@tonic-gate  * byte of data representing the algorithm.
969*0Sstevel@tonic-gate  */
970*0Sstevel@tonic-gate static void
opt_format_authproto(uchar_t * optdata,uint8_t size)971*0Sstevel@tonic-gate opt_format_authproto(uchar_t *optdata, uint8_t size)
972*0Sstevel@tonic-gate {
973*0Sstevel@tonic-gate 	uint16_t proto;
974*0Sstevel@tonic-gate 	ppp_protoinfo_t *auth_protoinfo;
975*0Sstevel@tonic-gate 
976*0Sstevel@tonic-gate 	GETINT16(proto, optdata);
977*0Sstevel@tonic-gate 
978*0Sstevel@tonic-gate 	auth_protoinfo = ppp_getprotoinfo(proto);
979*0Sstevel@tonic-gate 
980*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Protocol = 0x%x (%s)", proto,
981*0Sstevel@tonic-gate 	    auth_protoinfo->name);
982*0Sstevel@tonic-gate 
983*0Sstevel@tonic-gate 	switch (proto) {
984*0Sstevel@tonic-gate 	case PPP_CHAP: {
985*0Sstevel@tonic-gate 		uint8_t algo;
986*0Sstevel@tonic-gate 		char *algostr;
987*0Sstevel@tonic-gate 
988*0Sstevel@tonic-gate 		if (size < sizeof (proto) + sizeof (algo))
989*0Sstevel@tonic-gate 			return;
990*0Sstevel@tonic-gate 
991*0Sstevel@tonic-gate 		GETINT8(algo, optdata);
992*0Sstevel@tonic-gate 		switch (algo) {
993*0Sstevel@tonic-gate 		case 5:
994*0Sstevel@tonic-gate 			algostr = "CHAP with MD5";
995*0Sstevel@tonic-gate 			break;
996*0Sstevel@tonic-gate 		case 128:
997*0Sstevel@tonic-gate 			algostr = "MS-CHAP";
998*0Sstevel@tonic-gate 			break;
999*0Sstevel@tonic-gate 		case 129:
1000*0Sstevel@tonic-gate 			algostr = "MS-CHAP-2";
1001*0Sstevel@tonic-gate 			break;
1002*0Sstevel@tonic-gate 		default:
1003*0Sstevel@tonic-gate 			algostr = unknown_string;
1004*0Sstevel@tonic-gate 			break;
1005*0Sstevel@tonic-gate 		}
1006*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Algorithm = %d (%s)", algo,
1007*0Sstevel@tonic-gate 		    algostr);
1008*0Sstevel@tonic-gate 		break;
1009*0Sstevel@tonic-gate 	}
1010*0Sstevel@tonic-gate 	default:
1011*0Sstevel@tonic-gate 		break;
1012*0Sstevel@tonic-gate 	}
1013*0Sstevel@tonic-gate }
1014*0Sstevel@tonic-gate 
1015*0Sstevel@tonic-gate /*
1016*0Sstevel@tonic-gate  * The format of the Quality Protocol option (rfc1661) is:
1017*0Sstevel@tonic-gate  *
1018*0Sstevel@tonic-gate  *  0                   1                   2                   3
1019*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1020*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1021*0Sstevel@tonic-gate  * |     Type      |    Length     |        Quality-Protocol       |
1022*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1023*0Sstevel@tonic-gate  * |    Data ...
1024*0Sstevel@tonic-gate  * +-+-+-+-+
1025*0Sstevel@tonic-gate  *
1026*0Sstevel@tonic-gate  * For LQR, the data consists of a 4 byte reporting period.
1027*0Sstevel@tonic-gate  */
1028*0Sstevel@tonic-gate static void
opt_format_qualproto(uchar_t * optdata,uint8_t size)1029*0Sstevel@tonic-gate opt_format_qualproto(uchar_t *optdata, uint8_t size)
1030*0Sstevel@tonic-gate {
1031*0Sstevel@tonic-gate 	uint16_t proto;
1032*0Sstevel@tonic-gate 	ppp_protoinfo_t *qual_protoinfo;
1033*0Sstevel@tonic-gate 
1034*0Sstevel@tonic-gate 	GETINT16(proto, optdata);
1035*0Sstevel@tonic-gate 
1036*0Sstevel@tonic-gate 	qual_protoinfo = ppp_getprotoinfo(proto);
1037*0Sstevel@tonic-gate 
1038*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Protocol = 0x%x (%s)", proto,
1039*0Sstevel@tonic-gate 	    qual_protoinfo->name);
1040*0Sstevel@tonic-gate 
1041*0Sstevel@tonic-gate 	switch (proto) {
1042*0Sstevel@tonic-gate 	case PPP_LQR: {
1043*0Sstevel@tonic-gate 		uint32_t reporting_period;
1044*0Sstevel@tonic-gate 
1045*0Sstevel@tonic-gate 		if (size < sizeof (proto) + sizeof (reporting_period))
1046*0Sstevel@tonic-gate 			return;
1047*0Sstevel@tonic-gate 
1048*0Sstevel@tonic-gate 		GETINT32(reporting_period, optdata);
1049*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Reporting-Period = %d",
1050*0Sstevel@tonic-gate 		    reporting_period);
1051*0Sstevel@tonic-gate 		break;
1052*0Sstevel@tonic-gate 	}
1053*0Sstevel@tonic-gate 	default:
1054*0Sstevel@tonic-gate 		break;
1055*0Sstevel@tonic-gate 	}
1056*0Sstevel@tonic-gate }
1057*0Sstevel@tonic-gate 
1058*0Sstevel@tonic-gate /*
1059*0Sstevel@tonic-gate  * The format of the Magic Number option (rfc1661) is:
1060*0Sstevel@tonic-gate  *
1061*0Sstevel@tonic-gate  *  0                   1                   2                   3
1062*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1063*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1064*0Sstevel@tonic-gate  * |     Type      |    Length     |          Magic-Number
1065*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1066*0Sstevel@tonic-gate  *       Magic-Number (cont)       |
1067*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1068*0Sstevel@tonic-gate  */
1069*0Sstevel@tonic-gate /*ARGSUSED1*/
1070*0Sstevel@tonic-gate static void
opt_format_magicnum(uchar_t * optdata,uint8_t size)1071*0Sstevel@tonic-gate opt_format_magicnum(uchar_t *optdata, uint8_t size)
1072*0Sstevel@tonic-gate {
1073*0Sstevel@tonic-gate 	uint32_t magicnum;
1074*0Sstevel@tonic-gate 
1075*0Sstevel@tonic-gate 	GETINT32(magicnum, optdata);
1076*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Magic Number = 0x%08x", magicnum);
1077*0Sstevel@tonic-gate }
1078*0Sstevel@tonic-gate 
1079*0Sstevel@tonic-gate /*
1080*0Sstevel@tonic-gate  * The format of the FCS-Alternatives option (rfc1570) is:
1081*0Sstevel@tonic-gate  *
1082*0Sstevel@tonic-gate  *  0                   1                   2
1083*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
1084*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1085*0Sstevel@tonic-gate  * |     Type      |    Length     |    Options    |
1086*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1087*0Sstevel@tonic-gate  */
1088*0Sstevel@tonic-gate /*ARGSUSED1*/
1089*0Sstevel@tonic-gate static void
opt_format_fcs(uchar_t * optdata,uint8_t size)1090*0Sstevel@tonic-gate opt_format_fcs(uchar_t *optdata, uint8_t size)
1091*0Sstevel@tonic-gate {
1092*0Sstevel@tonic-gate 	uint8_t options;
1093*0Sstevel@tonic-gate 
1094*0Sstevel@tonic-gate 	GETINT8(options, optdata);
1095*0Sstevel@tonic-gate 
1096*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Options = 0x%02x", options);
1097*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "     %s",
1098*0Sstevel@tonic-gate 	    getflag(options, 0x01, "NULL FCS", ""));
1099*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "     %s",
1100*0Sstevel@tonic-gate 	    getflag(options, 0x02, "CCITT 16-bit FCS", ""));
1101*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "     %s",
1102*0Sstevel@tonic-gate 	    getflag(options, 0x04, "CCITT 32-bit FCS", ""));
1103*0Sstevel@tonic-gate }
1104*0Sstevel@tonic-gate 
1105*0Sstevel@tonic-gate /*
1106*0Sstevel@tonic-gate  * The format of the Self-Describing-Padding option (rfc1570) is:
1107*0Sstevel@tonic-gate  *
1108*0Sstevel@tonic-gate  *  0                   1                   2
1109*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
1110*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1111*0Sstevel@tonic-gate  * |     Type      |    Length     |    Maximum    |
1112*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1113*0Sstevel@tonic-gate  */
1114*0Sstevel@tonic-gate /*ARGSUSED1*/
1115*0Sstevel@tonic-gate static void
opt_format_sdp(uchar_t * optdata,uint8_t size)1116*0Sstevel@tonic-gate opt_format_sdp(uchar_t *optdata, uint8_t size)
1117*0Sstevel@tonic-gate {
1118*0Sstevel@tonic-gate 	uint8_t max;
1119*0Sstevel@tonic-gate 
1120*0Sstevel@tonic-gate 	GETINT8(max, optdata);
1121*0Sstevel@tonic-gate 
1122*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Maximum = %d", max);
1123*0Sstevel@tonic-gate }
1124*0Sstevel@tonic-gate 
1125*0Sstevel@tonic-gate /*
1126*0Sstevel@tonic-gate  * The format of the Numbered-Mode option (rfc1663) is:
1127*0Sstevel@tonic-gate  *
1128*0Sstevel@tonic-gate  *  0                   1                   2                   3
1129*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1130*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1131*0Sstevel@tonic-gate  * |     Type      |     Length    |    Window     |   Address...
1132*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1133*0Sstevel@tonic-gate  */
1134*0Sstevel@tonic-gate /*ARGSUSED1*/
1135*0Sstevel@tonic-gate static void
opt_format_nummode(uchar_t * optdata,uint8_t size)1136*0Sstevel@tonic-gate opt_format_nummode(uchar_t *optdata, uint8_t size)
1137*0Sstevel@tonic-gate {
1138*0Sstevel@tonic-gate 	uint8_t window;
1139*0Sstevel@tonic-gate 
1140*0Sstevel@tonic-gate 	GETINT8(window, optdata);
1141*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Window = %d", window);
1142*0Sstevel@tonic-gate }
1143*0Sstevel@tonic-gate 
1144*0Sstevel@tonic-gate /*
1145*0Sstevel@tonic-gate  * The format of the Callback option (rfc1570) is:
1146*0Sstevel@tonic-gate  *
1147*0Sstevel@tonic-gate  *  0                   1                   2                   3
1148*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1149*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1150*0Sstevel@tonic-gate  * |     Type      |    Length     |   Operation   |  Message ...
1151*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1152*0Sstevel@tonic-gate  */
1153*0Sstevel@tonic-gate static void
opt_format_callback(uchar_t * optdata,uint8_t size)1154*0Sstevel@tonic-gate opt_format_callback(uchar_t *optdata, uint8_t size)
1155*0Sstevel@tonic-gate {
1156*0Sstevel@tonic-gate 	uint8_t operation;
1157*0Sstevel@tonic-gate 	char *opstr;
1158*0Sstevel@tonic-gate 
1159*0Sstevel@tonic-gate 	GETINT8(operation, optdata);
1160*0Sstevel@tonic-gate 	switch (operation) {
1161*0Sstevel@tonic-gate 	case 0:
1162*0Sstevel@tonic-gate 		opstr = "User Authentication";
1163*0Sstevel@tonic-gate 		break;
1164*0Sstevel@tonic-gate 	case 1:
1165*0Sstevel@tonic-gate 		opstr = "Dialing String";
1166*0Sstevel@tonic-gate 		break;
1167*0Sstevel@tonic-gate 	case 2:
1168*0Sstevel@tonic-gate 		opstr = "Location Identifier";
1169*0Sstevel@tonic-gate 		break;
1170*0Sstevel@tonic-gate 	case 3:
1171*0Sstevel@tonic-gate 		opstr = "E.164 Number";
1172*0Sstevel@tonic-gate 		break;
1173*0Sstevel@tonic-gate 	case 4:
1174*0Sstevel@tonic-gate 		opstr = "X.500 Distinguished Name";
1175*0Sstevel@tonic-gate 		break;
1176*0Sstevel@tonic-gate 	case 6:
1177*0Sstevel@tonic-gate 		opstr = "CBCP Negotiation";
1178*0Sstevel@tonic-gate 		break;
1179*0Sstevel@tonic-gate 	default:
1180*0Sstevel@tonic-gate 		opstr = unknown_string;
1181*0Sstevel@tonic-gate 		break;
1182*0Sstevel@tonic-gate 	}
1183*0Sstevel@tonic-gate 
1184*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Operation = %d (%s)", operation, opstr);
1185*0Sstevel@tonic-gate 
1186*0Sstevel@tonic-gate 	if (size > sizeof (operation)) {
1187*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Message = %.*s",
1188*0Sstevel@tonic-gate 		    size - sizeof (operation), optdata);
1189*0Sstevel@tonic-gate 	}
1190*0Sstevel@tonic-gate }
1191*0Sstevel@tonic-gate 
1192*0Sstevel@tonic-gate /*
1193*0Sstevel@tonic-gate  * The format of the Multilink-MRRU option (rfc1990) is:
1194*0Sstevel@tonic-gate  *
1195*0Sstevel@tonic-gate  *  0                   1                   2                   3
1196*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1197*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1198*0Sstevel@tonic-gate  * |   Type = 17   |   Length = 4  | Max-Receive-Reconstructed-Unit|
1199*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1200*0Sstevel@tonic-gate  */
1201*0Sstevel@tonic-gate /*ARGSUSED1*/
1202*0Sstevel@tonic-gate static void
opt_format_mrru(uchar_t * optdata,uint8_t size)1203*0Sstevel@tonic-gate opt_format_mrru(uchar_t *optdata, uint8_t size)
1204*0Sstevel@tonic-gate {
1205*0Sstevel@tonic-gate 	uint16_t mrru;
1206*0Sstevel@tonic-gate 
1207*0Sstevel@tonic-gate 	GETINT16(mrru, optdata);
1208*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "MRRU = %d", mrru);
1209*0Sstevel@tonic-gate }
1210*0Sstevel@tonic-gate 
1211*0Sstevel@tonic-gate /*
1212*0Sstevel@tonic-gate  * The format of the Endpoint Discriminator option (rfc1990) is:
1213*0Sstevel@tonic-gate  *
1214*0Sstevel@tonic-gate  *  0                   1                   2                   3
1215*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1216*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1217*0Sstevel@tonic-gate  * |   Type = 19   |     Length    |    Class      |  Address ...
1218*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1219*0Sstevel@tonic-gate  */
1220*0Sstevel@tonic-gate static void
opt_format_epdisc(uchar_t * optdata,uint8_t size)1221*0Sstevel@tonic-gate opt_format_epdisc(uchar_t *optdata, uint8_t size)
1222*0Sstevel@tonic-gate {
1223*0Sstevel@tonic-gate 	uint8_t class;
1224*0Sstevel@tonic-gate 	char *classstr;
1225*0Sstevel@tonic-gate 	uint8_t addrlen = size - sizeof (class);
1226*0Sstevel@tonic-gate 	char *addr;
1227*0Sstevel@tonic-gate 
1228*0Sstevel@tonic-gate 	GETINT8(class, optdata);
1229*0Sstevel@tonic-gate 
1230*0Sstevel@tonic-gate 	switch (class) {
1231*0Sstevel@tonic-gate 	case 0:
1232*0Sstevel@tonic-gate 		classstr = "Null Class";
1233*0Sstevel@tonic-gate 		break;
1234*0Sstevel@tonic-gate 	case 1:
1235*0Sstevel@tonic-gate 		classstr = "Locally Assigned Address";
1236*0Sstevel@tonic-gate 		break;
1237*0Sstevel@tonic-gate 	case 2:
1238*0Sstevel@tonic-gate 		classstr = "IPv4 Address";
1239*0Sstevel@tonic-gate 		break;
1240*0Sstevel@tonic-gate 	case 3:
1241*0Sstevel@tonic-gate 		classstr = "IEE 802.1 Global MAC Address";
1242*0Sstevel@tonic-gate 		break;
1243*0Sstevel@tonic-gate 	case 4:
1244*0Sstevel@tonic-gate 		classstr = "PPP Magic-Number Block";
1245*0Sstevel@tonic-gate 		break;
1246*0Sstevel@tonic-gate 	case 5:
1247*0Sstevel@tonic-gate 		classstr = "Public Switched Network Directory Number";
1248*0Sstevel@tonic-gate 		break;
1249*0Sstevel@tonic-gate 	default:
1250*0Sstevel@tonic-gate 		classstr = unknown_string;
1251*0Sstevel@tonic-gate 		break;
1252*0Sstevel@tonic-gate 	}
1253*0Sstevel@tonic-gate 
1254*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Address Class = %d (%s)", class,
1255*0Sstevel@tonic-gate 	    classstr);
1256*0Sstevel@tonic-gate 
1257*0Sstevel@tonic-gate 	if (addrlen == 0)
1258*0Sstevel@tonic-gate 		return;
1259*0Sstevel@tonic-gate 
1260*0Sstevel@tonic-gate 	addr = (char *)malloc(addrlen);
1261*0Sstevel@tonic-gate 	(void) memcpy(addr, optdata, addrlen);
1262*0Sstevel@tonic-gate 	switch (class) {
1263*0Sstevel@tonic-gate 	case 2: {
1264*0Sstevel@tonic-gate 		char addrstr[INET_ADDRSTRLEN];
1265*0Sstevel@tonic-gate 
1266*0Sstevel@tonic-gate 		if (addrlen != sizeof (in_addr_t))
1267*0Sstevel@tonic-gate 			break;
1268*0Sstevel@tonic-gate 		if (inet_ntop(AF_INET, addr, addrstr, INET_ADDRSTRLEN) !=
1269*0Sstevel@tonic-gate 		    NULL) {
1270*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Address = %s", addrstr);
1271*0Sstevel@tonic-gate 		}
1272*0Sstevel@tonic-gate 		break;
1273*0Sstevel@tonic-gate 	}
1274*0Sstevel@tonic-gate 	case 3: {
1275*0Sstevel@tonic-gate 		char *addrstr;
1276*0Sstevel@tonic-gate 
1277*0Sstevel@tonic-gate 		if (addrlen != sizeof (struct ether_addr))
1278*0Sstevel@tonic-gate 			break;
1279*0Sstevel@tonic-gate 		if ((addrstr = ether_ntoa((struct ether_addr *)addr)) != NULL) {
1280*0Sstevel@tonic-gate 			(void) sprintf(get_line(0, 0), "Address = %s", addrstr);
1281*0Sstevel@tonic-gate 		}
1282*0Sstevel@tonic-gate 		break;
1283*0Sstevel@tonic-gate 	}
1284*0Sstevel@tonic-gate 	case 5: {
1285*0Sstevel@tonic-gate 		/*
1286*0Sstevel@tonic-gate 		 * For this case, the address is supposed to be a plain
1287*0Sstevel@tonic-gate 		 * text telephone number.
1288*0Sstevel@tonic-gate 		 */
1289*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Address = %.*s", addrlen,
1290*0Sstevel@tonic-gate 		    addr);
1291*0Sstevel@tonic-gate 	}
1292*0Sstevel@tonic-gate 	default:
1293*0Sstevel@tonic-gate 		break;
1294*0Sstevel@tonic-gate 	}
1295*0Sstevel@tonic-gate 
1296*0Sstevel@tonic-gate 	free(addr);
1297*0Sstevel@tonic-gate }
1298*0Sstevel@tonic-gate 
1299*0Sstevel@tonic-gate /*
1300*0Sstevel@tonic-gate  * The DCE identifier option has the following format (from rfc1976):
1301*0Sstevel@tonic-gate  *
1302*0Sstevel@tonic-gate  *     0                   1                   2
1303*0Sstevel@tonic-gate  *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
1304*0Sstevel@tonic-gate  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1305*0Sstevel@tonic-gate  *    |     Type      |    Length     |      Mode     |
1306*0Sstevel@tonic-gate  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1307*0Sstevel@tonic-gate  */
1308*0Sstevel@tonic-gate /*ARGSUSED1*/
1309*0Sstevel@tonic-gate static void
opt_format_dce(uchar_t * optdata,uint8_t size)1310*0Sstevel@tonic-gate opt_format_dce(uchar_t *optdata, uint8_t size)
1311*0Sstevel@tonic-gate {
1312*0Sstevel@tonic-gate 	uint8_t mode;
1313*0Sstevel@tonic-gate 	char *modestr;
1314*0Sstevel@tonic-gate 
1315*0Sstevel@tonic-gate 	GETINT8(mode, optdata);
1316*0Sstevel@tonic-gate 	switch (mode) {
1317*0Sstevel@tonic-gate 	case 1:
1318*0Sstevel@tonic-gate 		modestr = "No Additional Negotiation";
1319*0Sstevel@tonic-gate 		break;
1320*0Sstevel@tonic-gate 	case 2:
1321*0Sstevel@tonic-gate 		modestr = "Full PPP Negotiation and State Machine";
1322*0Sstevel@tonic-gate 		break;
1323*0Sstevel@tonic-gate 	default:
1324*0Sstevel@tonic-gate 		modestr = unknown_string;
1325*0Sstevel@tonic-gate 		break;
1326*0Sstevel@tonic-gate 	}
1327*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Mode = %d (%s)", mode, modestr);
1328*0Sstevel@tonic-gate }
1329*0Sstevel@tonic-gate 
1330*0Sstevel@tonic-gate /*
1331*0Sstevel@tonic-gate  * The format of the Link Discriminator option (rfc2125) is:
1332*0Sstevel@tonic-gate  *
1333*0Sstevel@tonic-gate  *  0                   1                   2                   3
1334*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1335*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1336*0Sstevel@tonic-gate  * |     Type      |     Length    |       Link Discriminator      |
1337*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1338*0Sstevel@tonic-gate  */
1339*0Sstevel@tonic-gate /*ARGSUSED1*/
1340*0Sstevel@tonic-gate static void
opt_format_linkdisc(uchar_t * optdata,uint8_t size)1341*0Sstevel@tonic-gate opt_format_linkdisc(uchar_t *optdata, uint8_t size)
1342*0Sstevel@tonic-gate {
1343*0Sstevel@tonic-gate 	uint16_t discrim;
1344*0Sstevel@tonic-gate 
1345*0Sstevel@tonic-gate 	GETINT16(discrim, optdata);
1346*0Sstevel@tonic-gate 
1347*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Link Discriminator = %d", discrim);
1348*0Sstevel@tonic-gate }
1349*0Sstevel@tonic-gate 
1350*0Sstevel@tonic-gate 
1351*0Sstevel@tonic-gate /*
1352*0Sstevel@tonic-gate  * The format of the Internationalization option (rfc2484) is:
1353*0Sstevel@tonic-gate  *
1354*0Sstevel@tonic-gate  *  0                   1                   2                   3
1355*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1356*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1357*0Sstevel@tonic-gate  * |     Type      |    Length     |          MIBenum
1358*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1359*0Sstevel@tonic-gate  *           MIBenum (cont)        |        Language-Tag...
1360*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1361*0Sstevel@tonic-gate  */
1362*0Sstevel@tonic-gate static void
opt_format_i18n(uchar_t * optdata,uint8_t size)1363*0Sstevel@tonic-gate opt_format_i18n(uchar_t *optdata, uint8_t size)
1364*0Sstevel@tonic-gate {
1365*0Sstevel@tonic-gate 	uint32_t mibenum;
1366*0Sstevel@tonic-gate 	uint8_t taglen;
1367*0Sstevel@tonic-gate 
1368*0Sstevel@tonic-gate 	taglen = size - sizeof (mibenum);
1369*0Sstevel@tonic-gate 
1370*0Sstevel@tonic-gate 	GETINT32(mibenum, optdata);
1371*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "MIBenum = %d", mibenum);
1372*0Sstevel@tonic-gate 
1373*0Sstevel@tonic-gate 	if (taglen > 0) {
1374*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Language Tag = %.*s", taglen,
1375*0Sstevel@tonic-gate 		    optdata);
1376*0Sstevel@tonic-gate 	}
1377*0Sstevel@tonic-gate }
1378*0Sstevel@tonic-gate 
1379*0Sstevel@tonic-gate /*
1380*0Sstevel@tonic-gate  * The format of the obsolete IP-Addresses option (rfc1172) is:
1381*0Sstevel@tonic-gate  *
1382*0Sstevel@tonic-gate  *  0                   1                   2                   3
1383*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1384*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1385*0Sstevel@tonic-gate  * |     Type      |    Length     |     Source-IP-Address
1386*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1387*0Sstevel@tonic-gate  *   Source-IP-Address (cont)      |  Destination-IP-Address
1388*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1389*0Sstevel@tonic-gate  *  Destination-IP-Address (cont)  |
1390*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1391*0Sstevel@tonic-gate  */
1392*0Sstevel@tonic-gate /*ARGSUSED1*/
1393*0Sstevel@tonic-gate static void
opt_format_ipaddresses(uchar_t * optdata,uint8_t size)1394*0Sstevel@tonic-gate opt_format_ipaddresses(uchar_t *optdata, uint8_t size)
1395*0Sstevel@tonic-gate {
1396*0Sstevel@tonic-gate 	in_addr_t addr;
1397*0Sstevel@tonic-gate 	char addrstr[INET_ADDRSTRLEN];
1398*0Sstevel@tonic-gate 
1399*0Sstevel@tonic-gate 	(void) memcpy(&addr, optdata, sizeof (in_addr_t));
1400*0Sstevel@tonic-gate 	if (inet_ntop(AF_INET, &addr, addrstr, INET_ADDRSTRLEN) != NULL) {
1401*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Source Address =      %s",
1402*0Sstevel@tonic-gate 		    addrstr);
1403*0Sstevel@tonic-gate 	}
1404*0Sstevel@tonic-gate 
1405*0Sstevel@tonic-gate 	optdata += sizeof (in_addr_t);
1406*0Sstevel@tonic-gate 
1407*0Sstevel@tonic-gate 	(void) memcpy(&addr, optdata, sizeof (in_addr_t));
1408*0Sstevel@tonic-gate 	if (inet_ntop(AF_INET, &addr, addrstr, INET_ADDRSTRLEN) != NULL) {
1409*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Destination Address = %s",
1410*0Sstevel@tonic-gate 		    addrstr);
1411*0Sstevel@tonic-gate 	}
1412*0Sstevel@tonic-gate }
1413*0Sstevel@tonic-gate 
1414*0Sstevel@tonic-gate /*
1415*0Sstevel@tonic-gate  * The format of the IP-Compression-Protocol option (rfc1332) is:
1416*0Sstevel@tonic-gate  *
1417*0Sstevel@tonic-gate  *  0                   1                   2                   3
1418*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1419*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1420*0Sstevel@tonic-gate  * |     Type      |    Length     |     IP-Compression-Protocol   |
1421*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1422*0Sstevel@tonic-gate  * |    Data ...
1423*0Sstevel@tonic-gate  * +-+-+-+-+
1424*0Sstevel@tonic-gate  *
1425*0Sstevel@tonic-gate  * For VJ Compressed TCP/IP, data consists of:
1426*0Sstevel@tonic-gate  *
1427*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1428*0Sstevel@tonic-gate  * |  Max-Slot-Id  | Comp-Slot-Id  |
1429*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1430*0Sstevel@tonic-gate  *
1431*0Sstevel@tonic-gate  * For IPHC (rfc2509), data consists of:
1432*0Sstevel@tonic-gate  *
1433*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1434*0Sstevel@tonic-gate  * |           TCP_SPACE           |         NON_TCP_SPACE         |
1435*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1436*0Sstevel@tonic-gate  * |         F_MAX_PERIOD          |          F_MAX_TIME           |
1437*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1438*0Sstevel@tonic-gate  * |           MAX_HEADER          |          suboptions...
1439*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1440*0Sstevel@tonic-gate  */
1441*0Sstevel@tonic-gate static void
opt_format_ipcompproto(uchar_t * optdata,uint8_t size)1442*0Sstevel@tonic-gate opt_format_ipcompproto(uchar_t *optdata, uint8_t size)
1443*0Sstevel@tonic-gate {
1444*0Sstevel@tonic-gate 	uint16_t proto;
1445*0Sstevel@tonic-gate 	ppp_protoinfo_t *comp_protoinfo;
1446*0Sstevel@tonic-gate 
1447*0Sstevel@tonic-gate 	GETINT16(proto, optdata);
1448*0Sstevel@tonic-gate 
1449*0Sstevel@tonic-gate 	comp_protoinfo = ppp_getprotoinfo(proto);
1450*0Sstevel@tonic-gate 
1451*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Protocol = 0x%x (%s)", proto,
1452*0Sstevel@tonic-gate 	    comp_protoinfo->name);
1453*0Sstevel@tonic-gate 
1454*0Sstevel@tonic-gate 	switch (proto) {
1455*0Sstevel@tonic-gate 	case PPP_VJC_COMP: {
1456*0Sstevel@tonic-gate 		uint8_t maxslotid;
1457*0Sstevel@tonic-gate 		uint8_t compslotid;
1458*0Sstevel@tonic-gate 
1459*0Sstevel@tonic-gate 		if (size < sizeof (proto) + sizeof (maxslotid) +
1460*0Sstevel@tonic-gate 		    sizeof (compslotid))
1461*0Sstevel@tonic-gate 			break;
1462*0Sstevel@tonic-gate 
1463*0Sstevel@tonic-gate 		GETINT8(maxslotid, optdata);
1464*0Sstevel@tonic-gate 		GETINT8(compslotid, optdata);
1465*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Max-Slot-Id = %d", maxslotid);
1466*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Comp-Slot Flag = 0x%x",
1467*0Sstevel@tonic-gate 		    compslotid);
1468*0Sstevel@tonic-gate 		break;
1469*0Sstevel@tonic-gate 	}
1470*0Sstevel@tonic-gate 	case PPP_FULLHDR: {
1471*0Sstevel@tonic-gate 		uint16_t tcp_space;
1472*0Sstevel@tonic-gate 		uint16_t non_tcp_space;
1473*0Sstevel@tonic-gate 		uint16_t f_max_period;
1474*0Sstevel@tonic-gate 		uint16_t f_max_time;
1475*0Sstevel@tonic-gate 		uint16_t max_header;
1476*0Sstevel@tonic-gate 
1477*0Sstevel@tonic-gate 		if (size < sizeof (proto) + sizeof (tcp_space) +
1478*0Sstevel@tonic-gate 		    sizeof (non_tcp_space) + sizeof (f_max_period) +
1479*0Sstevel@tonic-gate 		    sizeof (f_max_time) + sizeof (max_header))
1480*0Sstevel@tonic-gate 			break;
1481*0Sstevel@tonic-gate 
1482*0Sstevel@tonic-gate 		GETINT16(tcp_space, optdata);
1483*0Sstevel@tonic-gate 		GETINT16(non_tcp_space, optdata);
1484*0Sstevel@tonic-gate 		GETINT16(f_max_period, optdata);
1485*0Sstevel@tonic-gate 		GETINT16(f_max_time, optdata);
1486*0Sstevel@tonic-gate 		GETINT16(max_header, optdata);
1487*0Sstevel@tonic-gate 
1488*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "TCP_SPACE = %d", tcp_space);
1489*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "NON_TCP_SPACE = %d",
1490*0Sstevel@tonic-gate 		    non_tcp_space);
1491*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "F_MAX_PERIOD = %d",
1492*0Sstevel@tonic-gate 		    f_max_period);
1493*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "F_MAX_TIME = %d", f_max_time);
1494*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "MAX_HEADER = %d octets",
1495*0Sstevel@tonic-gate 		    max_header);
1496*0Sstevel@tonic-gate 	}
1497*0Sstevel@tonic-gate 	default:
1498*0Sstevel@tonic-gate 		break;
1499*0Sstevel@tonic-gate 	}
1500*0Sstevel@tonic-gate }
1501*0Sstevel@tonic-gate 
1502*0Sstevel@tonic-gate /*
1503*0Sstevel@tonic-gate  * The format of the IP-Address option (rfc1332) is:
1504*0Sstevel@tonic-gate  *
1505*0Sstevel@tonic-gate  *  0                   1                   2                   3
1506*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1507*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1508*0Sstevel@tonic-gate  * |     Type      |    Length     |           IP-Address
1509*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1510*0Sstevel@tonic-gate  *         IP-Address (cont)       |
1511*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1512*0Sstevel@tonic-gate  */
1513*0Sstevel@tonic-gate /*ARGSUSED1*/
1514*0Sstevel@tonic-gate static void
opt_format_ipaddress(uchar_t * optdata,uint8_t size)1515*0Sstevel@tonic-gate opt_format_ipaddress(uchar_t *optdata, uint8_t size)
1516*0Sstevel@tonic-gate {
1517*0Sstevel@tonic-gate 	in_addr_t ipaddr;
1518*0Sstevel@tonic-gate 	char addrstr[INET_ADDRSTRLEN];
1519*0Sstevel@tonic-gate 
1520*0Sstevel@tonic-gate 	(void) memcpy(&ipaddr, optdata, sizeof (in_addr_t));
1521*0Sstevel@tonic-gate 	if (inet_ntop(AF_INET, &ipaddr, addrstr, INET_ADDRSTRLEN) != NULL) {
1522*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Address = %s", addrstr);
1523*0Sstevel@tonic-gate 	}
1524*0Sstevel@tonic-gate }
1525*0Sstevel@tonic-gate 
1526*0Sstevel@tonic-gate /*
1527*0Sstevel@tonic-gate  * The format of the Mobile-IPv4 option (rfc2290) is:
1528*0Sstevel@tonic-gate  *
1529*0Sstevel@tonic-gate  *  0                   1                   2                   3
1530*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1531*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1532*0Sstevel@tonic-gate  * |     Type      |    Length     |         Mobile Node's ...
1533*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1534*0Sstevel@tonic-gate  *       ...  Home Address         |
1535*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1536*0Sstevel@tonic-gate  */
1537*0Sstevel@tonic-gate /*ARGSUSED1*/
1538*0Sstevel@tonic-gate static void
opt_format_mobileipv4(uchar_t * optdata,uint8_t size)1539*0Sstevel@tonic-gate opt_format_mobileipv4(uchar_t *optdata, uint8_t size)
1540*0Sstevel@tonic-gate {
1541*0Sstevel@tonic-gate 	in_addr_t ipaddr;
1542*0Sstevel@tonic-gate 	char addrstr[INET_ADDRSTRLEN];
1543*0Sstevel@tonic-gate 
1544*0Sstevel@tonic-gate 	(void) memcpy(&ipaddr, optdata, sizeof (in_addr_t));
1545*0Sstevel@tonic-gate 	if (inet_ntop(AF_INET, &ipaddr, addrstr, INET_ADDRSTRLEN) != NULL) {
1546*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0),
1547*0Sstevel@tonic-gate 		    "Mobile Node's Home Address = %s", addrstr);
1548*0Sstevel@tonic-gate 	}
1549*0Sstevel@tonic-gate }
1550*0Sstevel@tonic-gate 
1551*0Sstevel@tonic-gate /*
1552*0Sstevel@tonic-gate  * The format of the Interface-Identifier option (rfc2472) is:
1553*0Sstevel@tonic-gate  *
1554*0Sstevel@tonic-gate  * 0                   1                   2                   3
1555*0Sstevel@tonic-gate  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1556*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1557*0Sstevel@tonic-gate  * |     Type      |    Length     | Interface-Identifier (MS Bytes)
1558*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1559*0Sstevel@tonic-gate  *                      Interface-Identifier (cont)
1560*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1561*0Sstevel@tonic-gate  * Interface-Identifier (LS Bytes) |
1562*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1563*0Sstevel@tonic-gate  */
1564*0Sstevel@tonic-gate /*ARGSUSED1*/
1565*0Sstevel@tonic-gate static void
opt_format_ifaceid(uchar_t * optdata,uint8_t size)1566*0Sstevel@tonic-gate opt_format_ifaceid(uchar_t *optdata, uint8_t size)
1567*0Sstevel@tonic-gate {
1568*0Sstevel@tonic-gate 	in6_addr_t id;
1569*0Sstevel@tonic-gate 	char idstr[INET6_ADDRSTRLEN];
1570*0Sstevel@tonic-gate 
1571*0Sstevel@tonic-gate 	(void) memset(&id, 0, sizeof (in6_addr_t));
1572*0Sstevel@tonic-gate 	(void) memcpy(&id.s6_addr[8], optdata, 8);
1573*0Sstevel@tonic-gate 
1574*0Sstevel@tonic-gate 	if (inet_ntop(AF_INET6, &id, idstr, INET6_ADDRSTRLEN) != NULL) {
1575*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "Interface ID = %s", idstr);
1576*0Sstevel@tonic-gate 	}
1577*0Sstevel@tonic-gate }
1578*0Sstevel@tonic-gate 
1579*0Sstevel@tonic-gate /*
1580*0Sstevel@tonic-gate  * The format of the IPv6-Compression-Protocol option (rfc2472) is:
1581*0Sstevel@tonic-gate  *
1582*0Sstevel@tonic-gate  * 0                   1                   2                   3
1583*0Sstevel@tonic-gate  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1584*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1585*0Sstevel@tonic-gate  * |     Type      |    Length     |   IPv6-Compression-Protocol   |
1586*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1587*0Sstevel@tonic-gate  * |    Data ...
1588*0Sstevel@tonic-gate  * +-+-+-+-+
1589*0Sstevel@tonic-gate  */
1590*0Sstevel@tonic-gate static void
opt_format_ipv6compproto(uchar_t * optdata,uint8_t size)1591*0Sstevel@tonic-gate opt_format_ipv6compproto(uchar_t *optdata, uint8_t size)
1592*0Sstevel@tonic-gate {
1593*0Sstevel@tonic-gate 	uint16_t proto;
1594*0Sstevel@tonic-gate 	ppp_protoinfo_t *comp_protoinfo;
1595*0Sstevel@tonic-gate 
1596*0Sstevel@tonic-gate 	GETINT16(proto, optdata);
1597*0Sstevel@tonic-gate 
1598*0Sstevel@tonic-gate 	comp_protoinfo = ppp_getprotoinfo(proto);
1599*0Sstevel@tonic-gate 
1600*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Protocol = 0x%x (%s)", proto,
1601*0Sstevel@tonic-gate 	    comp_protoinfo->name);
1602*0Sstevel@tonic-gate 
1603*0Sstevel@tonic-gate 	switch (proto) {
1604*0Sstevel@tonic-gate 	case PPP_FULLHDR: {
1605*0Sstevel@tonic-gate 		uint16_t tcp_space;
1606*0Sstevel@tonic-gate 		uint16_t non_tcp_space;
1607*0Sstevel@tonic-gate 		uint16_t f_max_period;
1608*0Sstevel@tonic-gate 		uint16_t f_max_time;
1609*0Sstevel@tonic-gate 		uint16_t max_header;
1610*0Sstevel@tonic-gate 
1611*0Sstevel@tonic-gate 		if (size < sizeof (proto) + sizeof (tcp_space) +
1612*0Sstevel@tonic-gate 		    sizeof (non_tcp_space) + sizeof (f_max_period) +
1613*0Sstevel@tonic-gate 		    sizeof (f_max_time) + sizeof (max_header))
1614*0Sstevel@tonic-gate 			return;
1615*0Sstevel@tonic-gate 
1616*0Sstevel@tonic-gate 		GETINT16(tcp_space, optdata);
1617*0Sstevel@tonic-gate 		GETINT16(non_tcp_space, optdata);
1618*0Sstevel@tonic-gate 		GETINT16(f_max_period, optdata);
1619*0Sstevel@tonic-gate 		GETINT16(f_max_time, optdata);
1620*0Sstevel@tonic-gate 		GETINT16(max_header, optdata);
1621*0Sstevel@tonic-gate 
1622*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "TCP_SPACE = %d", tcp_space);
1623*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "NON_TCP_SPACE = %d",
1624*0Sstevel@tonic-gate 		    non_tcp_space);
1625*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "F_MAX_PERIOD = %d",
1626*0Sstevel@tonic-gate 		    f_max_period);
1627*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "F_MAX_TIME = %d", f_max_time);
1628*0Sstevel@tonic-gate 		(void) sprintf(get_line(0, 0), "MAX_HEADER = %d octets",
1629*0Sstevel@tonic-gate 		    max_header);
1630*0Sstevel@tonic-gate 	}
1631*0Sstevel@tonic-gate 	default:
1632*0Sstevel@tonic-gate 		break;
1633*0Sstevel@tonic-gate 	}
1634*0Sstevel@tonic-gate }
1635*0Sstevel@tonic-gate 
1636*0Sstevel@tonic-gate /*
1637*0Sstevel@tonic-gate  * The format of the Proprietary Compression OUI option (rfc1962) is:
1638*0Sstevel@tonic-gate  *
1639*0Sstevel@tonic-gate  *  0                   1                   2                   3
1640*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1641*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1642*0Sstevel@tonic-gate  * |     Type      |    Length     |       OUI ...
1643*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1644*0Sstevel@tonic-gate  *       OUI       |    Subtype    |  Values...
1645*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
1646*0Sstevel@tonic-gate  */
1647*0Sstevel@tonic-gate /*ARGSUSED1*/
1648*0Sstevel@tonic-gate static void
opt_format_compoui(uchar_t * optdata,uint8_t size)1649*0Sstevel@tonic-gate opt_format_compoui(uchar_t *optdata, uint8_t size)
1650*0Sstevel@tonic-gate {
1651*0Sstevel@tonic-gate 	uint32_t oui;
1652*0Sstevel@tonic-gate 	uint8_t subtype;
1653*0Sstevel@tonic-gate 	char *ouistr;
1654*0Sstevel@tonic-gate 
1655*0Sstevel@tonic-gate 	GETINT32(oui, optdata);
1656*0Sstevel@tonic-gate 	subtype = oui & 0x000000ff;
1657*0Sstevel@tonic-gate 	oui >>= 8;
1658*0Sstevel@tonic-gate 
1659*0Sstevel@tonic-gate 	ouistr = ether_ouiname(oui);
1660*0Sstevel@tonic-gate 	if (ouistr == NULL)
1661*0Sstevel@tonic-gate 		ouistr = unknown_string;
1662*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "OUI = 0x%06x (%s)", oui, ouistr);
1663*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Subtype = 0x%x", subtype);
1664*0Sstevel@tonic-gate }
1665*0Sstevel@tonic-gate 
1666*0Sstevel@tonic-gate /*
1667*0Sstevel@tonic-gate  * The format of the Stac LZS configuration option (rfc1974) is:
1668*0Sstevel@tonic-gate  *
1669*0Sstevel@tonic-gate  *  0                   1                   2                   3
1670*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1671*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1672*0Sstevel@tonic-gate  * |     Type      |    Length     |        History Count          |
1673*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1674*0Sstevel@tonic-gate  * |   Check Mode  |
1675*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+
1676*0Sstevel@tonic-gate  */
1677*0Sstevel@tonic-gate /*ARGSUSED1*/
1678*0Sstevel@tonic-gate static void
opt_format_staclzs(uchar_t * optdata,uint8_t size)1679*0Sstevel@tonic-gate opt_format_staclzs(uchar_t *optdata, uint8_t size)
1680*0Sstevel@tonic-gate {
1681*0Sstevel@tonic-gate 	uint16_t hcount;
1682*0Sstevel@tonic-gate 	uint8_t cmode;
1683*0Sstevel@tonic-gate 
1684*0Sstevel@tonic-gate 	GETINT16(hcount, optdata);
1685*0Sstevel@tonic-gate 	GETINT8(cmode, optdata);
1686*0Sstevel@tonic-gate 
1687*0Sstevel@tonic-gate 	cmode &= 0x07;
1688*0Sstevel@tonic-gate 
1689*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "History Count = %d", hcount);
1690*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Check Mode = %d", cmode);
1691*0Sstevel@tonic-gate }
1692*0Sstevel@tonic-gate 
1693*0Sstevel@tonic-gate /*
1694*0Sstevel@tonic-gate  * The format of MPPC configuration option (rfc2118) is:
1695*0Sstevel@tonic-gate  *
1696*0Sstevel@tonic-gate  *  0                   1                   2                   3
1697*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1698*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1699*0Sstevel@tonic-gate  * |     Type      |    Length     |        Supported Bits         |
1700*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1701*0Sstevel@tonic-gate  * |       Supported Bits          |
1702*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1703*0Sstevel@tonic-gate  */
1704*0Sstevel@tonic-gate /*ARGSUSED1*/
1705*0Sstevel@tonic-gate static void
opt_format_mppc(uchar_t * optdata,uint8_t size)1706*0Sstevel@tonic-gate opt_format_mppc(uchar_t *optdata, uint8_t size)
1707*0Sstevel@tonic-gate {
1708*0Sstevel@tonic-gate 	uint32_t sb;
1709*0Sstevel@tonic-gate 
1710*0Sstevel@tonic-gate 	GETINT32(sb, optdata);
1711*0Sstevel@tonic-gate 
1712*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Supported Bits = 0x%x", sb);
1713*0Sstevel@tonic-gate }
1714*0Sstevel@tonic-gate 
1715*0Sstevel@tonic-gate /*
1716*0Sstevel@tonic-gate  * The format of the Gandalf FZA configuration option (rfc1993) is:
1717*0Sstevel@tonic-gate  *
1718*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1719*0Sstevel@tonic-gate  * |     Type      |    Length     |   History   |    Version ...
1720*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1721*0Sstevel@tonic-gate  */
1722*0Sstevel@tonic-gate /*ARGSUSED1*/
1723*0Sstevel@tonic-gate static void
opt_format_gandalf(uchar_t * optdata,uint8_t size)1724*0Sstevel@tonic-gate opt_format_gandalf(uchar_t *optdata, uint8_t size)
1725*0Sstevel@tonic-gate {
1726*0Sstevel@tonic-gate 	uint8_t history;
1727*0Sstevel@tonic-gate 
1728*0Sstevel@tonic-gate 	GETINT8(history, optdata);
1729*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Maximum History Size = %d bits",
1730*0Sstevel@tonic-gate 	    history);
1731*0Sstevel@tonic-gate }
1732*0Sstevel@tonic-gate 
1733*0Sstevel@tonic-gate /*
1734*0Sstevel@tonic-gate  * The format of the BSD Compress configuration option (rfc1977) is:
1735*0Sstevel@tonic-gate  *
1736*0Sstevel@tonic-gate  *  0                   1                   2
1737*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
1738*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1739*0Sstevel@tonic-gate  * |     Type      |    Length     | Vers|   Dict  |
1740*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1741*0Sstevel@tonic-gate  */
1742*0Sstevel@tonic-gate /*ARGSUSED1*/
1743*0Sstevel@tonic-gate static void
opt_format_bsdcomp(uchar_t * optdata,uint8_t size)1744*0Sstevel@tonic-gate opt_format_bsdcomp(uchar_t *optdata, uint8_t size)
1745*0Sstevel@tonic-gate {
1746*0Sstevel@tonic-gate 	uint8_t version;
1747*0Sstevel@tonic-gate 	uint8_t codesize;
1748*0Sstevel@tonic-gate 
1749*0Sstevel@tonic-gate 	GETINT8(codesize, optdata);
1750*0Sstevel@tonic-gate 
1751*0Sstevel@tonic-gate 	version = codesize >> 5;
1752*0Sstevel@tonic-gate 	codesize &= 0x1f;
1753*0Sstevel@tonic-gate 
1754*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Version = 0x%x", version);
1755*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Maximum Code Size = %d bits", codesize);
1756*0Sstevel@tonic-gate }
1757*0Sstevel@tonic-gate 
1758*0Sstevel@tonic-gate /*
1759*0Sstevel@tonic-gate  * The format of the LZS-DCP configuration option (rfc1967) is:
1760*0Sstevel@tonic-gate  *
1761*0Sstevel@tonic-gate  *  0                   1                   2                   3
1762*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1763*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1764*0Sstevel@tonic-gate  * |     Type      |    Length     |        History Count          |
1765*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1766*0Sstevel@tonic-gate  * |   Check Mode  | Process Mode  |
1767*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1768*0Sstevel@tonic-gate  */
1769*0Sstevel@tonic-gate /*ARGSUSED1*/
1770*0Sstevel@tonic-gate static void
opt_format_lzsdcp(uchar_t * optdata,uint8_t size)1771*0Sstevel@tonic-gate opt_format_lzsdcp(uchar_t *optdata, uint8_t size)
1772*0Sstevel@tonic-gate {
1773*0Sstevel@tonic-gate 	uint16_t history;
1774*0Sstevel@tonic-gate 	uint8_t mode;
1775*0Sstevel@tonic-gate 	char *modestr;
1776*0Sstevel@tonic-gate 
1777*0Sstevel@tonic-gate 	GETINT16(history, optdata);
1778*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "History Count = %d", history);
1779*0Sstevel@tonic-gate 
1780*0Sstevel@tonic-gate 	/* check mode */
1781*0Sstevel@tonic-gate 	GETINT8(mode, optdata);
1782*0Sstevel@tonic-gate 	switch (mode) {
1783*0Sstevel@tonic-gate 	case 0:
1784*0Sstevel@tonic-gate 		modestr = "None";
1785*0Sstevel@tonic-gate 		break;
1786*0Sstevel@tonic-gate 	case 1:
1787*0Sstevel@tonic-gate 		modestr = "LCB";
1788*0Sstevel@tonic-gate 		break;
1789*0Sstevel@tonic-gate 	case 2:
1790*0Sstevel@tonic-gate 		modestr = "Sequence Number";
1791*0Sstevel@tonic-gate 		break;
1792*0Sstevel@tonic-gate 	case 3:
1793*0Sstevel@tonic-gate 		modestr = "Sequence Number + LCB (default)";
1794*0Sstevel@tonic-gate 		break;
1795*0Sstevel@tonic-gate 	default:
1796*0Sstevel@tonic-gate 		modestr = unknown_string;
1797*0Sstevel@tonic-gate 		break;
1798*0Sstevel@tonic-gate 	}
1799*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Check Mode = %d (%s)", mode, modestr);
1800*0Sstevel@tonic-gate 
1801*0Sstevel@tonic-gate 	/* process mode */
1802*0Sstevel@tonic-gate 	GETINT8(mode, optdata);
1803*0Sstevel@tonic-gate 	switch (mode) {
1804*0Sstevel@tonic-gate 	case 0:
1805*0Sstevel@tonic-gate 		modestr = "None (default)";
1806*0Sstevel@tonic-gate 		break;
1807*0Sstevel@tonic-gate 	case 1:
1808*0Sstevel@tonic-gate 		modestr = "Process-Uncompressed";
1809*0Sstevel@tonic-gate 		break;
1810*0Sstevel@tonic-gate 	default:
1811*0Sstevel@tonic-gate 		modestr = unknown_string;
1812*0Sstevel@tonic-gate 		break;
1813*0Sstevel@tonic-gate 	}
1814*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Process Mode = %d (%s)", mode, modestr);
1815*0Sstevel@tonic-gate 
1816*0Sstevel@tonic-gate }
1817*0Sstevel@tonic-gate 
1818*0Sstevel@tonic-gate /*
1819*0Sstevel@tonic-gate  * The format of the Magnalink configuration option (rfc1975) is:
1820*0Sstevel@tonic-gate  *
1821*0Sstevel@tonic-gate  *  0                   1                   2                   3
1822*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1823*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1824*0Sstevel@tonic-gate  * |     Type      |    Length     |FE |P| History |  # Contexts   |
1825*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1826*0Sstevel@tonic-gate  */
1827*0Sstevel@tonic-gate /*ARGSUSED1*/
1828*0Sstevel@tonic-gate static void
opt_format_magnalink(uchar_t * optdata,uint8_t size)1829*0Sstevel@tonic-gate opt_format_magnalink(uchar_t *optdata, uint8_t size)
1830*0Sstevel@tonic-gate {
1831*0Sstevel@tonic-gate 	uint8_t features;
1832*0Sstevel@tonic-gate 	uint8_t pflag;
1833*0Sstevel@tonic-gate 	uint8_t history;
1834*0Sstevel@tonic-gate 	uint8_t contexts;
1835*0Sstevel@tonic-gate 
1836*0Sstevel@tonic-gate 	GETINT8(history, optdata);
1837*0Sstevel@tonic-gate 	GETINT8(contexts, optdata);
1838*0Sstevel@tonic-gate 
1839*0Sstevel@tonic-gate 	features = history >> 6;
1840*0Sstevel@tonic-gate 	pflag = (history >> 5) & 0x01;
1841*0Sstevel@tonic-gate 	history &= 0x1f;
1842*0Sstevel@tonic-gate 
1843*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Features = 0x%d", features);
1844*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Packet Flag = %d", pflag);
1845*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "History Size = %d", history);
1846*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Contexts = %d", contexts);
1847*0Sstevel@tonic-gate }
1848*0Sstevel@tonic-gate 
1849*0Sstevel@tonic-gate /*
1850*0Sstevel@tonic-gate  * The format of the Deflate configuration option (rfc1979) is:
1851*0Sstevel@tonic-gate  *
1852*0Sstevel@tonic-gate  *  0                   1                   2                   3
1853*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1854*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1855*0Sstevel@tonic-gate  * |     Type      |    Length     |Window | Method|    MBZ    |Chk|
1856*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1857*0Sstevel@tonic-gate  */
1858*0Sstevel@tonic-gate /*ARGSUSED1*/
1859*0Sstevel@tonic-gate static void
opt_format_deflate(uchar_t * optdata,uint8_t size)1860*0Sstevel@tonic-gate opt_format_deflate(uchar_t *optdata, uint8_t size)
1861*0Sstevel@tonic-gate {
1862*0Sstevel@tonic-gate 	uint8_t window;
1863*0Sstevel@tonic-gate 	uint8_t method;
1864*0Sstevel@tonic-gate 	uint8_t chk;
1865*0Sstevel@tonic-gate 
1866*0Sstevel@tonic-gate 	GETINT8(method, optdata);
1867*0Sstevel@tonic-gate 	window = method >> 4;
1868*0Sstevel@tonic-gate 	method &= 0x0f;
1869*0Sstevel@tonic-gate 
1870*0Sstevel@tonic-gate 	GETINT8(chk, optdata);
1871*0Sstevel@tonic-gate 	chk &= 0x03;
1872*0Sstevel@tonic-gate 
1873*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Maximum Window Size = %d", window);
1874*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Compression Method = 0x%x", method);
1875*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Check Method = 0x%x", chk);
1876*0Sstevel@tonic-gate }
1877*0Sstevel@tonic-gate 
1878*0Sstevel@tonic-gate /*
1879*0Sstevel@tonic-gate  * The format of the Proprietary Encryption OUI option (rfc1968) is:
1880*0Sstevel@tonic-gate  *
1881*0Sstevel@tonic-gate  * 0                   1                   2                   3
1882*0Sstevel@tonic-gate  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1883*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1884*0Sstevel@tonic-gate  * |     Type      |    Length     |       OUI ...
1885*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1886*0Sstevel@tonic-gate  *       OUI       |    Subtype    |  Values...
1887*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
1888*0Sstevel@tonic-gate  */
1889*0Sstevel@tonic-gate /*ARGSUSED1*/
1890*0Sstevel@tonic-gate static void
opt_format_encroui(uchar_t * optdata,uint8_t size)1891*0Sstevel@tonic-gate opt_format_encroui(uchar_t *optdata, uint8_t size)
1892*0Sstevel@tonic-gate {
1893*0Sstevel@tonic-gate 	uint32_t oui;
1894*0Sstevel@tonic-gate 	uint8_t subtype;
1895*0Sstevel@tonic-gate 	char *ouistr;
1896*0Sstevel@tonic-gate 
1897*0Sstevel@tonic-gate 	GETINT32(oui, optdata);
1898*0Sstevel@tonic-gate 	subtype = oui & 0x000000ff;
1899*0Sstevel@tonic-gate 	oui >>= 8;
1900*0Sstevel@tonic-gate 
1901*0Sstevel@tonic-gate 	ouistr = ether_ouiname(oui);
1902*0Sstevel@tonic-gate 	if (ouistr == NULL)
1903*0Sstevel@tonic-gate 		ouistr = unknown_string;
1904*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "OUI = 0x%06x (%s)", oui, ouistr);
1905*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Subtype = 0x%x", subtype);
1906*0Sstevel@tonic-gate }
1907*0Sstevel@tonic-gate 
1908*0Sstevel@tonic-gate /*
1909*0Sstevel@tonic-gate  * The format of the DESE, DESE-bis, and 3DESE configuration options
1910*0Sstevel@tonic-gate  * (rfc1969, rfc2419, and rfc2420) are:
1911*0Sstevel@tonic-gate  *
1912*0Sstevel@tonic-gate  * 0                   1                   2                   3
1913*0Sstevel@tonic-gate  * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1914*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1915*0Sstevel@tonic-gate  * |   Type = 3    |    Length     |         Initial Nonce ...
1916*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1917*0Sstevel@tonic-gate  */
1918*0Sstevel@tonic-gate /*ARGSUSED1*/
1919*0Sstevel@tonic-gate static void
opt_format_dese(uchar_t * optdata,uint8_t size)1920*0Sstevel@tonic-gate opt_format_dese(uchar_t *optdata, uint8_t size)
1921*0Sstevel@tonic-gate {
1922*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0),
1923*0Sstevel@tonic-gate 	    "Initial Nonce = 0x%02x%02x%02x%02x%02x%02x%02x%02x",
1924*0Sstevel@tonic-gate 	    optdata[0], optdata[1], optdata[2], optdata[3], optdata[4],
1925*0Sstevel@tonic-gate 	    optdata[5], optdata[6], optdata[7]);
1926*0Sstevel@tonic-gate }
1927*0Sstevel@tonic-gate 
1928*0Sstevel@tonic-gate /*
1929*0Sstevel@tonic-gate  * The format of the PPPMux Default Protocol Id option
1930*0Sstevel@tonic-gate  * (draft-ietf-pppext-pppmux-02.txt) is:
1931*0Sstevel@tonic-gate  *
1932*0Sstevel@tonic-gate  *  0                   1                   2                   3
1933*0Sstevel@tonic-gate  *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1934*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1935*0Sstevel@tonic-gate  * |   Type = 1    |   Length = 4  |        Default PID            |
1936*0Sstevel@tonic-gate  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1937*0Sstevel@tonic-gate  */
1938*0Sstevel@tonic-gate /*ARGSUSED1*/
1939*0Sstevel@tonic-gate static void
opt_format_muxpid(uchar_t * optdata,uint8_t size)1940*0Sstevel@tonic-gate opt_format_muxpid(uchar_t *optdata, uint8_t size)
1941*0Sstevel@tonic-gate {
1942*0Sstevel@tonic-gate 	uint16_t defpid;
1943*0Sstevel@tonic-gate 
1944*0Sstevel@tonic-gate 	GETINT16(defpid, optdata);
1945*0Sstevel@tonic-gate 	(void) sprintf(get_line(0, 0), "Default PID = %d", defpid);
1946*0Sstevel@tonic-gate }
1947