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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. 24 * Copyright 2015 Joyent, Inc. 25 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #include <sys/sysmacros.h> 30 #include <sys/param.h> 31 32 #include <smbios.h> 33 #include <alloca.h> 34 #include <limits.h> 35 #include <unistd.h> 36 #include <strings.h> 37 #include <stdlib.h> 38 #include <stdarg.h> 39 #include <stdio.h> 40 #include <fcntl.h> 41 #include <errno.h> 42 #include <ctype.h> 43 44 #define SMBIOS_SUCCESS 0 45 #define SMBIOS_ERROR 1 46 #define SMBIOS_USAGE 2 47 48 static const char *g_pname; 49 static int g_hdr; 50 51 static int opt_e; 52 static int opt_i = -1; 53 static int opt_O; 54 static int opt_s; 55 static int opt_t = -1; 56 static int opt_x; 57 58 /*PRINTFLIKE2*/ 59 static void 60 oprintf(FILE *fp, const char *format, ...) 61 { 62 va_list ap; 63 64 va_start(ap, format); 65 (void) vfprintf(fp, format, ap); 66 va_end(ap); 67 } 68 69 /*PRINTFLIKE3*/ 70 static void 71 desc_printf(const char *d, FILE *fp, const char *format, ...) 72 { 73 va_list ap; 74 75 va_start(ap, format); 76 (void) vfprintf(fp, format, ap); 77 va_end(ap); 78 79 if (d != NULL) 80 (void) fprintf(fp, " (%s)\n", d); 81 else 82 (void) fprintf(fp, "\n"); 83 } 84 85 static void 86 flag_printf(FILE *fp, const char *s, uint_t flags, size_t bits, 87 const char *(*flag_name)(uint_t), const char *(*flag_desc)(uint_t)) 88 { 89 size_t i; 90 91 oprintf(fp, " %s: 0x%x\n", s, flags); 92 93 for (i = 0; i < bits; i++) { 94 uint_t f = 1 << i; 95 const char *n; 96 97 if (!(flags & f)) 98 continue; 99 100 if ((n = flag_name(f)) != NULL) 101 desc_printf(flag_desc(f), fp, "\t%s", n); 102 else 103 desc_printf(flag_desc(f), fp, "\t0x%x", f); 104 } 105 } 106 107 static void 108 flag64_printf(FILE *fp, const char *s, uint64_t flags, size_t bits, 109 const char *(*flag_name)(uint64_t), const char *(*flag_desc)(uint64_t)) 110 { 111 size_t i; 112 113 oprintf(fp, " %s: 0x%llx\n", s, (u_longlong_t)flags); 114 115 for (i = 0; i < bits; i++) { 116 u_longlong_t f = 1ULL << i; 117 const char *n; 118 119 if (!(flags & f)) 120 continue; 121 122 if ((n = flag_name(f)) != NULL) 123 desc_printf(flag_desc(f), fp, "\t%s", n); 124 else 125 desc_printf(flag_desc(f), fp, "\t0x%llx", f); 126 } 127 } 128 129 static void 130 id_printf(FILE *fp, const char *s, id_t id) 131 { 132 switch (id) { 133 case SMB_ID_NONE: 134 oprintf(fp, "%sNone\n", s); 135 break; 136 case SMB_ID_NOTSUP: 137 oprintf(fp, "%sNot Supported\n", s); 138 break; 139 default: 140 oprintf(fp, "%s%u\n", s, (uint_t)id); 141 } 142 } 143 144 static int 145 check_oem(smbios_hdl_t *shp) 146 { 147 int i; 148 int cnt; 149 int rv; 150 id_t oem_id; 151 smbios_struct_t s; 152 const char **oem_str; 153 154 rv = smbios_lookup_type(shp, SMB_TYPE_OEMSTR, &s); 155 if (rv != 0) { 156 return (-1); 157 } 158 159 oem_id = s.smbstr_id; 160 161 cnt = smbios_info_strtab(shp, oem_id, 0, NULL); 162 if (cnt > 0) { 163 oem_str = alloca(sizeof (char *) * cnt); 164 (void) smbios_info_strtab(shp, oem_id, cnt, oem_str); 165 166 for (i = 0; i < cnt; i++) { 167 if (strncmp(oem_str[i], SMB_PRMS1, 168 strlen(SMB_PRMS1) + 1) == 0) { 169 return (0); 170 } 171 } 172 } 173 174 return (-1); 175 } 176 177 static void 178 print_smbios(smbios_hdl_t *shp, FILE *fp) 179 { 180 smbios_entry_t ep; 181 int i; 182 183 smbios_info_smbios(shp, &ep); 184 185 oprintf(fp, "Entry Point Anchor Tag: %*.*s\n", 186 (int)sizeof (ep.smbe_eanchor), (int)sizeof (ep.smbe_eanchor), 187 ep.smbe_eanchor); 188 189 oprintf(fp, "Entry Point Checksum: 0x%x\n", ep.smbe_ecksum); 190 oprintf(fp, "Entry Point Length: %u\n", ep.smbe_elen); 191 oprintf(fp, "Entry Point Version: %u.%u\n", 192 ep.smbe_major, ep.smbe_minor); 193 oprintf(fp, "Max Structure Size: %u\n", ep.smbe_maxssize); 194 oprintf(fp, "Entry Point Revision: 0x%x\n", ep.smbe_revision); 195 196 oprintf(fp, "Entry Point Revision Data:"); 197 for (i = 0; i < sizeof (ep.smbe_format); i++) 198 oprintf(fp, " 0x%02x", ep.smbe_format[i]); 199 oprintf(fp, "\n"); 200 201 oprintf(fp, "Intermediate Anchor Tag: %*.*s\n", 202 (int)sizeof (ep.smbe_ianchor), (int)sizeof (ep.smbe_ianchor), 203 ep.smbe_ianchor); 204 205 oprintf(fp, "Intermediate Checksum: 0x%x\n", ep.smbe_icksum); 206 oprintf(fp, "Structure Table Length: %u\n", ep.smbe_stlen); 207 oprintf(fp, "Structure Table Address: 0x%x\n", ep.smbe_staddr); 208 oprintf(fp, "Structure Table Entries: %u\n", ep.smbe_stnum); 209 oprintf(fp, "DMI BCD Revision: 0x%x\n", ep.smbe_bcdrev); 210 } 211 212 static void 213 print_common(const smbios_info_t *ip, FILE *fp) 214 { 215 if (ip->smbi_manufacturer[0] != '\0') 216 oprintf(fp, " Manufacturer: %s\n", ip->smbi_manufacturer); 217 if (ip->smbi_product[0] != '\0') 218 oprintf(fp, " Product: %s\n", ip->smbi_product); 219 if (ip->smbi_version[0] != '\0') 220 oprintf(fp, " Version: %s\n", ip->smbi_version); 221 if (ip->smbi_serial[0] != '\0') 222 oprintf(fp, " Serial Number: %s\n", ip->smbi_serial); 223 if (ip->smbi_asset[0] != '\0') 224 oprintf(fp, " Asset Tag: %s\n", ip->smbi_asset); 225 if (ip->smbi_location[0] != '\0') 226 oprintf(fp, " Location Tag: %s\n", ip->smbi_location); 227 if (ip->smbi_part[0] != '\0') 228 oprintf(fp, " Part Number: %s\n", ip->smbi_part); 229 } 230 231 static void 232 print_bios(smbios_hdl_t *shp, FILE *fp) 233 { 234 smbios_bios_t b; 235 236 (void) smbios_info_bios(shp, &b); 237 238 oprintf(fp, " Vendor: %s\n", b.smbb_vendor); 239 oprintf(fp, " Version String: %s\n", b.smbb_version); 240 oprintf(fp, " Release Date: %s\n", b.smbb_reldate); 241 oprintf(fp, " Address Segment: 0x%x\n", b.smbb_segment); 242 oprintf(fp, " ROM Size: %u bytes\n", b.smbb_romsize); 243 oprintf(fp, " Image Size: %u bytes\n", b.smbb_runsize); 244 245 flag64_printf(fp, "Characteristics", 246 b.smbb_cflags, sizeof (b.smbb_cflags) * NBBY, 247 smbios_bios_flag_name, smbios_bios_flag_desc); 248 249 if (b.smbb_nxcflags > SMB_BIOSXB_1) { 250 flag_printf(fp, "Characteristics Extension Byte 1", 251 b.smbb_xcflags[SMB_BIOSXB_1], 252 sizeof (b.smbb_xcflags[SMB_BIOSXB_1]) * NBBY, 253 smbios_bios_xb1_name, smbios_bios_xb1_desc); 254 } 255 256 if (b.smbb_nxcflags > SMB_BIOSXB_2) { 257 flag_printf(fp, "Characteristics Extension Byte 2", 258 b.smbb_xcflags[SMB_BIOSXB_2], 259 sizeof (b.smbb_xcflags[SMB_BIOSXB_2]) * NBBY, 260 smbios_bios_xb2_name, smbios_bios_xb2_desc); 261 } 262 263 if (b.smbb_nxcflags > SMB_BIOSXB_BIOS_MIN) { 264 oprintf(fp, " Version Number: %u.%u\n", 265 b.smbb_biosv.smbv_major, b.smbb_biosv.smbv_minor); 266 } 267 268 if (b.smbb_nxcflags > SMB_BIOSXB_ECFW_MIN) { 269 oprintf(fp, " Embedded Ctlr Firmware Version Number: %u.%u\n", 270 b.smbb_ecfwv.smbv_major, b.smbb_ecfwv.smbv_minor); 271 } 272 } 273 274 static void 275 print_system(smbios_hdl_t *shp, FILE *fp) 276 { 277 smbios_system_t s; 278 uint_t i; 279 280 (void) smbios_info_system(shp, &s); 281 282 oprintf(fp, " UUID: "); 283 for (i = 0; i < s.smbs_uuidlen; i++) { 284 oprintf(fp, "%02x", s.smbs_uuid[i]); 285 if (i == 3 || i == 5 || i == 7 || i == 9) 286 oprintf(fp, "-"); 287 } 288 oprintf(fp, "\n"); 289 290 desc_printf(smbios_system_wakeup_desc(s.smbs_wakeup), 291 fp, " Wake-Up Event: 0x%x", s.smbs_wakeup); 292 293 oprintf(fp, " SKU Number: %s\n", s.smbs_sku); 294 oprintf(fp, " Family: %s\n", s.smbs_family); 295 } 296 297 static void 298 print_bboard(smbios_hdl_t *shp, id_t id, FILE *fp) 299 { 300 smbios_bboard_t b; 301 int chdl_cnt; 302 303 (void) smbios_info_bboard(shp, id, &b); 304 305 oprintf(fp, " Chassis: %u\n", (uint_t)b.smbb_chassis); 306 307 flag_printf(fp, "Flags", b.smbb_flags, sizeof (b.smbb_flags) * NBBY, 308 smbios_bboard_flag_name, smbios_bboard_flag_desc); 309 310 desc_printf(smbios_bboard_type_desc(b.smbb_type), 311 fp, " Board Type: 0x%x", b.smbb_type); 312 313 chdl_cnt = b.smbb_contn; 314 if (chdl_cnt != 0) { 315 id_t *chdl; 316 uint16_t hdl; 317 int i, n, cnt; 318 319 chdl = alloca(chdl_cnt * sizeof (id_t)); 320 cnt = smbios_info_contains(shp, id, chdl_cnt, chdl); 321 if (cnt > SMB_CONT_MAX) 322 return; 323 n = MIN(chdl_cnt, cnt); 324 325 oprintf(fp, "\n"); 326 for (i = 0; i < n; i++) { 327 hdl = (uint16_t)chdl[i]; 328 oprintf(fp, " Contained Handle: %u\n", hdl); 329 } 330 } 331 } 332 333 static void 334 print_chassis(smbios_hdl_t *shp, id_t id, FILE *fp) 335 { 336 smbios_chassis_t c; 337 int elem_cnt; 338 339 (void) smbios_info_chassis(shp, id, &c); 340 341 oprintf(fp, " OEM Data: 0x%x\n", c.smbc_oemdata); 342 oprintf(fp, " SKU number: %s\n", 343 c.smbc_sku == NULL ? "<unknown>" : c.smbc_sku); 344 oprintf(fp, " Lock Present: %s\n", c.smbc_lock ? "Y" : "N"); 345 346 desc_printf(smbios_chassis_type_desc(c.smbc_type), 347 fp, " Chassis Type: 0x%x", c.smbc_type); 348 349 desc_printf(smbios_chassis_state_desc(c.smbc_bustate), 350 fp, " Boot-Up State: 0x%x", c.smbc_bustate); 351 352 desc_printf(smbios_chassis_state_desc(c.smbc_psstate), 353 fp, " Power Supply State: 0x%x", c.smbc_psstate); 354 355 desc_printf(smbios_chassis_state_desc(c.smbc_thstate), 356 fp, " Thermal State: 0x%x", c.smbc_thstate); 357 358 oprintf(fp, " Chassis Height: %uu\n", c.smbc_uheight); 359 oprintf(fp, " Power Cords: %u\n", c.smbc_cords); 360 361 elem_cnt = c.smbc_elems; 362 oprintf(fp, " Element Records: %u\n", elem_cnt); 363 364 if (elem_cnt > 0) { 365 id_t *elems; 366 uint8_t type; 367 int i, n, cnt; 368 369 elems = alloca(c.smbc_elems * sizeof (id_t)); 370 cnt = smbios_info_contains(shp, id, elem_cnt, elems); 371 if (cnt > SMB_CONT_MAX) 372 return; 373 n = MIN(elem_cnt, cnt); 374 375 oprintf(fp, "\n"); 376 for (i = 0; i < n; i++) { 377 type = (uint8_t)elems[i]; 378 if (type & 0x80) { 379 /* SMBIOS structrure Type */ 380 desc_printf(smbios_type_name(type & 0x7f), fp, 381 " Contained SMBIOS structure Type: %u", 382 type & 0x80); 383 } else { 384 /* SMBIOS Base Board Type */ 385 desc_printf(smbios_bboard_type_desc(type), fp, 386 " Contained SMBIOS Base Board Type: 0x%x", 387 type); 388 } 389 } 390 } 391 } 392 393 static void 394 print_processor(smbios_hdl_t *shp, id_t id, FILE *fp) 395 { 396 smbios_processor_t p; 397 uint_t status; 398 399 (void) smbios_info_processor(shp, id, &p); 400 status = SMB_PRSTATUS_STATUS(p.smbp_status); 401 402 desc_printf(smbios_processor_family_desc(p.smbp_family), 403 fp, " Family: %u", p.smbp_family); 404 405 if (p.smbp_family2 != 0) 406 desc_printf(smbios_processor_family_desc(p.smbp_family2), 407 fp, " Family Ext: %u", p.smbp_family2); 408 409 oprintf(fp, " CPUID: 0x%llx\n", (u_longlong_t)p.smbp_cpuid); 410 411 desc_printf(smbios_processor_type_desc(p.smbp_type), 412 fp, " Type: %u", p.smbp_type); 413 414 desc_printf(smbios_processor_upgrade_desc(p.smbp_upgrade), 415 fp, " Socket Upgrade: %u", p.smbp_upgrade); 416 417 oprintf(fp, " Socket Status: %s\n", 418 SMB_PRSTATUS_PRESENT(p.smbp_status) ? 419 "Populated" : "Not Populated"); 420 421 desc_printf(smbios_processor_status_desc(status), 422 fp, " Processor Status: %u", status); 423 424 if (SMB_PRV_LEGACY(p.smbp_voltage)) { 425 oprintf(fp, " Supported Voltages:"); 426 switch (p.smbp_voltage) { 427 case SMB_PRV_5V: 428 oprintf(fp, " 5.0V"); 429 break; 430 case SMB_PRV_33V: 431 oprintf(fp, " 3.3V"); 432 break; 433 case SMB_PRV_29V: 434 oprintf(fp, " 2.9V"); 435 break; 436 } 437 oprintf(fp, "\n"); 438 } else { 439 oprintf(fp, " Supported Voltages: %.1fV\n", 440 (float)SMB_PRV_VOLTAGE(p.smbp_voltage) / 10); 441 } 442 443 if (p.smbp_corecount != 0) { 444 if (p.smbp_corecount != 0xff || p.smbp_corecount2 == 0) 445 oprintf(fp, " Core Count: %u\n", p.smbp_corecount); 446 else 447 oprintf(fp, " Core Count: %u\n", p.smbp_corecount2); 448 } else { 449 oprintf(fp, " Core Count: Unknown\n"); 450 } 451 452 if (p.smbp_coresenabled != 0) { 453 if (p.smbp_coresenabled != 0xff || p.smbp_coresenabled2 == 0) { 454 oprintf(fp, " Cores Enabled: %u\n", 455 p.smbp_coresenabled); 456 } else { 457 oprintf(fp, " Cores Enabled: %u\n", 458 p.smbp_coresenabled2); 459 } 460 } else { 461 oprintf(fp, " Cores Enabled: Unknown\n"); 462 } 463 464 if (p.smbp_threadcount != 0) { 465 if (p.smbp_threadcount != 0xff || p.smbp_threadcount2 == 0) { 466 oprintf(fp, " Thread Count: %u\n", 467 p.smbp_threadcount); 468 } else { 469 oprintf(fp, " Thread Count: %u\n", 470 p.smbp_threadcount2); 471 } 472 } else { 473 oprintf(fp, " Thread Count: Unknown\n"); 474 } 475 476 if (p.smbp_cflags) { 477 flag_printf(fp, "Processor Characteristics", 478 p.smbp_cflags, sizeof (p.smbp_cflags) * NBBY, 479 smbios_processor_core_flag_name, 480 smbios_processor_core_flag_desc); 481 } 482 483 if (p.smbp_clkspeed != 0) 484 oprintf(fp, " External Clock Speed: %uMHz\n", p.smbp_clkspeed); 485 else 486 oprintf(fp, " External Clock Speed: Unknown\n"); 487 488 if (p.smbp_maxspeed != 0) 489 oprintf(fp, " Maximum Speed: %uMHz\n", p.smbp_maxspeed); 490 else 491 oprintf(fp, " Maximum Speed: Unknown\n"); 492 493 if (p.smbp_curspeed != 0) 494 oprintf(fp, " Current Speed: %uMHz\n", p.smbp_curspeed); 495 else 496 oprintf(fp, " Current Speed: Unknown\n"); 497 498 id_printf(fp, " L1 Cache: ", p.smbp_l1cache); 499 id_printf(fp, " L2 Cache: ", p.smbp_l2cache); 500 id_printf(fp, " L3 Cache: ", p.smbp_l3cache); 501 } 502 503 static void 504 print_cache(smbios_hdl_t *shp, id_t id, FILE *fp) 505 { 506 smbios_cache_t c; 507 508 (void) smbios_info_cache(shp, id, &c); 509 510 oprintf(fp, " Level: %u\n", c.smba_level); 511 oprintf(fp, " Maximum Installed Size: %u bytes\n", c.smba_maxsize); 512 513 if (c.smba_size != 0) 514 oprintf(fp, " Installed Size: %u bytes\n", c.smba_size); 515 else 516 oprintf(fp, " Installed Size: Not Installed\n"); 517 518 if (c.smba_speed != 0) 519 oprintf(fp, " Speed: %uns\n", c.smba_speed); 520 else 521 oprintf(fp, " Speed: Unknown\n"); 522 523 flag_printf(fp, "Supported SRAM Types", 524 c.smba_stype, sizeof (c.smba_stype) * NBBY, 525 smbios_cache_ctype_name, smbios_cache_ctype_desc); 526 527 desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 528 fp, " Current SRAM Type: 0x%x", c.smba_ctype); 529 530 desc_printf(smbios_cache_ecc_desc(c.smba_etype), 531 fp, " Error Correction Type: %u", c.smba_etype); 532 533 desc_printf(smbios_cache_logical_desc(c.smba_ltype), 534 fp, " Logical Cache Type: %u", c.smba_ltype); 535 536 desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 537 fp, " Associativity: %u", c.smba_assoc); 538 539 desc_printf(smbios_cache_mode_desc(c.smba_mode), 540 fp, " Mode: %u", c.smba_mode); 541 542 desc_printf(smbios_cache_loc_desc(c.smba_location), 543 fp, " Location: %u", c.smba_location); 544 545 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 546 smbios_cache_flag_name, smbios_cache_flag_desc); 547 } 548 549 static void 550 print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 551 { 552 smbios_port_t p; 553 554 (void) smbios_info_port(shp, id, &p); 555 556 oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref); 557 oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref); 558 559 desc_printf(smbios_port_conn_desc(p.smbo_itype), 560 fp, " Internal Connector Type: %u", p.smbo_itype); 561 562 desc_printf(smbios_port_conn_desc(p.smbo_etype), 563 fp, " External Connector Type: %u", p.smbo_etype); 564 565 desc_printf(smbios_port_type_desc(p.smbo_ptype), 566 fp, " Port Type: %u", p.smbo_ptype); 567 } 568 569 static void 570 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 571 { 572 smbios_slot_t s; 573 smbios_entry_t e; 574 575 (void) smbios_info_slot(shp, id, &s); 576 (void) smbios_info_smbios(shp, &e); 577 578 oprintf(fp, " Reference Designator: %s\n", s.smbl_name); 579 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 580 581 desc_printf(smbios_slot_type_desc(s.smbl_type), 582 fp, " Type: 0x%x", s.smbl_type); 583 584 desc_printf(smbios_slot_width_desc(s.smbl_width), 585 fp, " Width: 0x%x", s.smbl_width); 586 587 desc_printf(smbios_slot_usage_desc(s.smbl_usage), 588 fp, " Usage: 0x%x", s.smbl_usage); 589 590 desc_printf(smbios_slot_length_desc(s.smbl_length), 591 fp, " Length: 0x%x", s.smbl_length); 592 593 flag_printf(fp, "Slot Characteristics 1", 594 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 595 smbios_slot_ch1_name, smbios_slot_ch1_desc); 596 597 flag_printf(fp, "Slot Characteristics 2", 598 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 599 smbios_slot_ch2_name, smbios_slot_ch2_desc); 600 601 if (check_oem(shp) != 0 && (e.smbe_major < 2 || e.smbe_minor < 6)) 602 return; 603 604 oprintf(fp, " Segment Group: %u\n", s.smbl_sg); 605 oprintf(fp, " Bus Number: %u\n", s.smbl_bus); 606 oprintf(fp, " Device/Function Number: %u\n", s.smbl_df); 607 } 608 609 static void 610 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp) 611 { 612 boolean_t enabled; 613 smbios_obdev_ext_t oe; 614 const char *type; 615 616 (void) smbios_info_obdevs_ext(shp, id, &oe); 617 618 /* 619 * Bit 7 is always whether or not the device is enabled while bits 0:6 620 * are the actual device type. 621 */ 622 enabled = oe.smboe_dtype >> 7; 623 type = smbios_onboard_type_desc(oe.smboe_dtype & 0x7f); 624 625 oprintf(fp, " Reference Designator: %s\n", oe.smboe_name); 626 oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" : 627 "false"); 628 oprintf(fp, " Device Type: %s\n", type); 629 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti); 630 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg); 631 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus); 632 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df); 633 } 634 635 static void 636 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 637 { 638 smbios_obdev_t *argv; 639 int i, argc; 640 641 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 642 argv = alloca(sizeof (smbios_obdev_t) * argc); 643 (void) smbios_info_obdevs(shp, id, argc, argv); 644 for (i = 0; i < argc; i++) 645 oprintf(fp, " %s\n", argv[i].smbd_name); 646 } 647 } 648 649 static void 650 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 651 { 652 const char **argv; 653 int i, argc; 654 655 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 656 argv = alloca(sizeof (char *) * argc); 657 (void) smbios_info_strtab(shp, id, argc, argv); 658 for (i = 0; i < argc; i++) 659 oprintf(fp, " %s\n", argv[i]); 660 } 661 } 662 663 static void 664 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 665 { 666 smbios_lang_t l; 667 668 (void) smbios_info_lang(shp, &l); 669 670 oprintf(fp, " Current Language: %s\n", l.smbla_cur); 671 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 672 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 673 oprintf(fp, " Installed Languages:\n"); 674 675 print_strtab(shp, id, fp); 676 } 677 678 /*ARGSUSED*/ 679 static void 680 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 681 { 682 smbios_evlog_t ev; 683 uint32_t i; 684 685 (void) smbios_info_eventlog(shp, &ev); 686 687 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 688 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 689 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 690 691 desc_printf(smbios_evlog_method_desc(ev.smbev_method), 692 fp, " Data Access Method: %u", ev.smbev_method); 693 694 flag_printf(fp, "Log Flags", 695 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 696 smbios_evlog_flag_name, smbios_evlog_flag_desc); 697 698 desc_printf(smbios_evlog_format_desc(ev.smbev_format), 699 fp, " Log Header Format: %u", ev.smbev_format); 700 701 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 702 oprintf(fp, " Data Access Address: "); 703 704 switch (ev.smbev_method) { 705 case SMB_EVM_1x1i_1x1d: 706 case SMB_EVM_2x1i_1x1d: 707 case SMB_EVM_1x2i_1x1d: 708 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 709 ev.smbev_addr.eva_io.evi_iaddr, 710 ev.smbev_addr.eva_io.evi_daddr); 711 break; 712 case SMB_EVM_GPNV: 713 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 714 break; 715 default: 716 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 717 } 718 719 oprintf(fp, " Type Descriptors:\n"); 720 721 for (i = 0; i < ev.smbev_typec; i++) { 722 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 723 ev.smbev_typev[i].smbevt_ltype, 724 ev.smbev_typev[i].smbevt_dtype); 725 } 726 } 727 728 static void 729 print_bytes(const uint8_t *data, size_t size, FILE *fp) 730 { 731 size_t row, rows = P2ROUNDUP(size, 16) / 16; 732 size_t col, cols; 733 734 char buf[17]; 735 uint8_t x; 736 737 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 738 "0123456789abcdef\n"); 739 740 for (row = 0; row < rows; row++) { 741 oprintf(fp, " %#4lx: ", (ulong_t)row * 16); 742 cols = MIN(size - row * 16, 16); 743 744 for (col = 0; col < cols; col++) { 745 if (col % 4 == 0) 746 oprintf(fp, " "); 747 x = *data++; 748 oprintf(fp, "%02x", x); 749 buf[col] = x <= ' ' || x > '~' ? '.' : x; 750 } 751 752 for (; col < 16; col++) { 753 if (col % 4 == 0) 754 oprintf(fp, " "); 755 oprintf(fp, " "); 756 buf[col] = ' '; 757 } 758 759 buf[col] = '\0'; 760 oprintf(fp, " %s\n", buf); 761 } 762 763 oprintf(fp, "\n"); 764 } 765 766 static void 767 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 768 { 769 smbios_memarray_t ma; 770 771 (void) smbios_info_memarray(shp, id, &ma); 772 773 desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 774 fp, " Location: %u", ma.smbma_location); 775 776 desc_printf(smbios_memarray_use_desc(ma.smbma_use), 777 fp, " Use: %u", ma.smbma_use); 778 779 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 780 fp, " ECC: %u", ma.smbma_ecc); 781 782 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 783 id_printf(fp, " Memory Error Data: ", ma.smbma_err); 784 oprintf(fp, " Max Capacity: %llu bytes\n", 785 (u_longlong_t)ma.smbma_size); 786 } 787 788 static void 789 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 790 { 791 smbios_memdevice_t md; 792 793 (void) smbios_info_memdevice(shp, id, &md); 794 795 id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 796 id_printf(fp, " Memory Error Data: ", md.smbmd_error); 797 798 if (md.smbmd_twidth != -1u) 799 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 800 else 801 oprintf(fp, " Total Width: Unknown\n"); 802 803 if (md.smbmd_dwidth != -1u) 804 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 805 else 806 oprintf(fp, " Data Width: Unknown\n"); 807 808 switch (md.smbmd_size) { 809 case -1ull: 810 oprintf(fp, " Size: Unknown\n"); 811 break; 812 case 0: 813 oprintf(fp, " Size: Not Populated\n"); 814 break; 815 default: 816 oprintf(fp, " Size: %llu bytes\n", 817 (u_longlong_t)md.smbmd_size); 818 } 819 820 desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 821 fp, " Form Factor: %u", md.smbmd_form); 822 823 if (md.smbmd_set == 0) 824 oprintf(fp, " Set: None\n"); 825 else if (md.smbmd_set == (uint8_t)-1u) 826 oprintf(fp, " Set: Unknown\n"); 827 else 828 oprintf(fp, " Set: %u\n", md.smbmd_set); 829 830 if (md.smbmd_rank != 0) { 831 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank), 832 fp, " Rank: %u", md.smbmd_rank); 833 } else { 834 oprintf(fp, " Rank: Unknown\n"); 835 } 836 837 desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 838 fp, " Memory Type: %u", md.smbmd_type); 839 840 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 841 smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 842 843 if (md.smbmd_speed != 0) 844 oprintf(fp, " Speed: %u MHz\n", md.smbmd_speed); 845 else 846 oprintf(fp, " Speed: Unknown\n"); 847 848 if (md.smbmd_clkspeed != 0) 849 oprintf(fp, " Configured Speed: %u MHz\n", md.smbmd_clkspeed); 850 else 851 oprintf(fp, " Configured Speed: Unknown\n"); 852 853 oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc); 854 oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc); 855 856 if (md.smbmd_minvolt != 0) { 857 oprintf(fp, " Minimum Voltage: %.2fV\n", 858 md.smbmd_minvolt / 1000.0); 859 } else { 860 oprintf(fp, " Minimum Voltage: Unknown\n"); 861 } 862 863 if (md.smbmd_maxvolt != 0) { 864 oprintf(fp, " Maximum Voltage: %.2fV\n", 865 md.smbmd_maxvolt / 1000.0); 866 } else { 867 oprintf(fp, " Maximum Voltage: Unknown\n"); 868 } 869 870 if (md.smbmd_confvolt != 0) { 871 oprintf(fp, " Configured Voltage: %.2fV\n", 872 md.smbmd_confvolt / 1000.0); 873 } else { 874 oprintf(fp, " Configured Voltage: Unknown\n"); 875 } 876 } 877 878 static void 879 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 880 { 881 smbios_memarrmap_t ma; 882 883 (void) smbios_info_memarrmap(shp, id, &ma); 884 885 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 886 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 887 888 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 889 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 890 } 891 892 static void 893 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 894 { 895 smbios_memdevmap_t md; 896 897 (void) smbios_info_memdevmap(shp, id, &md); 898 899 id_printf(fp, " Memory Device: ", md.smbmdm_device); 900 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 901 902 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 903 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 904 905 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 906 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 907 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 908 } 909 910 static void 911 print_hwsec(smbios_hdl_t *shp, FILE *fp) 912 { 913 smbios_hwsec_t h; 914 915 (void) smbios_info_hwsec(shp, &h); 916 917 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 918 fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 919 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 920 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 921 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 922 fp, " Administrator Password Status: %u", h.smbh_adm_ps); 923 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 924 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 925 } 926 927 static void 928 print_boot(smbios_hdl_t *shp, FILE *fp) 929 { 930 smbios_boot_t b; 931 932 (void) smbios_info_boot(shp, &b); 933 934 desc_printf(smbios_boot_desc(b.smbt_status), 935 fp, " Boot Status Code: 0x%x", b.smbt_status); 936 937 if (b.smbt_size != 0) { 938 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 939 print_bytes(b.smbt_data, b.smbt_size, fp); 940 } 941 } 942 943 static void 944 print_ipmi(smbios_hdl_t *shp, FILE *fp) 945 { 946 smbios_ipmi_t i; 947 948 (void) smbios_info_ipmi(shp, &i); 949 950 desc_printf(smbios_ipmi_type_desc(i.smbip_type), 951 fp, " Type: %u", i.smbip_type); 952 953 oprintf(fp, " BMC IPMI Version: %u.%u\n", 954 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 955 956 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 957 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 958 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 959 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 960 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 961 962 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 963 smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 964 } 965 966 static void 967 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp) 968 { 969 int i; 970 smbios_processor_ext_t ep; 971 972 if (check_oem(shp) != 0) 973 return; 974 975 (void) smbios_info_extprocessor(shp, id, &ep); 976 977 oprintf(fp, " Processor: %u\n", ep.smbpe_processor); 978 oprintf(fp, " FRU: %u\n", ep.smbpe_fru); 979 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n); 980 981 for (i = 0; i < ep.smbpe_n; i++) { 982 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i, 983 ep.smbpe_apicid[i]); 984 } 985 } 986 987 static void 988 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp) 989 { 990 smbios_port_ext_t epo; 991 992 if (check_oem(shp) != 0) 993 return; 994 995 (void) smbios_info_extport(shp, id, &epo); 996 997 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis); 998 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port); 999 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype); 1000 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl); 1001 oprintf(fp, " PHY: %u\n", epo.smbporte_phy); 1002 } 1003 1004 static void 1005 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp) 1006 { 1007 smbios_pciexrc_t pcie; 1008 1009 if (check_oem(shp) != 0) 1010 return; 1011 1012 (void) smbios_info_pciexrc(shp, id, &pcie); 1013 1014 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb); 1015 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf); 1016 } 1017 1018 static void 1019 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp) 1020 { 1021 smbios_memarray_ext_t em; 1022 1023 if (check_oem(shp) != 0) 1024 return; 1025 1026 (void) smbios_info_extmemarray(shp, id, &em); 1027 1028 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma); 1029 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp); 1030 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf); 1031 } 1032 1033 static void 1034 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 1035 { 1036 int i; 1037 smbios_memdevice_ext_t emd; 1038 1039 if (check_oem(shp) != 0) 1040 return; 1041 1042 (void) smbios_info_extmemdevice(shp, id, &emd); 1043 1044 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md); 1045 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch); 1046 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs); 1047 1048 for (i = 0; i < emd.smbmdeve_ncs; i++) { 1049 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]); 1050 } 1051 } 1052 1053 static int 1054 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 1055 { 1056 smbios_info_t info; 1057 int hex = opt_x; 1058 const char *s; 1059 1060 if (opt_t != -1 && opt_t != sp->smbstr_type) 1061 return (0); /* skip struct if type doesn't match -t */ 1062 1063 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 1064 sp->smbstr_type == SMB_TYPE_MEMMOD)) 1065 return (0); /* skip struct if type is obsolete */ 1066 1067 if (g_hdr++ == 0 || !opt_s) 1068 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 1069 1070 oprintf(fp, "%-5u %-4lu", 1071 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 1072 1073 if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 1074 oprintf(fp, " %s (type %u)", s, sp->smbstr_type); 1075 else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 1076 sp->smbstr_type < SMB_TYPE_OEM_HI) 1077 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO", 1078 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type); 1079 else 1080 oprintf(fp, " %u", sp->smbstr_type); 1081 1082 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 1083 oprintf(fp, " (%s)\n", s); 1084 else 1085 oprintf(fp, "\n"); 1086 1087 if (opt_s) 1088 return (0); /* only print header line if -s specified */ 1089 1090 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 1091 oprintf(fp, "\n"); 1092 print_common(&info, fp); 1093 } 1094 1095 switch (sp->smbstr_type) { 1096 case SMB_TYPE_BIOS: 1097 oprintf(fp, "\n"); 1098 print_bios(shp, fp); 1099 break; 1100 case SMB_TYPE_SYSTEM: 1101 oprintf(fp, "\n"); 1102 print_system(shp, fp); 1103 break; 1104 case SMB_TYPE_BASEBOARD: 1105 oprintf(fp, "\n"); 1106 print_bboard(shp, sp->smbstr_id, fp); 1107 break; 1108 case SMB_TYPE_CHASSIS: 1109 oprintf(fp, "\n"); 1110 print_chassis(shp, sp->smbstr_id, fp); 1111 break; 1112 case SMB_TYPE_PROCESSOR: 1113 oprintf(fp, "\n"); 1114 print_processor(shp, sp->smbstr_id, fp); 1115 break; 1116 case SMB_TYPE_CACHE: 1117 oprintf(fp, "\n"); 1118 print_cache(shp, sp->smbstr_id, fp); 1119 break; 1120 case SMB_TYPE_PORT: 1121 oprintf(fp, "\n"); 1122 print_port(shp, sp->smbstr_id, fp); 1123 break; 1124 case SMB_TYPE_SLOT: 1125 oprintf(fp, "\n"); 1126 print_slot(shp, sp->smbstr_id, fp); 1127 break; 1128 case SMB_TYPE_OBDEVS: 1129 oprintf(fp, "\n"); 1130 print_obdevs(shp, sp->smbstr_id, fp); 1131 break; 1132 case SMB_TYPE_OEMSTR: 1133 case SMB_TYPE_SYSCONFSTR: 1134 oprintf(fp, "\n"); 1135 print_strtab(shp, sp->smbstr_id, fp); 1136 break; 1137 case SMB_TYPE_LANG: 1138 oprintf(fp, "\n"); 1139 print_lang(shp, sp->smbstr_id, fp); 1140 break; 1141 case SMB_TYPE_EVENTLOG: 1142 oprintf(fp, "\n"); 1143 print_evlog(shp, sp->smbstr_id, fp); 1144 break; 1145 case SMB_TYPE_MEMARRAY: 1146 oprintf(fp, "\n"); 1147 print_memarray(shp, sp->smbstr_id, fp); 1148 break; 1149 case SMB_TYPE_MEMDEVICE: 1150 oprintf(fp, "\n"); 1151 print_memdevice(shp, sp->smbstr_id, fp); 1152 break; 1153 case SMB_TYPE_MEMARRAYMAP: 1154 oprintf(fp, "\n"); 1155 print_memarrmap(shp, sp->smbstr_id, fp); 1156 break; 1157 case SMB_TYPE_MEMDEVICEMAP: 1158 oprintf(fp, "\n"); 1159 print_memdevmap(shp, sp->smbstr_id, fp); 1160 break; 1161 case SMB_TYPE_SECURITY: 1162 oprintf(fp, "\n"); 1163 print_hwsec(shp, fp); 1164 break; 1165 case SMB_TYPE_BOOT: 1166 oprintf(fp, "\n"); 1167 print_boot(shp, fp); 1168 break; 1169 case SMB_TYPE_IPMIDEV: 1170 oprintf(fp, "\n"); 1171 print_ipmi(shp, fp); 1172 break; 1173 case SMB_TYPE_OBDEVEXT: 1174 oprintf(fp, "\n"); 1175 print_obdevs_ext(shp, sp->smbstr_id, fp); 1176 break; 1177 case SUN_OEM_EXT_PROCESSOR: 1178 oprintf(fp, "\n"); 1179 print_extprocessor(shp, sp->smbstr_id, fp); 1180 break; 1181 case SUN_OEM_EXT_PORT: 1182 oprintf(fp, "\n"); 1183 print_extport(shp, sp->smbstr_id, fp); 1184 break; 1185 case SUN_OEM_PCIEXRC: 1186 oprintf(fp, "\n"); 1187 print_pciexrc(shp, sp->smbstr_id, fp); 1188 break; 1189 case SUN_OEM_EXT_MEMARRAY: 1190 oprintf(fp, "\n"); 1191 print_extmemarray(shp, sp->smbstr_id, fp); 1192 break; 1193 case SUN_OEM_EXT_MEMDEVICE: 1194 oprintf(fp, "\n"); 1195 print_extmemdevice(shp, sp->smbstr_id, fp); 1196 break; 1197 default: 1198 hex++; 1199 } 1200 1201 if (hex) 1202 print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 1203 else 1204 oprintf(fp, "\n"); 1205 1206 return (0); 1207 } 1208 1209 static uint16_t 1210 getu16(const char *name, const char *s) 1211 { 1212 u_longlong_t val; 1213 char *p; 1214 1215 errno = 0; 1216 val = strtoull(s, &p, 0); 1217 1218 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 1219 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1220 g_pname, name, s); 1221 exit(SMBIOS_USAGE); 1222 } 1223 1224 return ((uint16_t)val); 1225 } 1226 1227 static uint16_t 1228 getstype(const char *name, const char *s) 1229 { 1230 const char *ts; 1231 uint16_t t; 1232 1233 for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 1234 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 1235 return (t); 1236 } 1237 1238 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1239 g_pname, name, s); 1240 1241 exit(SMBIOS_USAGE); 1242 /*NOTREACHED*/ 1243 } 1244 1245 static int 1246 usage(FILE *fp) 1247 { 1248 (void) fprintf(fp, "Usage: %s " 1249 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 1250 1251 (void) fprintf(fp, 1252 "\t-B disable header validation for broken BIOSes\n" 1253 "\t-e display SMBIOS entry point information\n" 1254 "\t-i display only the specified structure\n" 1255 "\t-O display obsolete structure types\n" 1256 "\t-s display only a summary of structure identifiers and types\n" 1257 "\t-t display only the specified structure type\n" 1258 "\t-w write the raw data to the specified file\n" 1259 "\t-x display raw data for structures\n"); 1260 1261 return (SMBIOS_USAGE); 1262 } 1263 1264 int 1265 main(int argc, char *argv[]) 1266 { 1267 const char *ifile = NULL; 1268 const char *ofile = NULL; 1269 int oflags = 0; 1270 1271 smbios_hdl_t *shp; 1272 smbios_struct_t s; 1273 int err, fd, c; 1274 char *p; 1275 1276 if ((p = strrchr(argv[0], '/')) == NULL) 1277 g_pname = argv[0]; 1278 else 1279 g_pname = p + 1; 1280 1281 while (optind < argc) { 1282 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 1283 switch (c) { 1284 case 'B': 1285 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 1286 break; 1287 case 'e': 1288 opt_e++; 1289 break; 1290 case 'i': 1291 opt_i = getu16("struct ID", optarg); 1292 break; 1293 case 'O': 1294 opt_O++; 1295 break; 1296 case 's': 1297 opt_s++; 1298 break; 1299 case 't': 1300 if (isdigit(optarg[0])) 1301 opt_t = getu16("struct type", optarg); 1302 else 1303 opt_t = getstype("struct type", optarg); 1304 break; 1305 case 'w': 1306 ofile = optarg; 1307 break; 1308 case 'x': 1309 opt_x++; 1310 break; 1311 case 'Z': 1312 oflags |= SMB_O_ZIDS; /* undocumented */ 1313 break; 1314 default: 1315 return (usage(stderr)); 1316 } 1317 } 1318 1319 if (optind < argc) { 1320 if (ifile != NULL) { 1321 (void) fprintf(stderr, "%s: illegal " 1322 "argument -- %s\n", g_pname, argv[optind]); 1323 return (SMBIOS_USAGE); 1324 } 1325 ifile = argv[optind++]; 1326 } 1327 } 1328 1329 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 1330 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 1331 g_pname, smbios_errmsg(err)); 1332 return (SMBIOS_ERROR); 1333 } 1334 1335 if (ofile != NULL) { 1336 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 1337 (void) fprintf(stderr, "%s: failed to open %s: %s\n", 1338 g_pname, ofile, strerror(errno)); 1339 err = SMBIOS_ERROR; 1340 } else if (smbios_write(shp, fd) != 0) { 1341 (void) fprintf(stderr, "%s: failed to write %s: %s\n", 1342 g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 1343 err = SMBIOS_ERROR; 1344 } 1345 smbios_close(shp); 1346 return (err); 1347 } 1348 1349 if (opt_e) { 1350 print_smbios(shp, stdout); 1351 smbios_close(shp); 1352 return (SMBIOS_SUCCESS); 1353 } 1354 1355 if (opt_O && (opt_i != -1 || opt_t != -1)) 1356 opt_O++; /* -i or -t imply displaying obsolete records */ 1357 1358 if (opt_i != -1) 1359 err = smbios_lookup_id(shp, opt_i, &s); 1360 else 1361 err = smbios_iter(shp, print_struct, stdout); 1362 1363 if (err != 0) { 1364 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 1365 g_pname, smbios_errmsg(smbios_errno(shp))); 1366 smbios_close(shp); 1367 return (SMBIOS_ERROR); 1368 } 1369 1370 if (opt_i != -1) 1371 (void) print_struct(shp, &s, stdout); 1372 1373 smbios_close(shp); 1374 return (SMBIOS_SUCCESS); 1375 } 1376