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 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 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 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 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 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 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 * 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 * 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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