1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright (c) 2018, Joyent, Inc. 14 * Copyright 2022 Oxide Computer Company 15 */ 16 17 /* 18 * Primordial SMBIOS test suite. At the moment, the purpose of this is just to 19 * test the recent SMBIOS 3.2 additions specific to the variable length slots. 20 * This should be evolved into a much fuller test suite. 21 */ 22 23 #include <umem.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #include <fcntl.h> 27 #include <limits.h> 28 #include <unistd.h> 29 #include "smbios_test.h" 30 31 static int test_dirfd = -1; 32 33 const char * 34 _umem_debug_init(void) 35 { 36 return ("default,verbose"); 37 } 38 39 const char * 40 _umem_logging_init(void) 41 { 42 return ("fail,contents"); 43 } 44 45 smbios_test_table_t * 46 smbios_test_table_init(smbios_entry_point_t type, uint_t version) 47 { 48 smbios_test_table_t *table; 49 50 if (type != SMBIOS_ENTRY_POINT_30) { 51 abort(); 52 } 53 54 table = umem_zalloc(sizeof (smbios_test_table_t), UMEM_DEFAULT); 55 if (table == NULL) { 56 return (NULL); 57 } 58 59 table->stt_data = umem_zalloc(SMBIOS_TEST_ALLOC_SIZE, UMEM_DEFAULT); 60 if (table->stt_data == NULL) { 61 umem_free(table, sizeof (smbios_test_table_t)); 62 return (NULL); 63 } 64 table->stt_buflen = SMBIOS_TEST_ALLOC_SIZE; 65 table->stt_type = type; 66 table->stt_version = version; 67 table->stt_nextid = 1; 68 69 return (table); 70 } 71 72 static void * 73 smbios_test_table_append_common(smbios_test_table_t *table, const void *buf, 74 size_t len) 75 { 76 void *start; 77 78 if (SIZE_MAX - table->stt_offset < len) 79 abort(); 80 81 if (len + table->stt_offset >= table->stt_buflen) { 82 void *newbuf; 83 size_t newlen = table->stt_buflen + SMBIOS_TEST_ALLOC_SIZE; 84 85 while (len + table->stt_offset >= newlen) { 86 newlen += SMBIOS_TEST_ALLOC_SIZE; 87 } 88 89 newbuf = umem_zalloc(newlen, UMEM_DEFAULT); 90 if (newbuf == NULL) { 91 err(EXIT_FAILURE, "failed to umem_zalloc for %lu bytes", 92 newlen); 93 } 94 95 (void) memcpy(newbuf, table->stt_data, table->stt_buflen); 96 umem_free(table->stt_data, table->stt_buflen); 97 table->stt_data = newbuf; 98 table->stt_buflen = newlen; 99 } 100 101 start = (void *)((uintptr_t)table->stt_data + table->stt_offset); 102 (void) memcpy(start, buf, len); 103 table->stt_offset += len; 104 105 return (start); 106 } 107 108 void 109 smbios_test_table_append_raw(smbios_test_table_t *table, const void *buf, 110 size_t len) 111 { 112 (void) smbios_test_table_append_common(table, buf, len); 113 } 114 115 void 116 smbios_test_table_append_string(smbios_test_table_t *table, const char *str) 117 { 118 size_t len = strlen(str) + 1; 119 (void) smbios_test_table_append_common(table, str, len); 120 } 121 122 void 123 smbios_test_table_str_fini(smbios_test_table_t *table) 124 { 125 const uint8_t endstring = 0; 126 127 smbios_test_table_append_raw(table, &endstring, sizeof (endstring)); 128 } 129 130 uint16_t 131 smbios_test_table_append(smbios_test_table_t *table, const void *buf, 132 size_t len) 133 { 134 smb_header_t *hdr; 135 uint16_t id; 136 137 hdr = smbios_test_table_append_common(table, buf, len); 138 table->stt_nents++; 139 140 id = table->stt_nextid; 141 hdr->smbh_hdl = htole16(table->stt_nextid); 142 table->stt_nextid++; 143 144 return (id); 145 } 146 147 void 148 smbios_test_table_append_eot(smbios_test_table_t *table) 149 { 150 smb_header_t eot; 151 uint8_t endstring = 0; 152 153 bzero(&eot, sizeof (eot)); 154 eot.smbh_type = SMB_TYPE_EOT; 155 eot.smbh_len = 4; 156 (void) smbios_test_table_append(table, &eot, sizeof (eot)); 157 (void) smbios_test_table_append_raw(table, &endstring, 158 sizeof (endstring)); 159 smbios_test_table_append_raw(table, &endstring, 160 sizeof (endstring)); 161 smbios_test_table_append_raw(table, &endstring, 162 sizeof (endstring)); 163 164 } 165 166 static uint8_t 167 smbios_test_table_checksum(const uint8_t *buf, size_t len) 168 { 169 uint8_t sum; 170 size_t i; 171 172 for (i = 0, sum = 0; i < len; i++) { 173 sum += buf[i]; 174 } 175 176 if (sum == 0) 177 return (0); 178 179 return ((uint8_t)(0x100 - sum)); 180 } 181 182 static void 183 smbios_test_table_snapshot(smbios_test_table_t *table, smbios_entry_t **entryp, 184 void **bufp, size_t *lenp) 185 { 186 smbios_30_entry_t *ent30; 187 188 switch (table->stt_type) { 189 case SMBIOS_ENTRY_POINT_30: 190 ent30 = &table->stt_entry.ep30; 191 192 (void) memcpy(ent30->smbe_eanchor, SMB3_ENTRY_EANCHOR, 193 sizeof (ent30->smbe_eanchor)); 194 ent30->smbe_ecksum = 0; 195 ent30->smbe_elen = sizeof (*ent30); 196 ent30->smbe_major = (table->stt_version >> 8) & 0xff; 197 ent30->smbe_minor = table->stt_version & 0xff; 198 ent30->smbe_docrev = 0; 199 ent30->smbe_revision = 1; 200 ent30->smbe_reserved = 0; 201 ent30->smbe_stlen = htole32(table->stt_offset); 202 ent30->smbe_staddr = htole64(P2ROUNDUP(sizeof (*ent30), 16)); 203 204 ent30->smbe_ecksum = smbios_test_table_checksum((void *)ent30, 205 sizeof (*ent30)); 206 break; 207 default: 208 abort(); 209 } 210 211 *entryp = &table->stt_entry; 212 *bufp = table->stt_data; 213 *lenp = table->stt_offset; 214 } 215 216 static void 217 smbios_test_table_fini(smbios_test_table_t *table) 218 { 219 if (table == NULL) { 220 return; 221 } 222 223 if (table->stt_data != NULL) { 224 umem_free(table->stt_data, table->stt_buflen); 225 } 226 227 umem_free(table, sizeof (smbios_test_table_t)); 228 } 229 230 static const smbios_test_t smbios_tests[] = { 231 { 232 .st_entry = SMBIOS_ENTRY_POINT_30, 233 .st_tvers = SMB_VERSION, 234 .st_libvers = 0xffff, 235 .st_mktable = smbios_test_badvers_mktable, 236 .st_desc = "bad library version" 237 }, { 238 .st_entry = SMBIOS_ENTRY_POINT_30, 239 .st_tvers = SMB_VERSION, 240 .st_libvers = 0, 241 .st_mktable = smbios_test_badvers_mktable, 242 .st_desc = "bad library version (zeros)" 243 }, { 244 .st_entry = SMBIOS_ENTRY_POINT_30, 245 .st_tvers = SMB_VERSION, 246 .st_libvers = SMB_VERSION, 247 .st_mktable = smbios_test_slot_mktable, 248 .st_canopen = B_TRUE, 249 .st_verify = smbios_test_verify_badids, 250 .st_desc = "smbios_info_* with bad id" 251 }, { 252 .st_entry = SMBIOS_ENTRY_POINT_30, 253 .st_tvers = SMB_VERSION, 254 .st_libvers = SMB_VERSION, 255 .st_mktable = smbios_test_slot_mktable, 256 .st_canopen = B_TRUE, 257 .st_verify = smbios_test_verify_strings, 258 .st_desc = "smbios string functions" 259 }, { 260 .st_entry = SMBIOS_ENTRY_POINT_30, 261 .st_tvers = SMB_VERSION_32, 262 .st_libvers = SMB_VERSION, 263 .st_mktable = smbios_test_slot_mktable, 264 .st_canopen = B_TRUE, 265 .st_verify = smbios_test_slot_verify, 266 .st_desc = "slot 3.2" 267 }, { 268 .st_entry = SMBIOS_ENTRY_POINT_30, 269 .st_tvers = SMB_VERSION_34, 270 .st_libvers = SMB_VERSION, 271 .st_mktable = smbios_test_slot_mktable_34_nopeers, 272 .st_canopen = B_TRUE, 273 .st_verify = smbios_test_slot_verify_34_nopeers, 274 .st_desc = "slot 3.4 without peers" 275 }, { 276 .st_entry = SMBIOS_ENTRY_POINT_30, 277 .st_tvers = SMB_VERSION_34, 278 .st_libvers = SMB_VERSION, 279 .st_mktable = smbios_test_slot_mktable_34_peers, 280 .st_canopen = B_TRUE, 281 .st_verify = smbios_test_slot_verify_34_peers, 282 .st_desc = "slot 3.4 with peers" 283 }, { 284 .st_entry = SMBIOS_ENTRY_POINT_30, 285 .st_tvers = SMB_VERSION_35, 286 .st_libvers = SMB_VERSION_34, 287 .st_mktable = smbios_test_slot_mktable_35, 288 .st_canopen = B_TRUE, 289 .st_verify = smbios_test_slot_verify_34_overrun, 290 .st_desc = "slot 3.5 against 3.4 lib" 291 }, { 292 .st_entry = SMBIOS_ENTRY_POINT_30, 293 .st_tvers = SMB_VERSION_35, 294 .st_libvers = SMB_VERSION, 295 .st_mktable = smbios_test_slot_mktable_35, 296 .st_canopen = B_TRUE, 297 .st_verify = smbios_test_slot_verify_35, 298 .st_desc = "slot 3.5" 299 }, { 300 .st_entry = SMBIOS_ENTRY_POINT_30, 301 .st_tvers = SMB_VERSION_32, 302 .st_libvers = SMB_VERSION_32, 303 .st_mktable = smbios_test_memdevice_mktable_32, 304 .st_canopen = B_TRUE, 305 .st_verify = smbios_test_memdevice_verify_32, 306 .st_desc = "memory device 3.2 % 3.2" 307 }, { 308 .st_entry = SMBIOS_ENTRY_POINT_30, 309 .st_tvers = SMB_VERSION_32, 310 .st_libvers = SMB_VERSION_33, 311 .st_mktable = smbios_test_memdevice_mktable_32, 312 .st_canopen = B_TRUE, 313 .st_verify = smbios_test_memdevice_verify_32_33, 314 .st_desc = "memory device 3.2 % 3.3" 315 }, { 316 .st_entry = SMBIOS_ENTRY_POINT_30, 317 .st_tvers = SMB_VERSION_33, 318 .st_libvers = SMB_VERSION_33, 319 .st_mktable = smbios_test_memdevice_mktable_33, 320 .st_canopen = B_TRUE, 321 .st_verify = smbios_test_memdevice_verify_33, 322 .st_desc = "memory device 3.3" 323 }, { 324 .st_entry = SMBIOS_ENTRY_POINT_30, 325 .st_tvers = SMB_VERSION_33, 326 .st_libvers = SMB_VERSION_33, 327 .st_mktable = smbios_test_memdevice_mktable_33ext, 328 .st_canopen = B_TRUE, 329 .st_verify = smbios_test_memdevice_verify_33ext, 330 .st_desc = "memory device 3.3" 331 }, { 332 .st_entry = SMBIOS_ENTRY_POINT_30, 333 .st_tvers = SMB_VERSION, 334 .st_libvers = SMB_VERSION, 335 .st_mktable = smbios_test_pinfo_mktable_amd64, 336 .st_canopen = B_TRUE, 337 .st_verify = smbios_test_pinfo_verify_amd64, 338 .st_desc = "processor additional information - amd64" 339 }, { 340 .st_entry = SMBIOS_ENTRY_POINT_30, 341 .st_tvers = SMB_VERSION, 342 .st_libvers = SMB_VERSION, 343 .st_mktable = smbios_test_pinfo_mktable_riscv, 344 .st_canopen = B_TRUE, 345 .st_verify = smbios_test_pinfo_verify_riscv, 346 .st_desc = "processor additional information - riscv" 347 }, { 348 .st_entry = SMBIOS_ENTRY_POINT_30, 349 .st_tvers = SMB_VERSION, 350 .st_libvers = SMB_VERSION, 351 .st_mktable = smbios_test_pinfo_mktable_invlen1, 352 .st_canopen = B_TRUE, 353 .st_verify = smbios_test_pinfo_verify_invlen1, 354 .st_desc = "processor additional information - bad table length 1" 355 }, { 356 .st_entry = SMBIOS_ENTRY_POINT_30, 357 .st_tvers = SMB_VERSION, 358 .st_libvers = SMB_VERSION, 359 .st_mktable = smbios_test_pinfo_mktable_invlen2, 360 .st_canopen = B_TRUE, 361 .st_verify = smbios_test_pinfo_verify_invlen2, 362 .st_desc = "processor additional information - bad table length 2" 363 }, { 364 .st_entry = SMBIOS_ENTRY_POINT_30, 365 .st_tvers = SMB_VERSION, 366 .st_libvers = SMB_VERSION, 367 .st_mktable = smbios_test_pinfo_mktable_invlen3, 368 .st_canopen = B_TRUE, 369 .st_verify = smbios_test_pinfo_verify_invlen3, 370 .st_desc = "processor additional information - bad table length 3" 371 }, { 372 .st_entry = SMBIOS_ENTRY_POINT_30, 373 .st_tvers = SMB_VERSION, 374 .st_libvers = SMB_VERSION, 375 .st_mktable = smbios_test_pinfo_mktable_invlen4, 376 .st_canopen = B_TRUE, 377 .st_verify = smbios_test_pinfo_verify_invlen4, 378 .st_desc = "processor additional information - bad table length 4" 379 }, { 380 .st_entry = SMBIOS_ENTRY_POINT_30, 381 .st_tvers = SMB_VERSION, 382 .st_libvers = SMB_VERSION, 383 .st_mktable = smbios_test_memdevice_mktable_32, 384 .st_canopen = B_TRUE, 385 .st_verify = smbios_test_pinfo_verify_badtype, 386 .st_desc = "processor additional information - bad type" 387 }, { 388 .st_entry = SMBIOS_ENTRY_POINT_30, 389 .st_tvers = SMB_VERSION, 390 .st_libvers = SMB_VERSION, 391 .st_mktable = smbios_test_strprop_mktable_invlen1, 392 .st_canopen = B_TRUE, 393 .st_verify = smbios_test_strprop_verify_invlen1, 394 .st_desc = "string property - bad table length 1" 395 }, { 396 .st_entry = SMBIOS_ENTRY_POINT_30, 397 .st_tvers = SMB_VERSION, 398 .st_libvers = SMB_VERSION, 399 .st_mktable = smbios_test_strprop_mktable_invlen2, 400 .st_canopen = B_TRUE, 401 .st_verify = smbios_test_strprop_verify_invlen2, 402 .st_desc = "string property - bad table length 2" 403 }, { 404 .st_entry = SMBIOS_ENTRY_POINT_30, 405 .st_tvers = SMB_VERSION, 406 .st_libvers = SMB_VERSION, 407 .st_mktable = smbios_test_memdevice_mktable_32, 408 .st_canopen = B_TRUE, 409 .st_verify = smbios_test_strprop_verify_badtype, 410 .st_desc = "string property - bad type" 411 }, { 412 .st_entry = SMBIOS_ENTRY_POINT_30, 413 .st_tvers = SMB_VERSION, 414 .st_libvers = SMB_VERSION, 415 .st_mktable = smbios_test_strprop_mktable_basic, 416 .st_canopen = B_TRUE, 417 .st_verify = smbios_test_strprop_verify_basic, 418 .st_desc = "string property - basic" 419 }, { 420 .st_entry = SMBIOS_ENTRY_POINT_30, 421 .st_tvers = SMB_VERSION, 422 .st_libvers = SMB_VERSION, 423 .st_mktable = smbios_test_strprop_mktable_badstr, 424 .st_canopen = B_TRUE, 425 .st_verify = smbios_test_strprop_verify_badstr, 426 .st_desc = "string property - bad string" 427 }, { 428 .st_entry = SMBIOS_ENTRY_POINT_30, 429 .st_tvers = SMB_VERSION, 430 .st_libvers = SMB_VERSION, 431 .st_mktable = smbios_test_fwinfo_mktable_invlen_base, 432 .st_canopen = B_TRUE, 433 .st_verify = smbios_test_fwinfo_verify_invlen_base, 434 .st_desc = "firmware inventory - bad base length" 435 }, { 436 .st_entry = SMBIOS_ENTRY_POINT_30, 437 .st_tvers = SMB_VERSION, 438 .st_libvers = SMB_VERSION, 439 .st_mktable = smbios_test_fwinfo_mktable_invlen_comps, 440 .st_canopen = B_TRUE, 441 .st_verify = smbios_test_fwinfo_verify_invlen_comps, 442 .st_desc = "firmware inventory - bad comp length" 443 }, { 444 .st_entry = SMBIOS_ENTRY_POINT_30, 445 .st_tvers = SMB_VERSION, 446 .st_libvers = SMB_VERSION, 447 .st_mktable = smbios_test_memdevice_mktable_32, 448 .st_canopen = B_TRUE, 449 .st_verify = smbios_test_fwinfo_verify_badtype, 450 .st_desc = "firmware inventory - bad type" 451 }, { 452 .st_entry = SMBIOS_ENTRY_POINT_30, 453 .st_tvers = SMB_VERSION, 454 .st_libvers = SMB_VERSION, 455 .st_mktable = smbios_test_fwinfo_mktable_nocomps, 456 .st_canopen = B_TRUE, 457 .st_verify = smbios_test_fwinfo_verify_nocomps, 458 .st_desc = "firmware inventory - no components" 459 }, { 460 .st_entry = SMBIOS_ENTRY_POINT_30, 461 .st_tvers = SMB_VERSION, 462 .st_libvers = SMB_VERSION, 463 .st_mktable = smbios_test_fwinfo_mktable_comps, 464 .st_canopen = B_TRUE, 465 .st_verify = smbios_test_fwinfo_verify_comps, 466 .st_desc = "firmware inventory - components" 467 }, { 468 .st_entry = SMBIOS_ENTRY_POINT_30, 469 .st_tvers = SMB_VERSION_24, 470 .st_libvers = SMB_VERSION, 471 .st_mktable = smbios_test_chassis_mktable_invlen_base, 472 .st_canopen = B_TRUE, 473 .st_verify = smbios_test_chassis_verify_invlen, 474 .st_desc = "chassis - bad length (2.4 table)" 475 }, { 476 .st_entry = SMBIOS_ENTRY_POINT_30, 477 .st_tvers = SMB_VERSION, 478 .st_libvers = SMB_VERSION, 479 .st_mktable = smbios_test_chassis_mktable_invlen_base, 480 .st_canopen = B_TRUE, 481 .st_verify = smbios_test_chassis_verify_invlen, 482 .st_desc = "chassis - bad length (latest version)" 483 }, { 484 .st_entry = SMBIOS_ENTRY_POINT_30, 485 .st_tvers = SMB_VERSION, 486 .st_libvers = SMB_VERSION, 487 .st_mktable = smbios_test_chassis_mktable_base, 488 .st_canopen = B_TRUE, 489 .st_verify = smbios_test_chassis_verify_invlen, 490 .st_desc = "chassis - bad length, expect sku" 491 }, { 492 .st_entry = SMBIOS_ENTRY_POINT_30, 493 .st_tvers = SMB_VERSION_24, 494 .st_libvers = SMB_VERSION, 495 .st_mktable = smbios_test_chassis_mktable_base, 496 .st_canopen = B_TRUE, 497 .st_verify = smbios_test_chassis_verify_base, 498 .st_desc = "chassis - basic 2.4 version" 499 }, { 500 .st_entry = SMBIOS_ENTRY_POINT_30, 501 .st_tvers = SMB_VERSION, 502 .st_libvers = SMB_VERSION, 503 .st_mktable = smbios_test_chassis_mktable_sku_nocomps, 504 .st_canopen = B_TRUE, 505 .st_verify = smbios_test_chassis_verify_sku_nocomps, 506 .st_desc = "chassis - sku, but no components" 507 }, { 508 .st_entry = SMBIOS_ENTRY_POINT_30, 509 .st_tvers = SMB_VERSION_24, 510 .st_libvers = SMB_VERSION, 511 .st_mktable = smbios_test_chassis_mktable_comps, 512 .st_canopen = B_TRUE, 513 .st_verify = smbios_test_chassis_verify_comps, 514 .st_desc = "chassis - 2.4 version with comps" 515 }, { 516 .st_entry = SMBIOS_ENTRY_POINT_30, 517 .st_tvers = SMB_VERSION, 518 .st_libvers = SMB_VERSION, 519 .st_mktable = smbios_test_chassis_mktable_sku_nocomps, 520 .st_canopen = B_TRUE, 521 .st_verify = smbios_test_chassis_verify_sku_nocomps, 522 .st_desc = "chassis - sku + comps" 523 }, { 524 .st_entry = SMBIOS_ENTRY_POINT_30, 525 .st_tvers = SMB_VERSION_25, 526 .st_libvers = SMB_VERSION, 527 .st_mktable = smbios_test_proc_mktable_25, 528 .st_canopen = B_TRUE, 529 .st_verify = smbios_test_proc_verify_25, 530 .st_desc = "SMBIOS 2.5 processor" 531 }, { 532 .st_entry = SMBIOS_ENTRY_POINT_30, 533 .st_tvers = SMB_VERSION_36, 534 .st_libvers = SMB_VERSION, 535 .st_mktable = smbios_test_proc_mktable_36, 536 .st_canopen = B_TRUE, 537 .st_verify = smbios_test_proc_verify_36, 538 .st_desc = "SMBIOS 3.6 processor" 539 }, { 540 .st_entry = SMBIOS_ENTRY_POINT_30, 541 .st_tvers = SMB_VERSION_36, 542 .st_libvers = SMB_VERSION_25, 543 .st_mktable = smbios_test_proc_mktable_36, 544 .st_canopen = B_TRUE, 545 .st_verify = smbios_test_proc_verify_36_25, 546 .st_desc = "SMBIOS 3.6 processor, 2.5 client" 547 } 548 }; 549 550 static boolean_t 551 smbios_test_run_one(const smbios_test_t *test) 552 { 553 smbios_test_table_t *table = NULL; 554 smbios_hdl_t *hdl = NULL; 555 void *buf; 556 size_t len; 557 smbios_entry_t *entry; 558 int err = 0; 559 boolean_t ret = B_FALSE; 560 561 table = smbios_test_table_init(test->st_entry, test->st_tvers); 562 if (!test->st_mktable(table)) { 563 goto out; 564 } 565 566 smbios_test_table_snapshot(table, &entry, &buf, &len); 567 hdl = smbios_bufopen(entry, buf, len, test->st_libvers, SMB_FL_DEBUG, 568 &err); 569 if (test->st_canopen) { 570 if (hdl == NULL) { 571 warnx("failed to create table for test %s: %s", 572 test->st_desc, smbios_errmsg(err)); 573 goto out; 574 } 575 } else { 576 if (hdl != NULL) { 577 warnx("accidentally created table for test %s, " 578 "expected failure", test->st_desc); 579 } else { 580 ret = B_TRUE; 581 } 582 goto out; 583 } 584 585 if (test->st_verify(hdl)) { 586 ret = B_TRUE; 587 } 588 589 if (hdl != NULL && test_dirfd > -1) { 590 int fd; 591 char fname[PATH_MAX]; 592 593 (void) snprintf(fname, sizeof (fname), "%s.smbios", 594 test->st_desc); 595 fd = openat(test_dirfd, fname, O_RDWR | O_CREAT, 0644); 596 if (fd < 0) { 597 warn("failed to dump test %s, failed to open output " 598 "file", test->st_desc); 599 } else { 600 if (smbios_write(hdl, fd) != 0) { 601 warnx("failed to dump test %s: %s", 602 test->st_desc, 603 smbios_errmsg(smbios_errno(hdl))); 604 } else { 605 (void) close(fd); 606 } 607 } 608 } 609 out: 610 if (hdl != NULL) { 611 smbios_close(hdl); 612 } 613 614 if (table != NULL) { 615 smbios_test_table_fini(table); 616 } 617 618 if (ret) { 619 (void) printf("TEST PASSED: %s\n", test->st_desc); 620 } else { 621 (void) printf("TEST FAILED: %s\n", test->st_desc); 622 } 623 624 return (ret); 625 } 626 627 int 628 main(int argc, char *argv[]) 629 { 630 int ret = 0, c; 631 size_t i; 632 const char *outdir = NULL; 633 634 while ((c = getopt(argc, argv, ":d:")) != -1) { 635 switch (c) { 636 case 'd': 637 outdir = optarg; 638 break; 639 case '?': 640 errx(EXIT_FAILURE, "unknown option: -%c", optopt); 641 case ':': 642 errx(EXIT_FAILURE, "-%c requires an operand", optopt); 643 } 644 } 645 646 if (outdir != NULL) { 647 if ((test_dirfd = open(outdir, O_RDONLY)) < 0) { 648 err(EXIT_FAILURE, "failed to open %s", outdir); 649 } 650 } 651 652 for (i = 0; i < ARRAY_SIZE(smbios_tests); i++) { 653 if (!smbios_test_run_one(&smbios_tests[i])) { 654 ret = 1; 655 } 656 } 657 658 if (ret == 0) { 659 (void) printf("All tests passed successfully\n"); 660 } 661 662 return (ret); 663 } 664