1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <ctype.h> 30*0Sstevel@tonic-gate #include <stdio.h> 31*0Sstevel@tonic-gate #include <stdlib.h> 32*0Sstevel@tonic-gate #include <fcntl.h> 33*0Sstevel@tonic-gate #include <string.h> 34*0Sstevel@tonic-gate #include <sys/types.h> 35*0Sstevel@tonic-gate #include <sys/socket.h> 36*0Sstevel@tonic-gate #include <sys/sysmacros.h> 37*0Sstevel@tonic-gate #include <netinet/in.h> 38*0Sstevel@tonic-gate #include <netinet/dhcp.h> 39*0Sstevel@tonic-gate #include <arpa/inet.h> 40*0Sstevel@tonic-gate #include <dhcp_inittab.h> 41*0Sstevel@tonic-gate #include <dhcp_symbol.h> 42*0Sstevel@tonic-gate #include "snoop.h" 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate extern char *dlc_header; 45*0Sstevel@tonic-gate static char *show_htype(int); 46*0Sstevel@tonic-gate static const char *show_msgtype(unsigned char); 47*0Sstevel@tonic-gate static int show_options(unsigned char *, int); 48*0Sstevel@tonic-gate static void display_ip(int, char *, char *, unsigned char **); 49*0Sstevel@tonic-gate static void display_ascii(char *, char *, unsigned char **); 50*0Sstevel@tonic-gate static void display_number(char *, char *, unsigned char **); 51*0Sstevel@tonic-gate static void display_ascii_hex(char *, unsigned char **); 52*0Sstevel@tonic-gate static unsigned char bootmagic[] = BOOTMAGIC; /* rfc 1048 */ 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate static char *option_types[] = { 55*0Sstevel@tonic-gate "", /* 0 */ 56*0Sstevel@tonic-gate "Subnet Mask", /* 1 */ 57*0Sstevel@tonic-gate "UTC Time Offset", /* 2 */ 58*0Sstevel@tonic-gate "Router", /* 3 */ 59*0Sstevel@tonic-gate "RFC868 Time Servers", /* 4 */ 60*0Sstevel@tonic-gate "IEN 116 Name Servers", /* 5 */ 61*0Sstevel@tonic-gate "DNS Servers", /* 6 */ 62*0Sstevel@tonic-gate "UDP LOG Servers", /* 7 */ 63*0Sstevel@tonic-gate "RFC 865 Cookie Servers", /* 8 */ 64*0Sstevel@tonic-gate "RFC 1179 Line Printer Servers (LPR)", /* 9 */ 65*0Sstevel@tonic-gate "Impress Servers", /* 10 */ 66*0Sstevel@tonic-gate "RFC 887 Resource Location Servers", /* 11 */ 67*0Sstevel@tonic-gate "Client Hostname", /* 12 */ 68*0Sstevel@tonic-gate "Boot File size in 512 byte Blocks", /* 13 */ 69*0Sstevel@tonic-gate "Merit Dump File", /* 14 */ 70*0Sstevel@tonic-gate "DNS Domain Name", /* 15 */ 71*0Sstevel@tonic-gate "SWAP Server", /* 16 */ 72*0Sstevel@tonic-gate "Client Root Path", /* 17 */ 73*0Sstevel@tonic-gate "BOOTP options extensions path", /* 18 */ 74*0Sstevel@tonic-gate "IP Forwarding Flag", /* 19 */ 75*0Sstevel@tonic-gate "NonLocal Source Routing Flag", /* 20 */ 76*0Sstevel@tonic-gate "Policy Filters for NonLocal Routing", /* 21 */ 77*0Sstevel@tonic-gate "Maximum Datagram Reassembly Size", /* 22 */ 78*0Sstevel@tonic-gate "Default IP Time To Live", /* 23 */ 79*0Sstevel@tonic-gate "Path MTU Aging Timeout", /* 24 */ 80*0Sstevel@tonic-gate "Path MTU Size Plateau Table", /* 25 */ 81*0Sstevel@tonic-gate "Interface MTU Size", /* 26 */ 82*0Sstevel@tonic-gate "All Subnets are Local Flag", /* 27 */ 83*0Sstevel@tonic-gate "Broadcast Address", /* 28 */ 84*0Sstevel@tonic-gate "Perform Mask Discovery Flag", /* 29 */ 85*0Sstevel@tonic-gate "Mask Supplier Flag", /* 30 */ 86*0Sstevel@tonic-gate "Perform Router Discovery Flag", /* 31 */ 87*0Sstevel@tonic-gate "Router Solicitation Address", /* 32 */ 88*0Sstevel@tonic-gate "Static Routes", /* 33 */ 89*0Sstevel@tonic-gate "Trailer Encapsulation Flag", /* 34 */ 90*0Sstevel@tonic-gate "ARP Cache Timeout Seconds", /* 35 */ 91*0Sstevel@tonic-gate "Ethernet Encapsulation Flag", /* 36 */ 92*0Sstevel@tonic-gate "TCP Default Time To Live", /* 37 */ 93*0Sstevel@tonic-gate "TCP Keepalive Interval Seconds", /* 38 */ 94*0Sstevel@tonic-gate "TCP Keepalive Garbage Flag", /* 39 */ 95*0Sstevel@tonic-gate "NIS Domainname", /* 40 */ 96*0Sstevel@tonic-gate "NIS Servers", /* 41 */ 97*0Sstevel@tonic-gate "Network Time Protocol Servers", /* 42 */ 98*0Sstevel@tonic-gate "Vendor Specific Options", /* 43 */ 99*0Sstevel@tonic-gate "NetBIOS RFC 1001/1002 Name Servers", /* 44 */ 100*0Sstevel@tonic-gate "NetBIOS Datagram Dist. Servers", /* 45 */ 101*0Sstevel@tonic-gate "NetBIOS Node Type", /* 46 */ 102*0Sstevel@tonic-gate "NetBIOS Scope", /* 47 */ 103*0Sstevel@tonic-gate "X Window Font Servers", /* 48 */ 104*0Sstevel@tonic-gate "X Window Display Manager Servers", /* 49 */ 105*0Sstevel@tonic-gate "Requested IP Address", /* 50 */ 106*0Sstevel@tonic-gate "IP Address Lease Time", /* 51 */ 107*0Sstevel@tonic-gate "Option Field Overload Flag", /* 52 */ 108*0Sstevel@tonic-gate "DHCP Message Type", /* 53 */ 109*0Sstevel@tonic-gate "DHCP Server Identifier", /* 54 */ 110*0Sstevel@tonic-gate "Option Request List", /* 55 */ 111*0Sstevel@tonic-gate "Error Message", /* 56 */ 112*0Sstevel@tonic-gate "Maximum DHCP Message Size", /* 57 */ 113*0Sstevel@tonic-gate "Renewal (T1) Time Value", /* 58 */ 114*0Sstevel@tonic-gate "Rebinding (T2) Time Value", /* 59 */ 115*0Sstevel@tonic-gate "Client Class Identifier =", /* 60 */ 116*0Sstevel@tonic-gate "Client Identifier =", /* 61 */ 117*0Sstevel@tonic-gate "Netware IP Domain =", /* 62 */ 118*0Sstevel@tonic-gate "Netware IP Options =", /* 63 */ 119*0Sstevel@tonic-gate "NISPLUS Domainname", /* 64 */ 120*0Sstevel@tonic-gate "NISPLUS Servers", /* 65 */ 121*0Sstevel@tonic-gate "TFTP Server Name", /* 66 */ 122*0Sstevel@tonic-gate "Option BootFile Name", /* 67 */ 123*0Sstevel@tonic-gate "Mobile IP Agents", /* 68 */ 124*0Sstevel@tonic-gate "Simple Mail (SMTP) Servers", /* 69 */ 125*0Sstevel@tonic-gate "Post Office (POP3) Servers", /* 70 */ 126*0Sstevel@tonic-gate "Net News (NNTP) Servers", /* 71 */ 127*0Sstevel@tonic-gate "WorldWideWeb Servers", /* 72 */ 128*0Sstevel@tonic-gate "Finger Servers", /* 73 */ 129*0Sstevel@tonic-gate "Internet Relay Chat (IRC) Servers", /* 74 */ 130*0Sstevel@tonic-gate "StreetTalk Servers", /* 75 */ 131*0Sstevel@tonic-gate "StreetTalk Directory Assist. Servers", /* 76 */ 132*0Sstevel@tonic-gate "User Class Identifier", /* 77 */ 133*0Sstevel@tonic-gate }; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate #define OPTIONS_ARRAY_SIZE 78 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate int 138*0Sstevel@tonic-gate interpret_dhcp(int flags, PKT *dp, int len) 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate if (flags & F_SUM) { 141*0Sstevel@tonic-gate if ((memcmp(dp->cookie, bootmagic, sizeof (bootmagic)) == 0) && 142*0Sstevel@tonic-gate (len >= BASE_PKT_SIZE + 3) && 143*0Sstevel@tonic-gate dp->options[0] == CD_DHCP_TYPE) { 144*0Sstevel@tonic-gate (void) sprintf(get_sum_line(), 145*0Sstevel@tonic-gate "DHCP/BOOTP %s", show_msgtype(dp->options[2])); 146*0Sstevel@tonic-gate } else { 147*0Sstevel@tonic-gate switch (ntohs(dp->op)) { 148*0Sstevel@tonic-gate case BOOTREQUEST: 149*0Sstevel@tonic-gate (void) sprintf(get_sum_line(), 150*0Sstevel@tonic-gate "DHCP/BOOTP BOOTREQUEST"); 151*0Sstevel@tonic-gate break; 152*0Sstevel@tonic-gate case BOOTREPLY: 153*0Sstevel@tonic-gate (void) sprintf(get_sum_line(), 154*0Sstevel@tonic-gate "DHCP/BOOTP BOOTREPLY"); 155*0Sstevel@tonic-gate break; 156*0Sstevel@tonic-gate } 157*0Sstevel@tonic-gate } 158*0Sstevel@tonic-gate } 159*0Sstevel@tonic-gate if (flags & F_DTAIL) { 160*0Sstevel@tonic-gate show_header("DHCP: ", "Dynamic Host Configuration Protocol", 161*0Sstevel@tonic-gate len); 162*0Sstevel@tonic-gate show_space(); 163*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->htype - dlc_header, 1), 164*0Sstevel@tonic-gate "Hardware address type (htype) = %d (%s)", dp->htype, 165*0Sstevel@tonic-gate show_htype(dp->htype)); 166*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->hlen - dlc_header, 1), 167*0Sstevel@tonic-gate "Hardware address length (hlen) = %d octets", dp->hlen); 168*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->hops - dlc_header, 1), 169*0Sstevel@tonic-gate "Relay agent hops = %d", dp->hops); 170*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->xid - dlc_header, 4), 171*0Sstevel@tonic-gate "Transaction ID = 0x%x", ntohl(dp->xid)); 172*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->secs - dlc_header, 2), 173*0Sstevel@tonic-gate "Time since boot = %d seconds", ntohs(dp->secs)); 174*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->flags - dlc_header, 2), 175*0Sstevel@tonic-gate "Flags = 0x%.4x", ntohs(dp->flags)); 176*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&dp->ciaddr - dlc_header, 4), 177*0Sstevel@tonic-gate "Client address (ciaddr) = %s", inet_ntoa(dp->ciaddr)); 178*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&dp->yiaddr - dlc_header, 4), 179*0Sstevel@tonic-gate "Your client address (yiaddr) = %s", 180*0Sstevel@tonic-gate inet_ntoa(dp->yiaddr)); 181*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&dp->siaddr - dlc_header, 4), 182*0Sstevel@tonic-gate "Next server address (siaddr) = %s", 183*0Sstevel@tonic-gate inet_ntoa(dp->siaddr)); 184*0Sstevel@tonic-gate (void) sprintf(get_line((char *)&dp->giaddr - dlc_header, 4), 185*0Sstevel@tonic-gate "Relay agent address (giaddr) = %s", 186*0Sstevel@tonic-gate inet_ntoa(dp->giaddr)); 187*0Sstevel@tonic-gate if (dp->htype == 1) { 188*0Sstevel@tonic-gate (void) sprintf(get_line((char *)dp->chaddr - 189*0Sstevel@tonic-gate dlc_header, dp->hlen), 190*0Sstevel@tonic-gate "Client hardware address (chaddr) = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", 191*0Sstevel@tonic-gate dp->chaddr[0], 192*0Sstevel@tonic-gate dp->chaddr[1], 193*0Sstevel@tonic-gate dp->chaddr[2], 194*0Sstevel@tonic-gate dp->chaddr[3], 195*0Sstevel@tonic-gate dp->chaddr[4], 196*0Sstevel@tonic-gate dp->chaddr[5]); 197*0Sstevel@tonic-gate } 198*0Sstevel@tonic-gate /* 199*0Sstevel@tonic-gate * Check cookie, process options 200*0Sstevel@tonic-gate */ 201*0Sstevel@tonic-gate if (memcmp(dp->cookie, bootmagic, sizeof (bootmagic)) != 0) { 202*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 203*0Sstevel@tonic-gate "Unrecognized cookie: 0x%.2X%.2X%.2X%.2X\n", 204*0Sstevel@tonic-gate dp->cookie[0], 205*0Sstevel@tonic-gate dp->cookie[1], 206*0Sstevel@tonic-gate dp->cookie[2], 207*0Sstevel@tonic-gate dp->cookie[3]); 208*0Sstevel@tonic-gate return (0); 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate show_space(); 211*0Sstevel@tonic-gate show_header("DHCP: ", "(Options) field options", len); 212*0Sstevel@tonic-gate show_space(); 213*0Sstevel@tonic-gate switch (show_options(dp->options, (len - BASE_PKT_SIZE))) { 214*0Sstevel@tonic-gate case 0: 215*0Sstevel@tonic-gate /* No option overloading */ 216*0Sstevel@tonic-gate if (*(unsigned char *)(dp->sname) != '\0') { 217*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 218*0Sstevel@tonic-gate "Server Name = %s", dp->sname); 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate if (*(unsigned char *)(dp->file) != '\0') { 221*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 222*0Sstevel@tonic-gate "Boot File Name = %s", dp->file); 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate break; 225*0Sstevel@tonic-gate case 1: 226*0Sstevel@tonic-gate /* file field used */ 227*0Sstevel@tonic-gate if (*(unsigned char *)(dp->sname) != '\0') { 228*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 229*0Sstevel@tonic-gate "Server Name = %s", dp->sname); 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate show_space(); 232*0Sstevel@tonic-gate show_header("DHCP: ", "(File) field options", len); 233*0Sstevel@tonic-gate show_space(); 234*0Sstevel@tonic-gate (void) show_options(dp->file, 128); 235*0Sstevel@tonic-gate break; 236*0Sstevel@tonic-gate case 2: 237*0Sstevel@tonic-gate /* sname field used for options */ 238*0Sstevel@tonic-gate if (*(unsigned char *)(dp->file) != '\0') { 239*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 240*0Sstevel@tonic-gate "Boot File Name = %s", dp->file); 241*0Sstevel@tonic-gate } 242*0Sstevel@tonic-gate show_space(); 243*0Sstevel@tonic-gate show_header("DHCP: ", "(Sname) field options", len); 244*0Sstevel@tonic-gate show_space(); 245*0Sstevel@tonic-gate (void) show_options(dp->sname, 64); 246*0Sstevel@tonic-gate break; 247*0Sstevel@tonic-gate case 3: 248*0Sstevel@tonic-gate show_space(); 249*0Sstevel@tonic-gate show_header("DHCP: ", "(File) field options", len); 250*0Sstevel@tonic-gate show_space(); 251*0Sstevel@tonic-gate (void) show_options(dp->file, 128); 252*0Sstevel@tonic-gate show_space(); 253*0Sstevel@tonic-gate show_header("DHCP: ", "(Sname) field options", len); 254*0Sstevel@tonic-gate show_space(); 255*0Sstevel@tonic-gate (void) show_options(dp->sname, 64); 256*0Sstevel@tonic-gate break; 257*0Sstevel@tonic-gate }; 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate return (len); 260*0Sstevel@tonic-gate } 261*0Sstevel@tonic-gate static int 262*0Sstevel@tonic-gate show_options(unsigned char *cp, int len) 263*0Sstevel@tonic-gate { 264*0Sstevel@tonic-gate char *prmpt; 265*0Sstevel@tonic-gate unsigned char *end, *vend; 266*0Sstevel@tonic-gate unsigned char *start, save; 267*0Sstevel@tonic-gate int items, i; 268*0Sstevel@tonic-gate int nooverload = 0; 269*0Sstevel@tonic-gate ushort_t s_buf; 270*0Sstevel@tonic-gate struct in_addr tmp; 271*0Sstevel@tonic-gate char scratch[128]; 272*0Sstevel@tonic-gate dhcp_symbol_t *entry; 273*0Sstevel@tonic-gate char *decoded_opt; 274*0Sstevel@tonic-gate int opt_len; 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate start = cp; 277*0Sstevel@tonic-gate end = (unsigned char *)cp + len; 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate while (start < end) { 280*0Sstevel@tonic-gate if (*start == CD_PAD) { 281*0Sstevel@tonic-gate start++; 282*0Sstevel@tonic-gate continue; 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate if (*start == CD_END) 285*0Sstevel@tonic-gate break; /* done */ 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate save = *start++; 288*0Sstevel@tonic-gate switch (save) { 289*0Sstevel@tonic-gate /* Network order IP address(es) */ 290*0Sstevel@tonic-gate case CD_SUBNETMASK: 291*0Sstevel@tonic-gate case CD_ROUTER_SOLICIT_SERV: 292*0Sstevel@tonic-gate case CD_BROADCASTADDR: 293*0Sstevel@tonic-gate case CD_REQUESTED_IP_ADDR: 294*0Sstevel@tonic-gate case CD_SERVER_ID: 295*0Sstevel@tonic-gate /* Single IP address */ 296*0Sstevel@tonic-gate if (*start != 4) { 297*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 298*0Sstevel@tonic-gate "Error: Bad %s", option_types[save]); 299*0Sstevel@tonic-gate } else { 300*0Sstevel@tonic-gate start++; 301*0Sstevel@tonic-gate display_ip(1, "%s = %s", option_types[save], 302*0Sstevel@tonic-gate &start); 303*0Sstevel@tonic-gate } 304*0Sstevel@tonic-gate break; 305*0Sstevel@tonic-gate case CD_ROUTER: 306*0Sstevel@tonic-gate case CD_TIMESERV: 307*0Sstevel@tonic-gate case CD_IEN116_NAME_SERV: 308*0Sstevel@tonic-gate case CD_DNSSERV: 309*0Sstevel@tonic-gate case CD_LOG_SERV: 310*0Sstevel@tonic-gate case CD_COOKIE_SERV: 311*0Sstevel@tonic-gate case CD_LPR_SERV: 312*0Sstevel@tonic-gate case CD_IMPRESS_SERV: 313*0Sstevel@tonic-gate case CD_RESOURCE_SERV: 314*0Sstevel@tonic-gate case CD_SWAP_SERV: 315*0Sstevel@tonic-gate case CD_NIS_SERV: 316*0Sstevel@tonic-gate case CD_NTP_SERV: 317*0Sstevel@tonic-gate case CD_NETBIOS_NAME_SERV: 318*0Sstevel@tonic-gate case CD_NETBIOS_DIST_SERV: 319*0Sstevel@tonic-gate case CD_XWIN_FONT_SERV: 320*0Sstevel@tonic-gate case CD_XWIN_DISP_SERV: 321*0Sstevel@tonic-gate case CD_NISPLUS_SERVS: 322*0Sstevel@tonic-gate case CD_MOBILE_IP_AGENT: 323*0Sstevel@tonic-gate case CD_SMTP_SERVS: 324*0Sstevel@tonic-gate case CD_POP3_SERVS: 325*0Sstevel@tonic-gate case CD_NNTP_SERVS: 326*0Sstevel@tonic-gate case CD_WWW_SERVS: 327*0Sstevel@tonic-gate case CD_FINGER_SERVS: 328*0Sstevel@tonic-gate case CD_IRC_SERVS: 329*0Sstevel@tonic-gate case CD_STREETTALK_SERVS: 330*0Sstevel@tonic-gate case CD_STREETTALK_DA_SERVS: 331*0Sstevel@tonic-gate /* Multiple IP addresses */ 332*0Sstevel@tonic-gate if ((*start % 4) != 0) { 333*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 334*0Sstevel@tonic-gate "Error: Bad %s address", 335*0Sstevel@tonic-gate option_types[save]); 336*0Sstevel@tonic-gate } else { 337*0Sstevel@tonic-gate display_ip((*start++ / 4), "%s at = %s", 338*0Sstevel@tonic-gate option_types[save], &start); 339*0Sstevel@tonic-gate } 340*0Sstevel@tonic-gate break; 341*0Sstevel@tonic-gate case CD_TFTP_SERV_NAME: 342*0Sstevel@tonic-gate case CD_HOSTNAME: 343*0Sstevel@tonic-gate case CD_DUMP_FILE: 344*0Sstevel@tonic-gate case CD_DNSDOMAIN: 345*0Sstevel@tonic-gate case CD_ROOT_PATH: 346*0Sstevel@tonic-gate case CD_NIS_DOMAIN: 347*0Sstevel@tonic-gate case CD_NETBIOS_SCOPE: 348*0Sstevel@tonic-gate case CD_MESSAGE: 349*0Sstevel@tonic-gate case CD_NISPLUS_DMAIN: 350*0Sstevel@tonic-gate case CD_OPT_BOOTFILE_NAME: 351*0Sstevel@tonic-gate case CD_USER_CLASS_ID: 352*0Sstevel@tonic-gate /* Ascii strings */ 353*0Sstevel@tonic-gate display_ascii("%s = %s", option_types[save], &start); 354*0Sstevel@tonic-gate break; 355*0Sstevel@tonic-gate case CD_TIMEOFFSET: 356*0Sstevel@tonic-gate case CD_IPTTL: 357*0Sstevel@tonic-gate case CD_PATH_MTU_TIMEOUT: 358*0Sstevel@tonic-gate case CD_ARP_TIMEOUT: 359*0Sstevel@tonic-gate case CD_TCP_TTL: 360*0Sstevel@tonic-gate case CD_TCP_KALIVE_INTVL: 361*0Sstevel@tonic-gate case CD_T1_TIME: 362*0Sstevel@tonic-gate case CD_T2_TIME: 363*0Sstevel@tonic-gate case CD_LEASE_TIME: 364*0Sstevel@tonic-gate /* Number: seconds */ 365*0Sstevel@tonic-gate display_number("%s = %d seconds", option_types[save], 366*0Sstevel@tonic-gate &start); 367*0Sstevel@tonic-gate break; 368*0Sstevel@tonic-gate case CD_IP_FORWARDING_ON: 369*0Sstevel@tonic-gate case CD_NON_LCL_ROUTE_ON: 370*0Sstevel@tonic-gate case CD_ALL_SUBNETS_LCL_ON: 371*0Sstevel@tonic-gate case CD_MASK_DISCVRY_ON: 372*0Sstevel@tonic-gate case CD_MASK_SUPPLIER_ON: 373*0Sstevel@tonic-gate case CD_ROUTER_DISCVRY_ON: 374*0Sstevel@tonic-gate case CD_TRAILER_ENCAPS_ON: 375*0Sstevel@tonic-gate case CD_ETHERNET_ENCAPS_ON: 376*0Sstevel@tonic-gate case CD_TCP_KALIVE_GRBG_ON: 377*0Sstevel@tonic-gate /* Number: hex flag */ 378*0Sstevel@tonic-gate display_number("%s flag = 0x%x", option_types[save], 379*0Sstevel@tonic-gate &start); 380*0Sstevel@tonic-gate break; 381*0Sstevel@tonic-gate case CD_MAXIPSIZE: 382*0Sstevel@tonic-gate case CD_MTU: 383*0Sstevel@tonic-gate case CD_MAX_DHCP_SIZE: 384*0Sstevel@tonic-gate /* Number: bytes */ 385*0Sstevel@tonic-gate display_number("%s = %d bytes", option_types[save], 386*0Sstevel@tonic-gate &start); 387*0Sstevel@tonic-gate break; 388*0Sstevel@tonic-gate case CD_CLASS_ID: 389*0Sstevel@tonic-gate case CD_CLIENT_ID: 390*0Sstevel@tonic-gate case CD_NW_IP_DOMAIN: 391*0Sstevel@tonic-gate case CD_NW_IP_OPTIONS: 392*0Sstevel@tonic-gate /* Hex ascii strings */ 393*0Sstevel@tonic-gate display_ascii_hex(option_types[save], &start); 394*0Sstevel@tonic-gate break; 395*0Sstevel@tonic-gate case CD_BOOT_SIZE: 396*0Sstevel@tonic-gate display_number("%s = %d 512 byte blocks", 397*0Sstevel@tonic-gate "Boot file size", &start); 398*0Sstevel@tonic-gate break; 399*0Sstevel@tonic-gate case CD_POLICY_FILTER: 400*0Sstevel@tonic-gate if ((*start % 8) != 0) { 401*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 402*0Sstevel@tonic-gate "Error: Bad Policy Filter option"); 403*0Sstevel@tonic-gate } else { 404*0Sstevel@tonic-gate items = *start++ / 8; 405*0Sstevel@tonic-gate for (i = 0; i < items; i++) { 406*0Sstevel@tonic-gate display_ip(1, 407*0Sstevel@tonic-gate "%s = %s", 408*0Sstevel@tonic-gate "Policy Destination", 409*0Sstevel@tonic-gate &start); 410*0Sstevel@tonic-gate display_ip(1, "%s = %s", "Mask", 411*0Sstevel@tonic-gate &start); 412*0Sstevel@tonic-gate } 413*0Sstevel@tonic-gate } 414*0Sstevel@tonic-gate break; 415*0Sstevel@tonic-gate case CD_PATH_MTU_TABLE_SZ: 416*0Sstevel@tonic-gate if (*start % 2 != 0) { 417*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 418*0Sstevel@tonic-gate "Error: Bad Path MTU Table"); 419*0Sstevel@tonic-gate } else { 420*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 421*0Sstevel@tonic-gate "\tPath MTU Plateau Table:"); 422*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 423*0Sstevel@tonic-gate "\t======================="); 424*0Sstevel@tonic-gate items = *start / sizeof (ushort_t); 425*0Sstevel@tonic-gate ++start; 426*0Sstevel@tonic-gate for (i = 0; i < items; i++) { 427*0Sstevel@tonic-gate if (IS_P2ALIGNED(start, 428*0Sstevel@tonic-gate sizeof (ushort_t))) { 429*0Sstevel@tonic-gate /* LINTED: improper alignment */ 430*0Sstevel@tonic-gate s_buf = *(ushort_t *)start; 431*0Sstevel@tonic-gate } else { 432*0Sstevel@tonic-gate memcpy((char *)&s_buf, 433*0Sstevel@tonic-gate start, sizeof (short)); 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 436*0Sstevel@tonic-gate "\t\tEntry %d:\t\t%d", i, 437*0Sstevel@tonic-gate ntohs(s_buf)); 438*0Sstevel@tonic-gate start += sizeof (ushort_t); 439*0Sstevel@tonic-gate } 440*0Sstevel@tonic-gate } 441*0Sstevel@tonic-gate break; 442*0Sstevel@tonic-gate case CD_STATIC_ROUTE: 443*0Sstevel@tonic-gate if ((*start % 8) != 0) { 444*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 445*0Sstevel@tonic-gate "Error: Bad Static Route option: %d", 446*0Sstevel@tonic-gate *start); 447*0Sstevel@tonic-gate } else { 448*0Sstevel@tonic-gate items = *start++ / 8; 449*0Sstevel@tonic-gate for (i = 0; i < items; i++) { 450*0Sstevel@tonic-gate memcpy((char *)&tmp, start, 451*0Sstevel@tonic-gate sizeof (struct in_addr)); 452*0Sstevel@tonic-gate (void) strcpy(scratch, inet_ntoa(tmp)); 453*0Sstevel@tonic-gate start += sizeof (ulong_t); 454*0Sstevel@tonic-gate memcpy((char *)&tmp, start, 455*0Sstevel@tonic-gate sizeof (struct in_addr)); 456*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 457*0Sstevel@tonic-gate "Static route from %s to %s", 458*0Sstevel@tonic-gate scratch, inet_ntoa(tmp)); 459*0Sstevel@tonic-gate start += sizeof (ulong_t); 460*0Sstevel@tonic-gate } 461*0Sstevel@tonic-gate } 462*0Sstevel@tonic-gate break; 463*0Sstevel@tonic-gate case CD_VENDOR_SPEC: 464*0Sstevel@tonic-gate i = *start++; 465*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 466*0Sstevel@tonic-gate "Vendor-specific Options (%d total octets):", i); 467*0Sstevel@tonic-gate /* 468*0Sstevel@tonic-gate * We don't know what these things are, so just 469*0Sstevel@tonic-gate * display the option number, length, and value 470*0Sstevel@tonic-gate * (hex). 471*0Sstevel@tonic-gate */ 472*0Sstevel@tonic-gate vend = (uchar_t *)((uchar_t *)start + i); 473*0Sstevel@tonic-gate while (start < vend && *start != CD_END) { 474*0Sstevel@tonic-gate if (*start == CD_PAD) { 475*0Sstevel@tonic-gate start++; 476*0Sstevel@tonic-gate continue; 477*0Sstevel@tonic-gate } 478*0Sstevel@tonic-gate (void) sprintf(scratch, 479*0Sstevel@tonic-gate "\t(%.2d) %.2d octets", *start, 480*0Sstevel@tonic-gate *(uchar_t *)((uchar_t *)start + 1)); 481*0Sstevel@tonic-gate start++; 482*0Sstevel@tonic-gate display_ascii_hex(scratch, &start); 483*0Sstevel@tonic-gate } 484*0Sstevel@tonic-gate start = vend; /* in case CD_END found */ 485*0Sstevel@tonic-gate break; 486*0Sstevel@tonic-gate case CD_NETBIOS_NODE_TYPE: 487*0Sstevel@tonic-gate if (*start != 1) { 488*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 489*0Sstevel@tonic-gate "Error: Bad '%s' parameter", 490*0Sstevel@tonic-gate option_types[CD_NETBIOS_NODE_TYPE]); 491*0Sstevel@tonic-gate } else { 492*0Sstevel@tonic-gate char *type; 493*0Sstevel@tonic-gate start++; 494*0Sstevel@tonic-gate switch (*start) { 495*0Sstevel@tonic-gate case 0x1: 496*0Sstevel@tonic-gate type = "Broadcast Node"; 497*0Sstevel@tonic-gate break; 498*0Sstevel@tonic-gate case 0x2: 499*0Sstevel@tonic-gate type = "Point To Point Node"; 500*0Sstevel@tonic-gate break; 501*0Sstevel@tonic-gate case 0x4: 502*0Sstevel@tonic-gate type = "Mixed Mode Node"; 503*0Sstevel@tonic-gate break; 504*0Sstevel@tonic-gate case 0x8: 505*0Sstevel@tonic-gate type = "Hybrid Node"; 506*0Sstevel@tonic-gate break; 507*0Sstevel@tonic-gate default: 508*0Sstevel@tonic-gate type = "??? Node"; 509*0Sstevel@tonic-gate break; 510*0Sstevel@tonic-gate }; 511*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 512*0Sstevel@tonic-gate "%s = %s (%d)", 513*0Sstevel@tonic-gate option_types[CD_NETBIOS_NODE_TYPE], 514*0Sstevel@tonic-gate type, *start); 515*0Sstevel@tonic-gate start++; 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate break; 518*0Sstevel@tonic-gate case CD_OPTION_OVERLOAD: 519*0Sstevel@tonic-gate if (*start != 1) { 520*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 521*0Sstevel@tonic-gate "Bad Option Overload value."); 522*0Sstevel@tonic-gate } else { 523*0Sstevel@tonic-gate start++; 524*0Sstevel@tonic-gate nooverload = *start++; 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate break; 527*0Sstevel@tonic-gate case CD_DHCP_TYPE: 528*0Sstevel@tonic-gate if (*start < 1 || *start > 7) { 529*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 530*0Sstevel@tonic-gate "Bad DHCP Message Type."); 531*0Sstevel@tonic-gate } else { 532*0Sstevel@tonic-gate start++; 533*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 534*0Sstevel@tonic-gate "Message type = %s", 535*0Sstevel@tonic-gate show_msgtype(*start)); 536*0Sstevel@tonic-gate start++; 537*0Sstevel@tonic-gate } 538*0Sstevel@tonic-gate break; 539*0Sstevel@tonic-gate case CD_REQUEST_LIST: 540*0Sstevel@tonic-gate opt_len = *start++; 541*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 542*0Sstevel@tonic-gate "Requested Options:"); 543*0Sstevel@tonic-gate for (i = 0; i < opt_len; i++) { 544*0Sstevel@tonic-gate entry = NULL; 545*0Sstevel@tonic-gate if (*start < OPTIONS_ARRAY_SIZE) { 546*0Sstevel@tonic-gate prmpt = option_types[*start]; 547*0Sstevel@tonic-gate } else { 548*0Sstevel@tonic-gate entry = inittab_getbycode( 549*0Sstevel@tonic-gate ITAB_CAT_STANDARD|ITAB_CAT_SITE, 550*0Sstevel@tonic-gate ITAB_CONS_SNOOP, *start); 551*0Sstevel@tonic-gate if (entry == NULL) { 552*0Sstevel@tonic-gate if (*start >= DHCP_SITE_OPT && 553*0Sstevel@tonic-gate *start <= DHCP_END_SITE) { 554*0Sstevel@tonic-gate prmpt = "Site Option"; 555*0Sstevel@tonic-gate } else { 556*0Sstevel@tonic-gate prmpt = "Unrecognized " 557*0Sstevel@tonic-gate "Option"; 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate } else { 560*0Sstevel@tonic-gate prmpt = entry->ds_name; 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate } 563*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 564*0Sstevel@tonic-gate "\t%2d (%s)", *start, prmpt); 565*0Sstevel@tonic-gate start++; 566*0Sstevel@tonic-gate free(entry); 567*0Sstevel@tonic-gate } 568*0Sstevel@tonic-gate break; 569*0Sstevel@tonic-gate default: 570*0Sstevel@tonic-gate opt_len = *start++; 571*0Sstevel@tonic-gate entry = inittab_getbycode( 572*0Sstevel@tonic-gate ITAB_CAT_STANDARD|ITAB_CAT_SITE, 573*0Sstevel@tonic-gate ITAB_CONS_SNOOP, save); 574*0Sstevel@tonic-gate if (entry == NULL) { 575*0Sstevel@tonic-gate if (save >= DHCP_SITE_OPT && 576*0Sstevel@tonic-gate save <= DHCP_END_SITE) 577*0Sstevel@tonic-gate prmpt = "Site"; 578*0Sstevel@tonic-gate else 579*0Sstevel@tonic-gate prmpt = "Unrecognized"; 580*0Sstevel@tonic-gate decoded_opt = NULL; 581*0Sstevel@tonic-gate } else { 582*0Sstevel@tonic-gate if (save < OPTIONS_ARRAY_SIZE) { 583*0Sstevel@tonic-gate prmpt = option_types[save]; 584*0Sstevel@tonic-gate } else { 585*0Sstevel@tonic-gate prmpt = entry->ds_name; 586*0Sstevel@tonic-gate } 587*0Sstevel@tonic-gate decoded_opt = inittab_decode(entry, start, 588*0Sstevel@tonic-gate opt_len, B_TRUE); 589*0Sstevel@tonic-gate } 590*0Sstevel@tonic-gate if (decoded_opt == NULL) { 591*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), 592*0Sstevel@tonic-gate "%s Option = %d, length = %d octets", 593*0Sstevel@tonic-gate prmpt, save, opt_len); 594*0Sstevel@tonic-gate start--; 595*0Sstevel@tonic-gate display_ascii_hex("\tValue =", &start); 596*0Sstevel@tonic-gate } else { 597*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), "%s = %s", prmpt, 598*0Sstevel@tonic-gate decoded_opt); 599*0Sstevel@tonic-gate start += opt_len; 600*0Sstevel@tonic-gate free(decoded_opt); 601*0Sstevel@tonic-gate } 602*0Sstevel@tonic-gate free(entry); 603*0Sstevel@tonic-gate break; 604*0Sstevel@tonic-gate }; 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate return (nooverload); 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate static char * 609*0Sstevel@tonic-gate show_htype(int t) 610*0Sstevel@tonic-gate { 611*0Sstevel@tonic-gate switch (t) { 612*0Sstevel@tonic-gate case 1: 613*0Sstevel@tonic-gate return ("Ethernet (10Mb)"); 614*0Sstevel@tonic-gate case 2: 615*0Sstevel@tonic-gate return ("Experimental Ethernet (3MB)"); 616*0Sstevel@tonic-gate case 3: 617*0Sstevel@tonic-gate return ("Amateur Radio AX.25"); 618*0Sstevel@tonic-gate case 4: 619*0Sstevel@tonic-gate return ("Proteon ProNET Token Ring"); 620*0Sstevel@tonic-gate case 5: 621*0Sstevel@tonic-gate return ("Chaos"); 622*0Sstevel@tonic-gate case 6: 623*0Sstevel@tonic-gate return ("IEEE 802"); 624*0Sstevel@tonic-gate case 7: 625*0Sstevel@tonic-gate return ("ARCNET"); 626*0Sstevel@tonic-gate case 8: 627*0Sstevel@tonic-gate return ("Hyperchannel"); 628*0Sstevel@tonic-gate case 9: 629*0Sstevel@tonic-gate return ("Lanstar"); 630*0Sstevel@tonic-gate case 10: 631*0Sstevel@tonic-gate return ("Autonet"); 632*0Sstevel@tonic-gate case 11: 633*0Sstevel@tonic-gate return ("LocalTalk"); 634*0Sstevel@tonic-gate case 12: 635*0Sstevel@tonic-gate return ("LocalNet"); 636*0Sstevel@tonic-gate case 13: 637*0Sstevel@tonic-gate return ("Ultra Link"); 638*0Sstevel@tonic-gate case 14: 639*0Sstevel@tonic-gate return ("SMDS"); 640*0Sstevel@tonic-gate case 15: 641*0Sstevel@tonic-gate return ("Frame Relay"); 642*0Sstevel@tonic-gate case 16: 643*0Sstevel@tonic-gate return ("ATM"); 644*0Sstevel@tonic-gate case ARPHRD_IB: 645*0Sstevel@tonic-gate return ("IPIB"); 646*0Sstevel@tonic-gate }; 647*0Sstevel@tonic-gate return ("UNKNOWN"); 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate static const char * 650*0Sstevel@tonic-gate show_msgtype(unsigned char type) 651*0Sstevel@tonic-gate { 652*0Sstevel@tonic-gate /* 653*0Sstevel@tonic-gate * note: the ordering here allows direct indexing of the table 654*0Sstevel@tonic-gate * based on the RFC2131 packet type value passed in. 655*0Sstevel@tonic-gate */ 656*0Sstevel@tonic-gate 657*0Sstevel@tonic-gate static const char *types[] = { 658*0Sstevel@tonic-gate "BOOTP", 659*0Sstevel@tonic-gate "DHCPDISCOVER", "DHCPOFFER", "DHCPREQUEST", "DHCPDECLINE", 660*0Sstevel@tonic-gate "DHCPACK", "DHCPNAK", "DHCPRELEASE", "DHCPINFORM" 661*0Sstevel@tonic-gate }; 662*0Sstevel@tonic-gate 663*0Sstevel@tonic-gate if (type > (sizeof (types) / sizeof (*types)) || types[type] == NULL) 664*0Sstevel@tonic-gate return ("UNKNOWN"); 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate return (types[type]); 667*0Sstevel@tonic-gate } 668*0Sstevel@tonic-gate static void 669*0Sstevel@tonic-gate display_ip(int items, char *fmt, char *msg, unsigned char **opt) 670*0Sstevel@tonic-gate { 671*0Sstevel@tonic-gate struct in_addr tmp; 672*0Sstevel@tonic-gate int i; 673*0Sstevel@tonic-gate 674*0Sstevel@tonic-gate for (i = 0; i < items; i++) { 675*0Sstevel@tonic-gate memcpy((char *)&tmp, *opt, sizeof (struct in_addr)); 676*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, inet_ntoa(tmp)); 677*0Sstevel@tonic-gate *opt += 4; 678*0Sstevel@tonic-gate } 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate static void 681*0Sstevel@tonic-gate display_ascii(char *fmt, char *msg, unsigned char **opt) 682*0Sstevel@tonic-gate { 683*0Sstevel@tonic-gate static unsigned char buf[256]; 684*0Sstevel@tonic-gate unsigned char len = **opt; 685*0Sstevel@tonic-gate unsigned char slen = len; 686*0Sstevel@tonic-gate 687*0Sstevel@tonic-gate if (len >= sizeof (buf)) 688*0Sstevel@tonic-gate len = sizeof (buf) - 1; 689*0Sstevel@tonic-gate (*opt)++; 690*0Sstevel@tonic-gate memcpy(buf, *opt, len); 691*0Sstevel@tonic-gate *(unsigned char *)(buf + len) = '\0'; 692*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, buf); 693*0Sstevel@tonic-gate (*opt) += slen; 694*0Sstevel@tonic-gate } 695*0Sstevel@tonic-gate static void 696*0Sstevel@tonic-gate display_number(char *fmt, char *msg, unsigned char **opt) 697*0Sstevel@tonic-gate { 698*0Sstevel@tonic-gate int len = **opt; 699*0Sstevel@tonic-gate unsigned long l_buf = 0; 700*0Sstevel@tonic-gate unsigned short s_buf = 0; 701*0Sstevel@tonic-gate 702*0Sstevel@tonic-gate if (len > 4) { 703*0Sstevel@tonic-gate (*opt)++; 704*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, 0xdeadbeef); 705*0Sstevel@tonic-gate return; 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate switch (len) { 708*0Sstevel@tonic-gate case sizeof (uchar_t): 709*0Sstevel@tonic-gate (*opt)++; 710*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, **opt); 711*0Sstevel@tonic-gate break; 712*0Sstevel@tonic-gate case sizeof (ushort_t): 713*0Sstevel@tonic-gate (*opt)++; 714*0Sstevel@tonic-gate if (IS_P2ALIGNED(*opt, sizeof (ushort_t))) 715*0Sstevel@tonic-gate /* LINTED: improper alignment */ 716*0Sstevel@tonic-gate s_buf = *(unsigned short *)*opt; 717*0Sstevel@tonic-gate else 718*0Sstevel@tonic-gate memcpy((char *)&s_buf, *opt, len); 719*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, ntohs(s_buf)); 720*0Sstevel@tonic-gate break; 721*0Sstevel@tonic-gate case sizeof (ulong_t): 722*0Sstevel@tonic-gate (*opt)++; 723*0Sstevel@tonic-gate if (IS_P2ALIGNED(*opt, sizeof (ulong_t))) 724*0Sstevel@tonic-gate /* LINTED: improper alignment */ 725*0Sstevel@tonic-gate l_buf = *(unsigned long *)*opt; 726*0Sstevel@tonic-gate else 727*0Sstevel@tonic-gate memcpy((char *)&l_buf, *opt, len); 728*0Sstevel@tonic-gate (void) sprintf(get_line(0, 0), fmt, msg, ntohl(l_buf)); 729*0Sstevel@tonic-gate break; 730*0Sstevel@tonic-gate } 731*0Sstevel@tonic-gate (*opt) += len; 732*0Sstevel@tonic-gate } 733*0Sstevel@tonic-gate static void 734*0Sstevel@tonic-gate display_ascii_hex(char *msg, unsigned char **opt) 735*0Sstevel@tonic-gate { 736*0Sstevel@tonic-gate int printable; 737*0Sstevel@tonic-gate char buffer[512]; 738*0Sstevel@tonic-gate char *line, *tmp, *ap, *fmt; 739*0Sstevel@tonic-gate int i, j, len = **opt; 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate line = get_line(0, 0); 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate (*opt)++; 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gate if (len >= 255) { 746*0Sstevel@tonic-gate (void) sprintf(line, "\t%s <TOO LONG>", msg); 747*0Sstevel@tonic-gate return; 748*0Sstevel@tonic-gate } 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate for (printable = 1, tmp = (char *)(*opt), ap = buffer; 751*0Sstevel@tonic-gate tmp < (char *)&((*opt)[len]); tmp++) { 752*0Sstevel@tonic-gate if (isprint(*tmp)) 753*0Sstevel@tonic-gate *ap++ = *tmp; 754*0Sstevel@tonic-gate else { 755*0Sstevel@tonic-gate *ap++ = '.'; 756*0Sstevel@tonic-gate printable = 0; 757*0Sstevel@tonic-gate } 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate *ap = '\0'; 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate if (!printable) { 762*0Sstevel@tonic-gate for (tmp = (char *)(*opt), ap = buffer; 763*0Sstevel@tonic-gate (tmp < (char *)&((*opt)[len])) && (ap < &buffer[512]); 764*0Sstevel@tonic-gate tmp++) { 765*0Sstevel@tonic-gate ap += sprintf(ap, "0x%02X ", *(uchar_t *)(tmp)); 766*0Sstevel@tonic-gate } 767*0Sstevel@tonic-gate *(--ap) = '\0'; 768*0Sstevel@tonic-gate i = ap - buffer; 769*0Sstevel@tonic-gate fmt = "%s\t%s (unprintable)"; 770*0Sstevel@tonic-gate } else { 771*0Sstevel@tonic-gate i = strlen(buffer); 772*0Sstevel@tonic-gate fmt = "%s\t\"%s\""; 773*0Sstevel@tonic-gate } 774*0Sstevel@tonic-gate (*opt) += len; 775*0Sstevel@tonic-gate j = strlen(msg) + (MAXLINE / 2) - 30; 776*0Sstevel@tonic-gate if (i > j) { 777*0Sstevel@tonic-gate buffer[j - 1] = '.'; 778*0Sstevel@tonic-gate buffer[j - 2] = '.'; 779*0Sstevel@tonic-gate buffer[j - 3] = '.'; 780*0Sstevel@tonic-gate buffer[j] = '\0'; 781*0Sstevel@tonic-gate } 782*0Sstevel@tonic-gate (void) sprintf(line, fmt, msg, buffer); 783*0Sstevel@tonic-gate } 784