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 2016 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: %" PRIu64 " bytes\n", b.smbb_extromsize); 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[0] == '\0' ? "<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: %" PRIu64 " bytes\n", 512 c.smba_maxsize2); 513 514 if (c.smba_size2 != 0) { 515 oprintf(fp, " Installed Size: %" PRIu64 " bytes\n", 516 c.smba_size2); 517 } else { 518 oprintf(fp, " Installed Size: Not Installed\n"); 519 } 520 521 if (c.smba_speed != 0) 522 oprintf(fp, " Speed: %uns\n", c.smba_speed); 523 else 524 oprintf(fp, " Speed: Unknown\n"); 525 526 flag_printf(fp, "Supported SRAM Types", 527 c.smba_stype, sizeof (c.smba_stype) * NBBY, 528 smbios_cache_ctype_name, smbios_cache_ctype_desc); 529 530 desc_printf(smbios_cache_ctype_desc(c.smba_ctype), 531 fp, " Current SRAM Type: 0x%x", c.smba_ctype); 532 533 desc_printf(smbios_cache_ecc_desc(c.smba_etype), 534 fp, " Error Correction Type: %u", c.smba_etype); 535 536 desc_printf(smbios_cache_logical_desc(c.smba_ltype), 537 fp, " Logical Cache Type: %u", c.smba_ltype); 538 539 desc_printf(smbios_cache_assoc_desc(c.smba_assoc), 540 fp, " Associativity: %u", c.smba_assoc); 541 542 desc_printf(smbios_cache_mode_desc(c.smba_mode), 543 fp, " Mode: %u", c.smba_mode); 544 545 desc_printf(smbios_cache_loc_desc(c.smba_location), 546 fp, " Location: %u", c.smba_location); 547 548 flag_printf(fp, "Flags", c.smba_flags, sizeof (c.smba_flags) * NBBY, 549 smbios_cache_flag_name, smbios_cache_flag_desc); 550 } 551 552 static void 553 print_port(smbios_hdl_t *shp, id_t id, FILE *fp) 554 { 555 smbios_port_t p; 556 557 (void) smbios_info_port(shp, id, &p); 558 559 oprintf(fp, " Internal Reference Designator: %s\n", p.smbo_iref); 560 oprintf(fp, " External Reference Designator: %s\n", p.smbo_eref); 561 562 desc_printf(smbios_port_conn_desc(p.smbo_itype), 563 fp, " Internal Connector Type: %u", p.smbo_itype); 564 565 desc_printf(smbios_port_conn_desc(p.smbo_etype), 566 fp, " External Connector Type: %u", p.smbo_etype); 567 568 desc_printf(smbios_port_type_desc(p.smbo_ptype), 569 fp, " Port Type: %u", p.smbo_ptype); 570 } 571 572 static void 573 print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) 574 { 575 smbios_slot_t s; 576 smbios_entry_t e; 577 578 (void) smbios_info_slot(shp, id, &s); 579 (void) smbios_info_smbios(shp, &e); 580 581 oprintf(fp, " Reference Designator: %s\n", s.smbl_name); 582 oprintf(fp, " Slot ID: 0x%x\n", s.smbl_id); 583 584 desc_printf(smbios_slot_type_desc(s.smbl_type), 585 fp, " Type: 0x%x", s.smbl_type); 586 587 desc_printf(smbios_slot_width_desc(s.smbl_width), 588 fp, " Width: 0x%x", s.smbl_width); 589 590 desc_printf(smbios_slot_usage_desc(s.smbl_usage), 591 fp, " Usage: 0x%x", s.smbl_usage); 592 593 desc_printf(smbios_slot_length_desc(s.smbl_length), 594 fp, " Length: 0x%x", s.smbl_length); 595 596 flag_printf(fp, "Slot Characteristics 1", 597 s.smbl_ch1, sizeof (s.smbl_ch1) * NBBY, 598 smbios_slot_ch1_name, smbios_slot_ch1_desc); 599 600 flag_printf(fp, "Slot Characteristics 2", 601 s.smbl_ch2, sizeof (s.smbl_ch2) * NBBY, 602 smbios_slot_ch2_name, smbios_slot_ch2_desc); 603 604 if (check_oem(shp) != 0 && (e.smbe_major < 2 || e.smbe_minor < 6)) 605 return; 606 607 oprintf(fp, " Segment Group: %u\n", s.smbl_sg); 608 oprintf(fp, " Bus Number: %u\n", s.smbl_bus); 609 oprintf(fp, " Device/Function Number: %u\n", s.smbl_df); 610 } 611 612 static void 613 print_obdevs_ext(smbios_hdl_t *shp, id_t id, FILE *fp) 614 { 615 boolean_t enabled; 616 smbios_obdev_ext_t oe; 617 const char *type; 618 619 (void) smbios_info_obdevs_ext(shp, id, &oe); 620 621 /* 622 * Bit 7 is always whether or not the device is enabled while bits 0:6 623 * are the actual device type. 624 */ 625 enabled = oe.smboe_dtype >> 7; 626 type = smbios_onboard_type_desc(oe.smboe_dtype & 0x7f); 627 628 oprintf(fp, " Reference Designator: %s\n", oe.smboe_name); 629 oprintf(fp, " Device Enabled: %s\n", enabled == B_TRUE ? "true" : 630 "false"); 631 oprintf(fp, " Device Type: %s\n", type); 632 oprintf(fp, " Device Type Instance: %u\n", oe.smboe_dti); 633 oprintf(fp, " Segment Group Number: %u\n", oe.smboe_sg); 634 oprintf(fp, " Bus Number: %u\n", oe.smboe_bus); 635 oprintf(fp, " Device/Function Number: %u\n", oe.smboe_df); 636 } 637 638 static void 639 print_obdevs(smbios_hdl_t *shp, id_t id, FILE *fp) 640 { 641 smbios_obdev_t *argv; 642 int i, argc; 643 644 if ((argc = smbios_info_obdevs(shp, id, 0, NULL)) > 0) { 645 argv = alloca(sizeof (smbios_obdev_t) * argc); 646 (void) smbios_info_obdevs(shp, id, argc, argv); 647 for (i = 0; i < argc; i++) 648 oprintf(fp, " %s\n", argv[i].smbd_name); 649 } 650 } 651 652 static void 653 print_strtab(smbios_hdl_t *shp, id_t id, FILE *fp) 654 { 655 const char **argv; 656 int i, argc; 657 658 if ((argc = smbios_info_strtab(shp, id, 0, NULL)) > 0) { 659 argv = alloca(sizeof (char *) * argc); 660 (void) smbios_info_strtab(shp, id, argc, argv); 661 for (i = 0; i < argc; i++) 662 oprintf(fp, " %s\n", argv[i]); 663 } 664 } 665 666 static void 667 print_lang(smbios_hdl_t *shp, id_t id, FILE *fp) 668 { 669 smbios_lang_t l; 670 671 (void) smbios_info_lang(shp, &l); 672 673 oprintf(fp, " Current Language: %s\n", l.smbla_cur); 674 oprintf(fp, " Language String Format: %u\n", l.smbla_fmt); 675 oprintf(fp, " Number of Installed Languages: %u\n", l.smbla_num); 676 oprintf(fp, " Installed Languages:\n"); 677 678 print_strtab(shp, id, fp); 679 } 680 681 /*ARGSUSED*/ 682 static void 683 print_evlog(smbios_hdl_t *shp, id_t id, FILE *fp) 684 { 685 smbios_evlog_t ev; 686 uint32_t i; 687 688 (void) smbios_info_eventlog(shp, &ev); 689 690 oprintf(fp, " Log Area Size: %lu bytes\n", (ulong_t)ev.smbev_size); 691 oprintf(fp, " Header Offset: %lu\n", (ulong_t)ev.smbev_hdr); 692 oprintf(fp, " Data Offset: %lu\n", (ulong_t)ev.smbev_data); 693 694 desc_printf(smbios_evlog_method_desc(ev.smbev_method), 695 fp, " Data Access Method: %u", ev.smbev_method); 696 697 flag_printf(fp, "Log Flags", 698 ev.smbev_flags, sizeof (ev.smbev_flags) * NBBY, 699 smbios_evlog_flag_name, smbios_evlog_flag_desc); 700 701 desc_printf(smbios_evlog_format_desc(ev.smbev_format), 702 fp, " Log Header Format: %u", ev.smbev_format); 703 704 oprintf(fp, " Update Token: 0x%x\n", ev.smbev_token); 705 oprintf(fp, " Data Access Address: "); 706 707 switch (ev.smbev_method) { 708 case SMB_EVM_1x1i_1x1d: 709 case SMB_EVM_2x1i_1x1d: 710 case SMB_EVM_1x2i_1x1d: 711 oprintf(fp, "Index Address 0x%x, Data Address 0x%x\n", 712 ev.smbev_addr.eva_io.evi_iaddr, 713 ev.smbev_addr.eva_io.evi_daddr); 714 break; 715 case SMB_EVM_GPNV: 716 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_gpnv); 717 break; 718 default: 719 oprintf(fp, "0x%x\n", ev.smbev_addr.eva_addr); 720 } 721 722 oprintf(fp, " Type Descriptors:\n"); 723 724 for (i = 0; i < ev.smbev_typec; i++) { 725 oprintf(fp, " %u: Log Type 0x%x, Data Type 0x%x\n", i, 726 ev.smbev_typev[i].smbevt_ltype, 727 ev.smbev_typev[i].smbevt_dtype); 728 } 729 } 730 731 static void 732 print_bytes(const uint8_t *data, size_t size, FILE *fp) 733 { 734 size_t row, rows = P2ROUNDUP(size, 16) / 16; 735 size_t col, cols; 736 737 char buf[17]; 738 uint8_t x; 739 740 oprintf(fp, "\n offset: 0 1 2 3 4 5 6 7 8 9 a b c d e f " 741 "0123456789abcdef\n"); 742 743 for (row = 0; row < rows; row++) { 744 oprintf(fp, " %#4lx: ", (ulong_t)row * 16); 745 cols = MIN(size - row * 16, 16); 746 747 for (col = 0; col < cols; col++) { 748 if (col % 4 == 0) 749 oprintf(fp, " "); 750 x = *data++; 751 oprintf(fp, "%02x", x); 752 buf[col] = x <= ' ' || x > '~' ? '.' : x; 753 } 754 755 for (; col < 16; col++) { 756 if (col % 4 == 0) 757 oprintf(fp, " "); 758 oprintf(fp, " "); 759 buf[col] = ' '; 760 } 761 762 buf[col] = '\0'; 763 oprintf(fp, " %s\n", buf); 764 } 765 766 oprintf(fp, "\n"); 767 } 768 769 static void 770 print_memarray(smbios_hdl_t *shp, id_t id, FILE *fp) 771 { 772 smbios_memarray_t ma; 773 774 (void) smbios_info_memarray(shp, id, &ma); 775 776 desc_printf(smbios_memarray_loc_desc(ma.smbma_location), 777 fp, " Location: %u", ma.smbma_location); 778 779 desc_printf(smbios_memarray_use_desc(ma.smbma_use), 780 fp, " Use: %u", ma.smbma_use); 781 782 desc_printf(smbios_memarray_ecc_desc(ma.smbma_ecc), 783 fp, " ECC: %u", ma.smbma_ecc); 784 785 oprintf(fp, " Number of Slots/Sockets: %u\n", ma.smbma_ndevs); 786 id_printf(fp, " Memory Error Data: ", ma.smbma_err); 787 oprintf(fp, " Max Capacity: %llu bytes\n", 788 (u_longlong_t)ma.smbma_size); 789 } 790 791 static void 792 print_memdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 793 { 794 smbios_memdevice_t md; 795 796 (void) smbios_info_memdevice(shp, id, &md); 797 798 id_printf(fp, " Physical Memory Array: ", md.smbmd_array); 799 id_printf(fp, " Memory Error Data: ", md.smbmd_error); 800 801 if (md.smbmd_twidth != -1u) 802 oprintf(fp, " Total Width: %u bits\n", md.smbmd_twidth); 803 else 804 oprintf(fp, " Total Width: Unknown\n"); 805 806 if (md.smbmd_dwidth != -1u) 807 oprintf(fp, " Data Width: %u bits\n", md.smbmd_dwidth); 808 else 809 oprintf(fp, " Data Width: Unknown\n"); 810 811 switch (md.smbmd_size) { 812 case -1ull: 813 oprintf(fp, " Size: Unknown\n"); 814 break; 815 case 0: 816 oprintf(fp, " Size: Not Populated\n"); 817 break; 818 default: 819 oprintf(fp, " Size: %llu bytes\n", 820 (u_longlong_t)md.smbmd_size); 821 } 822 823 desc_printf(smbios_memdevice_form_desc(md.smbmd_form), 824 fp, " Form Factor: %u", md.smbmd_form); 825 826 if (md.smbmd_set == 0) 827 oprintf(fp, " Set: None\n"); 828 else if (md.smbmd_set == (uint8_t)-1u) 829 oprintf(fp, " Set: Unknown\n"); 830 else 831 oprintf(fp, " Set: %u\n", md.smbmd_set); 832 833 if (md.smbmd_rank != 0) { 834 desc_printf(smbios_memdevice_rank_desc(md.smbmd_rank), 835 fp, " Rank: %u", md.smbmd_rank); 836 } else { 837 oprintf(fp, " Rank: Unknown\n"); 838 } 839 840 desc_printf(smbios_memdevice_type_desc(md.smbmd_type), 841 fp, " Memory Type: %u", md.smbmd_type); 842 843 flag_printf(fp, "Flags", md.smbmd_flags, sizeof (md.smbmd_flags) * NBBY, 844 smbios_memdevice_flag_name, smbios_memdevice_flag_desc); 845 846 if (md.smbmd_speed != 0) 847 oprintf(fp, " Speed: %u MT/s\n", md.smbmd_speed); 848 else 849 oprintf(fp, " Speed: Unknown\n"); 850 851 if (md.smbmd_clkspeed != 0) 852 oprintf(fp, " Configured Speed: %u MT/s\n", md.smbmd_clkspeed); 853 else 854 oprintf(fp, " Configured Speed: Unknown\n"); 855 856 oprintf(fp, " Device Locator: %s\n", md.smbmd_dloc); 857 oprintf(fp, " Bank Locator: %s\n", md.smbmd_bloc); 858 859 if (md.smbmd_minvolt != 0) { 860 oprintf(fp, " Minimum Voltage: %.2fV\n", 861 md.smbmd_minvolt / 1000.0); 862 } else { 863 oprintf(fp, " Minimum Voltage: Unknown\n"); 864 } 865 866 if (md.smbmd_maxvolt != 0) { 867 oprintf(fp, " Maximum Voltage: %.2fV\n", 868 md.smbmd_maxvolt / 1000.0); 869 } else { 870 oprintf(fp, " Maximum Voltage: Unknown\n"); 871 } 872 873 if (md.smbmd_confvolt != 0) { 874 oprintf(fp, " Configured Voltage: %.2fV\n", 875 md.smbmd_confvolt / 1000.0); 876 } else { 877 oprintf(fp, " Configured Voltage: Unknown\n"); 878 } 879 } 880 881 static void 882 print_memarrmap(smbios_hdl_t *shp, id_t id, FILE *fp) 883 { 884 smbios_memarrmap_t ma; 885 886 (void) smbios_info_memarrmap(shp, id, &ma); 887 888 id_printf(fp, " Physical Memory Array: ", ma.smbmam_array); 889 oprintf(fp, " Devices per Row: %u\n", ma.smbmam_width); 890 891 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 892 (u_longlong_t)ma.smbmam_addr, (u_longlong_t)ma.smbmam_size); 893 } 894 895 static void 896 print_memdevmap(smbios_hdl_t *shp, id_t id, FILE *fp) 897 { 898 smbios_memdevmap_t md; 899 900 (void) smbios_info_memdevmap(shp, id, &md); 901 902 id_printf(fp, " Memory Device: ", md.smbmdm_device); 903 id_printf(fp, " Memory Array Mapped Address: ", md.smbmdm_arrmap); 904 905 oprintf(fp, " Physical Address: 0x%llx\n Size: %llu bytes\n", 906 (u_longlong_t)md.smbmdm_addr, (u_longlong_t)md.smbmdm_size); 907 908 oprintf(fp, " Partition Row Position: %u\n", md.smbmdm_rpos); 909 oprintf(fp, " Interleave Position: %u\n", md.smbmdm_ipos); 910 oprintf(fp, " Interleave Data Depth: %u\n", md.smbmdm_idepth); 911 } 912 913 static void 914 print_hwsec(smbios_hdl_t *shp, FILE *fp) 915 { 916 smbios_hwsec_t h; 917 918 (void) smbios_info_hwsec(shp, &h); 919 920 desc_printf(smbios_hwsec_desc(h.smbh_pwr_ps), 921 fp, " Power-On Password Status: %u", h.smbh_pwr_ps); 922 desc_printf(smbios_hwsec_desc(h.smbh_kbd_ps), 923 fp, " Keyboard Password Status: %u", h.smbh_kbd_ps); 924 desc_printf(smbios_hwsec_desc(h.smbh_adm_ps), 925 fp, " Administrator Password Status: %u", h.smbh_adm_ps); 926 desc_printf(smbios_hwsec_desc(h.smbh_pan_ps), 927 fp, " Front Panel Reset Status: %u", h.smbh_pan_ps); 928 } 929 930 static void 931 print_boot(smbios_hdl_t *shp, FILE *fp) 932 { 933 smbios_boot_t b; 934 935 (void) smbios_info_boot(shp, &b); 936 937 desc_printf(smbios_boot_desc(b.smbt_status), 938 fp, " Boot Status Code: 0x%x", b.smbt_status); 939 940 if (b.smbt_size != 0) { 941 oprintf(fp, " Boot Data (%lu bytes):\n", (ulong_t)b.smbt_size); 942 print_bytes(b.smbt_data, b.smbt_size, fp); 943 } 944 } 945 946 static void 947 print_ipmi(smbios_hdl_t *shp, FILE *fp) 948 { 949 smbios_ipmi_t i; 950 951 (void) smbios_info_ipmi(shp, &i); 952 953 desc_printf(smbios_ipmi_type_desc(i.smbip_type), 954 fp, " Type: %u", i.smbip_type); 955 956 oprintf(fp, " BMC IPMI Version: %u.%u\n", 957 i.smbip_vers.smbv_major, i.smbip_vers.smbv_minor); 958 959 oprintf(fp, " i2c Bus Slave Address: 0x%x\n", i.smbip_i2c); 960 oprintf(fp, " NV Storage Device Bus ID: 0x%x\n", i.smbip_bus); 961 oprintf(fp, " BMC Base Address: 0x%llx\n", (u_longlong_t)i.smbip_addr); 962 oprintf(fp, " Interrupt Number: %u\n", i.smbip_intr); 963 oprintf(fp, " Register Spacing: %u\n", i.smbip_regspacing); 964 965 flag_printf(fp, "Flags", i.smbip_flags, sizeof (i.smbip_flags) * NBBY, 966 smbios_ipmi_flag_name, smbios_ipmi_flag_desc); 967 } 968 969 static void 970 print_extprocessor(smbios_hdl_t *shp, id_t id, FILE *fp) 971 { 972 int i; 973 smbios_processor_ext_t ep; 974 975 if (check_oem(shp) != 0) 976 return; 977 978 (void) smbios_info_extprocessor(shp, id, &ep); 979 980 oprintf(fp, " Processor: %u\n", ep.smbpe_processor); 981 oprintf(fp, " FRU: %u\n", ep.smbpe_fru); 982 oprintf(fp, " Initial APIC ID count: %u\n\n", ep.smbpe_n); 983 984 for (i = 0; i < ep.smbpe_n; i++) { 985 oprintf(fp, " Logical Strand %u: Initial APIC ID: %u\n", i, 986 ep.smbpe_apicid[i]); 987 } 988 } 989 990 static void 991 print_extport(smbios_hdl_t *shp, id_t id, FILE *fp) 992 { 993 smbios_port_ext_t epo; 994 995 if (check_oem(shp) != 0) 996 return; 997 998 (void) smbios_info_extport(shp, id, &epo); 999 1000 oprintf(fp, " Chassis Handle: %u\n", epo.smbporte_chassis); 1001 oprintf(fp, " Port Connector Handle: %u\n", epo.smbporte_port); 1002 oprintf(fp, " Device Type: %u\n", epo.smbporte_dtype); 1003 oprintf(fp, " Device Handle: %u\n", epo.smbporte_devhdl); 1004 oprintf(fp, " PHY: %u\n", epo.smbporte_phy); 1005 } 1006 1007 static void 1008 print_pciexrc(smbios_hdl_t *shp, id_t id, FILE *fp) 1009 { 1010 smbios_pciexrc_t pcie; 1011 1012 if (check_oem(shp) != 0) 1013 return; 1014 1015 (void) smbios_info_pciexrc(shp, id, &pcie); 1016 1017 oprintf(fp, " Component ID: %u\n", pcie.smbpcie_bb); 1018 oprintf(fp, " BDF: 0x%x\n", pcie.smbpcie_bdf); 1019 } 1020 1021 static void 1022 print_extmemarray(smbios_hdl_t *shp, id_t id, FILE *fp) 1023 { 1024 smbios_memarray_ext_t em; 1025 1026 if (check_oem(shp) != 0) 1027 return; 1028 1029 (void) smbios_info_extmemarray(shp, id, &em); 1030 1031 oprintf(fp, " Physical Memory Array Handle: %u\n", em.smbmae_ma); 1032 oprintf(fp, " Component Parent Handle: %u\n", em.smbmae_comp); 1033 oprintf(fp, " BDF: 0x%x\n", em.smbmae_bdf); 1034 } 1035 1036 static void 1037 print_extmemdevice(smbios_hdl_t *shp, id_t id, FILE *fp) 1038 { 1039 int i; 1040 smbios_memdevice_ext_t emd; 1041 1042 if (check_oem(shp) != 0) 1043 return; 1044 1045 (void) smbios_info_extmemdevice(shp, id, &emd); 1046 1047 oprintf(fp, " Memory Device Handle: %u\n", emd.smbmdeve_md); 1048 oprintf(fp, " DRAM Channel: %u\n", emd.smbmdeve_drch); 1049 oprintf(fp, " Number of Chip Selects: %u\n", emd.smbmdeve_ncs); 1050 1051 for (i = 0; i < emd.smbmdeve_ncs; i++) { 1052 oprintf(fp, " Chip Select: %u\n", emd.smbmdeve_cs[i]); 1053 } 1054 } 1055 1056 static int 1057 print_struct(smbios_hdl_t *shp, const smbios_struct_t *sp, void *fp) 1058 { 1059 smbios_info_t info; 1060 int hex = opt_x; 1061 const char *s; 1062 1063 if (opt_t != -1 && opt_t != sp->smbstr_type) 1064 return (0); /* skip struct if type doesn't match -t */ 1065 1066 if (!opt_O && (sp->smbstr_type == SMB_TYPE_MEMCTL || 1067 sp->smbstr_type == SMB_TYPE_MEMMOD)) 1068 return (0); /* skip struct if type is obsolete */ 1069 1070 if (g_hdr++ == 0 || !opt_s) 1071 oprintf(fp, "%-5s %-4s %s\n", "ID", "SIZE", "TYPE"); 1072 1073 oprintf(fp, "%-5u %-4lu", 1074 (uint_t)sp->smbstr_id, (ulong_t)sp->smbstr_size); 1075 1076 if ((s = smbios_type_name(sp->smbstr_type)) != NULL) 1077 oprintf(fp, " %s (type %u)", s, sp->smbstr_type); 1078 else if (sp->smbstr_type > SMB_TYPE_OEM_LO && 1079 sp->smbstr_type < SMB_TYPE_OEM_HI) 1080 oprintf(fp, " %s+%u (type %u)", "SMB_TYPE_OEM_LO", 1081 sp->smbstr_type - SMB_TYPE_OEM_LO, sp->smbstr_type); 1082 else 1083 oprintf(fp, " %u", sp->smbstr_type); 1084 1085 if ((s = smbios_type_desc(sp->smbstr_type)) != NULL) 1086 oprintf(fp, " (%s)\n", s); 1087 else 1088 oprintf(fp, "\n"); 1089 1090 if (opt_s) 1091 return (0); /* only print header line if -s specified */ 1092 1093 if (smbios_info_common(shp, sp->smbstr_id, &info) == 0) { 1094 oprintf(fp, "\n"); 1095 print_common(&info, fp); 1096 } 1097 1098 switch (sp->smbstr_type) { 1099 case SMB_TYPE_BIOS: 1100 oprintf(fp, "\n"); 1101 print_bios(shp, fp); 1102 break; 1103 case SMB_TYPE_SYSTEM: 1104 oprintf(fp, "\n"); 1105 print_system(shp, fp); 1106 break; 1107 case SMB_TYPE_BASEBOARD: 1108 oprintf(fp, "\n"); 1109 print_bboard(shp, sp->smbstr_id, fp); 1110 break; 1111 case SMB_TYPE_CHASSIS: 1112 oprintf(fp, "\n"); 1113 print_chassis(shp, sp->smbstr_id, fp); 1114 break; 1115 case SMB_TYPE_PROCESSOR: 1116 oprintf(fp, "\n"); 1117 print_processor(shp, sp->smbstr_id, fp); 1118 break; 1119 case SMB_TYPE_CACHE: 1120 oprintf(fp, "\n"); 1121 print_cache(shp, sp->smbstr_id, fp); 1122 break; 1123 case SMB_TYPE_PORT: 1124 oprintf(fp, "\n"); 1125 print_port(shp, sp->smbstr_id, fp); 1126 break; 1127 case SMB_TYPE_SLOT: 1128 oprintf(fp, "\n"); 1129 print_slot(shp, sp->smbstr_id, fp); 1130 break; 1131 case SMB_TYPE_OBDEVS: 1132 oprintf(fp, "\n"); 1133 print_obdevs(shp, sp->smbstr_id, fp); 1134 break; 1135 case SMB_TYPE_OEMSTR: 1136 case SMB_TYPE_SYSCONFSTR: 1137 oprintf(fp, "\n"); 1138 print_strtab(shp, sp->smbstr_id, fp); 1139 break; 1140 case SMB_TYPE_LANG: 1141 oprintf(fp, "\n"); 1142 print_lang(shp, sp->smbstr_id, fp); 1143 break; 1144 case SMB_TYPE_EVENTLOG: 1145 oprintf(fp, "\n"); 1146 print_evlog(shp, sp->smbstr_id, fp); 1147 break; 1148 case SMB_TYPE_MEMARRAY: 1149 oprintf(fp, "\n"); 1150 print_memarray(shp, sp->smbstr_id, fp); 1151 break; 1152 case SMB_TYPE_MEMDEVICE: 1153 oprintf(fp, "\n"); 1154 print_memdevice(shp, sp->smbstr_id, fp); 1155 break; 1156 case SMB_TYPE_MEMARRAYMAP: 1157 oprintf(fp, "\n"); 1158 print_memarrmap(shp, sp->smbstr_id, fp); 1159 break; 1160 case SMB_TYPE_MEMDEVICEMAP: 1161 oprintf(fp, "\n"); 1162 print_memdevmap(shp, sp->smbstr_id, fp); 1163 break; 1164 case SMB_TYPE_SECURITY: 1165 oprintf(fp, "\n"); 1166 print_hwsec(shp, fp); 1167 break; 1168 case SMB_TYPE_BOOT: 1169 oprintf(fp, "\n"); 1170 print_boot(shp, fp); 1171 break; 1172 case SMB_TYPE_IPMIDEV: 1173 oprintf(fp, "\n"); 1174 print_ipmi(shp, fp); 1175 break; 1176 case SMB_TYPE_OBDEVEXT: 1177 oprintf(fp, "\n"); 1178 print_obdevs_ext(shp, sp->smbstr_id, fp); 1179 break; 1180 case SUN_OEM_EXT_PROCESSOR: 1181 oprintf(fp, "\n"); 1182 print_extprocessor(shp, sp->smbstr_id, fp); 1183 break; 1184 case SUN_OEM_EXT_PORT: 1185 oprintf(fp, "\n"); 1186 print_extport(shp, sp->smbstr_id, fp); 1187 break; 1188 case SUN_OEM_PCIEXRC: 1189 oprintf(fp, "\n"); 1190 print_pciexrc(shp, sp->smbstr_id, fp); 1191 break; 1192 case SUN_OEM_EXT_MEMARRAY: 1193 oprintf(fp, "\n"); 1194 print_extmemarray(shp, sp->smbstr_id, fp); 1195 break; 1196 case SUN_OEM_EXT_MEMDEVICE: 1197 oprintf(fp, "\n"); 1198 print_extmemdevice(shp, sp->smbstr_id, fp); 1199 break; 1200 default: 1201 hex++; 1202 } 1203 1204 if (hex) 1205 print_bytes(sp->smbstr_data, sp->smbstr_size, fp); 1206 else 1207 oprintf(fp, "\n"); 1208 1209 return (0); 1210 } 1211 1212 static uint16_t 1213 getu16(const char *name, const char *s) 1214 { 1215 u_longlong_t val; 1216 char *p; 1217 1218 errno = 0; 1219 val = strtoull(s, &p, 0); 1220 1221 if (errno != 0 || p == s || *p != '\0' || val > UINT16_MAX) { 1222 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1223 g_pname, name, s); 1224 exit(SMBIOS_USAGE); 1225 } 1226 1227 return ((uint16_t)val); 1228 } 1229 1230 static uint16_t 1231 getstype(const char *name, const char *s) 1232 { 1233 const char *ts; 1234 uint16_t t; 1235 1236 for (t = 0; t < SMB_TYPE_OEM_LO; t++) { 1237 if ((ts = smbios_type_name(t)) != NULL && strcmp(s, ts) == 0) 1238 return (t); 1239 } 1240 1241 (void) fprintf(stderr, "%s: invalid %s argument -- %s\n", 1242 g_pname, name, s); 1243 1244 exit(SMBIOS_USAGE); 1245 /*NOTREACHED*/ 1246 } 1247 1248 static int 1249 usage(FILE *fp) 1250 { 1251 (void) fprintf(fp, "Usage: %s " 1252 "[-BeOsx] [-i id] [-t type] [-w file] [file]\n\n", g_pname); 1253 1254 (void) fprintf(fp, 1255 "\t-B disable header validation for broken BIOSes\n" 1256 "\t-e display SMBIOS entry point information\n" 1257 "\t-i display only the specified structure\n" 1258 "\t-O display obsolete structure types\n" 1259 "\t-s display only a summary of structure identifiers and types\n" 1260 "\t-t display only the specified structure type\n" 1261 "\t-w write the raw data to the specified file\n" 1262 "\t-x display raw data for structures\n"); 1263 1264 return (SMBIOS_USAGE); 1265 } 1266 1267 int 1268 main(int argc, char *argv[]) 1269 { 1270 const char *ifile = NULL; 1271 const char *ofile = NULL; 1272 int oflags = 0; 1273 1274 smbios_hdl_t *shp; 1275 smbios_struct_t s; 1276 int err, fd, c; 1277 char *p; 1278 1279 if ((p = strrchr(argv[0], '/')) == NULL) 1280 g_pname = argv[0]; 1281 else 1282 g_pname = p + 1; 1283 1284 while (optind < argc) { 1285 while ((c = getopt(argc, argv, "Bei:Ost:w:xZ")) != EOF) { 1286 switch (c) { 1287 case 'B': 1288 oflags |= SMB_O_NOCKSUM | SMB_O_NOVERS; 1289 break; 1290 case 'e': 1291 opt_e++; 1292 break; 1293 case 'i': 1294 opt_i = getu16("struct ID", optarg); 1295 break; 1296 case 'O': 1297 opt_O++; 1298 break; 1299 case 's': 1300 opt_s++; 1301 break; 1302 case 't': 1303 if (isdigit(optarg[0])) 1304 opt_t = getu16("struct type", optarg); 1305 else 1306 opt_t = getstype("struct type", optarg); 1307 break; 1308 case 'w': 1309 ofile = optarg; 1310 break; 1311 case 'x': 1312 opt_x++; 1313 break; 1314 case 'Z': 1315 oflags |= SMB_O_ZIDS; /* undocumented */ 1316 break; 1317 default: 1318 return (usage(stderr)); 1319 } 1320 } 1321 1322 if (optind < argc) { 1323 if (ifile != NULL) { 1324 (void) fprintf(stderr, "%s: illegal " 1325 "argument -- %s\n", g_pname, argv[optind]); 1326 return (SMBIOS_USAGE); 1327 } 1328 ifile = argv[optind++]; 1329 } 1330 } 1331 1332 if ((shp = smbios_open(ifile, SMB_VERSION, oflags, &err)) == NULL) { 1333 (void) fprintf(stderr, "%s: failed to load SMBIOS: %s\n", 1334 g_pname, smbios_errmsg(err)); 1335 return (SMBIOS_ERROR); 1336 } 1337 1338 if (opt_i == -1 && opt_t == -1 && opt_e == 0 && 1339 smbios_truncated(shp)) 1340 (void) fprintf(stderr, "%s: SMBIOS table is truncated\n", 1341 g_pname); 1342 1343 if (ofile != NULL) { 1344 if ((fd = open(ofile, O_WRONLY|O_CREAT|O_TRUNC, 0666)) == -1) { 1345 (void) fprintf(stderr, "%s: failed to open %s: %s\n", 1346 g_pname, ofile, strerror(errno)); 1347 err = SMBIOS_ERROR; 1348 } else if (smbios_write(shp, fd) != 0) { 1349 (void) fprintf(stderr, "%s: failed to write %s: %s\n", 1350 g_pname, ofile, smbios_errmsg(smbios_errno(shp))); 1351 err = SMBIOS_ERROR; 1352 } 1353 smbios_close(shp); 1354 return (err); 1355 } 1356 1357 if (opt_e) { 1358 print_smbios(shp, stdout); 1359 smbios_close(shp); 1360 return (SMBIOS_SUCCESS); 1361 } 1362 1363 if (opt_O && (opt_i != -1 || opt_t != -1)) 1364 opt_O++; /* -i or -t imply displaying obsolete records */ 1365 1366 if (opt_i != -1) 1367 err = smbios_lookup_id(shp, opt_i, &s); 1368 else 1369 err = smbios_iter(shp, print_struct, stdout); 1370 1371 if (err != 0) { 1372 (void) fprintf(stderr, "%s: failed to access SMBIOS: %s\n", 1373 g_pname, smbios_errmsg(smbios_errno(shp))); 1374 smbios_close(shp); 1375 return (SMBIOS_ERROR); 1376 } 1377 1378 if (opt_i != -1) 1379 (void) print_struct(shp, &s, stdout); 1380 1381 smbios_close(shp); 1382 return (SMBIOS_SUCCESS); 1383 } 1384