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