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