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 #pragma ident "%Z%%M% %I% %E% SMI" 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 } 1947