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 2023 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 %zu 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_32, 318 .st_libvers = SMB_VERSION_37, 319 .st_mktable = smbios_test_memdevice_mktable_32, 320 .st_canopen = B_TRUE, 321 .st_verify = smbios_test_memdevice_verify_32_37, 322 .st_desc = "memory device 3.2 % 3.7" 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_33, 328 .st_canopen = B_TRUE, 329 .st_verify = smbios_test_memdevice_verify_33, 330 .st_desc = "memory device 3.3" 331 }, { 332 .st_entry = SMBIOS_ENTRY_POINT_30, 333 .st_tvers = SMB_VERSION_33, 334 .st_libvers = SMB_VERSION_33, 335 .st_mktable = smbios_test_memdevice_mktable_33ext, 336 .st_canopen = B_TRUE, 337 .st_verify = smbios_test_memdevice_verify_33ext, 338 .st_desc = "memory device 3.3 with extended data" 339 }, { 340 .st_entry = SMBIOS_ENTRY_POINT_30, 341 .st_tvers = SMB_VERSION_37, 342 .st_libvers = SMB_VERSION_37, 343 .st_mktable = smbios_test_memdevice_mktable_37, 344 .st_canopen = B_TRUE, 345 .st_verify = smbios_test_memdevice_verify_37, 346 .st_desc = "memory device 3.7" 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_amd64, 352 .st_canopen = B_TRUE, 353 .st_verify = smbios_test_pinfo_verify_amd64, 354 .st_desc = "processor additional information - amd64" 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_riscv, 360 .st_canopen = B_TRUE, 361 .st_verify = smbios_test_pinfo_verify_riscv, 362 .st_desc = "processor additional information - riscv" 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_invlen1, 368 .st_canopen = B_TRUE, 369 .st_verify = smbios_test_pinfo_verify_invlen1, 370 .st_desc = "processor additional information - bad table length 1" 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_invlen2, 376 .st_canopen = B_TRUE, 377 .st_verify = smbios_test_pinfo_verify_invlen2, 378 .st_desc = "processor additional information - bad table length 2" 379 }, { 380 .st_entry = SMBIOS_ENTRY_POINT_30, 381 .st_tvers = SMB_VERSION, 382 .st_libvers = SMB_VERSION, 383 .st_mktable = smbios_test_pinfo_mktable_invlen3, 384 .st_canopen = B_TRUE, 385 .st_verify = smbios_test_pinfo_verify_invlen3, 386 .st_desc = "processor additional information - bad table length 3" 387 }, { 388 .st_entry = SMBIOS_ENTRY_POINT_30, 389 .st_tvers = SMB_VERSION, 390 .st_libvers = SMB_VERSION, 391 .st_mktable = smbios_test_pinfo_mktable_invlen4, 392 .st_canopen = B_TRUE, 393 .st_verify = smbios_test_pinfo_verify_invlen4, 394 .st_desc = "processor additional information - bad table length 4" 395 }, { 396 .st_entry = SMBIOS_ENTRY_POINT_30, 397 .st_tvers = SMB_VERSION, 398 .st_libvers = SMB_VERSION, 399 .st_mktable = smbios_test_memdevice_mktable_32, 400 .st_canopen = B_TRUE, 401 .st_verify = smbios_test_pinfo_verify_badtype, 402 .st_desc = "processor additional information - bad type" 403 }, { 404 .st_entry = SMBIOS_ENTRY_POINT_30, 405 .st_tvers = SMB_VERSION, 406 .st_libvers = SMB_VERSION, 407 .st_mktable = smbios_test_strprop_mktable_invlen1, 408 .st_canopen = B_TRUE, 409 .st_verify = smbios_test_strprop_verify_invlen1, 410 .st_desc = "string property - bad table length 1" 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_invlen2, 416 .st_canopen = B_TRUE, 417 .st_verify = smbios_test_strprop_verify_invlen2, 418 .st_desc = "string property - bad table length 2" 419 }, { 420 .st_entry = SMBIOS_ENTRY_POINT_30, 421 .st_tvers = SMB_VERSION, 422 .st_libvers = SMB_VERSION, 423 .st_mktable = smbios_test_memdevice_mktable_32, 424 .st_canopen = B_TRUE, 425 .st_verify = smbios_test_strprop_verify_badtype, 426 .st_desc = "string property - bad type" 427 }, { 428 .st_entry = SMBIOS_ENTRY_POINT_30, 429 .st_tvers = SMB_VERSION, 430 .st_libvers = SMB_VERSION, 431 .st_mktable = smbios_test_strprop_mktable_basic, 432 .st_canopen = B_TRUE, 433 .st_verify = smbios_test_strprop_verify_basic, 434 .st_desc = "string property - basic" 435 }, { 436 .st_entry = SMBIOS_ENTRY_POINT_30, 437 .st_tvers = SMB_VERSION, 438 .st_libvers = SMB_VERSION, 439 .st_mktable = smbios_test_strprop_mktable_badstr, 440 .st_canopen = B_TRUE, 441 .st_verify = smbios_test_strprop_verify_badstr, 442 .st_desc = "string property - bad string" 443 }, { 444 .st_entry = SMBIOS_ENTRY_POINT_30, 445 .st_tvers = SMB_VERSION, 446 .st_libvers = SMB_VERSION, 447 .st_mktable = smbios_test_fwinfo_mktable_invlen_base, 448 .st_canopen = B_TRUE, 449 .st_verify = smbios_test_fwinfo_verify_invlen_base, 450 .st_desc = "firmware inventory - bad base length" 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_invlen_comps, 456 .st_canopen = B_TRUE, 457 .st_verify = smbios_test_fwinfo_verify_invlen_comps, 458 .st_desc = "firmware inventory - bad comp length" 459 }, { 460 .st_entry = SMBIOS_ENTRY_POINT_30, 461 .st_tvers = SMB_VERSION, 462 .st_libvers = SMB_VERSION, 463 .st_mktable = smbios_test_memdevice_mktable_32, 464 .st_canopen = B_TRUE, 465 .st_verify = smbios_test_fwinfo_verify_badtype, 466 .st_desc = "firmware inventory - bad type" 467 }, { 468 .st_entry = SMBIOS_ENTRY_POINT_30, 469 .st_tvers = SMB_VERSION, 470 .st_libvers = SMB_VERSION, 471 .st_mktable = smbios_test_fwinfo_mktable_nocomps, 472 .st_canopen = B_TRUE, 473 .st_verify = smbios_test_fwinfo_verify_nocomps, 474 .st_desc = "firmware inventory - no components" 475 }, { 476 .st_entry = SMBIOS_ENTRY_POINT_30, 477 .st_tvers = SMB_VERSION, 478 .st_libvers = SMB_VERSION, 479 .st_mktable = smbios_test_fwinfo_mktable_comps, 480 .st_canopen = B_TRUE, 481 .st_verify = smbios_test_fwinfo_verify_comps, 482 .st_desc = "firmware inventory - components" 483 }, { 484 .st_entry = SMBIOS_ENTRY_POINT_30, 485 .st_tvers = SMB_VERSION_24, 486 .st_libvers = SMB_VERSION, 487 .st_mktable = smbios_test_chassis_mktable_invlen_base, 488 .st_canopen = B_TRUE, 489 .st_verify = smbios_test_chassis_verify_invlen, 490 .st_desc = "chassis - bad length (2.4 table)" 491 }, { 492 .st_entry = SMBIOS_ENTRY_POINT_30, 493 .st_tvers = SMB_VERSION, 494 .st_libvers = SMB_VERSION, 495 .st_mktable = smbios_test_chassis_mktable_invlen_base, 496 .st_canopen = B_TRUE, 497 .st_verify = smbios_test_chassis_verify_invlen, 498 .st_desc = "chassis - bad length (latest 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_base, 504 .st_canopen = B_TRUE, 505 .st_verify = smbios_test_chassis_verify_invlen, 506 .st_desc = "chassis - bad length, expect sku" 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_base, 512 .st_canopen = B_TRUE, 513 .st_verify = smbios_test_chassis_verify_base, 514 .st_desc = "chassis - basic 2.4 version" 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, but no components" 523 }, { 524 .st_entry = SMBIOS_ENTRY_POINT_30, 525 .st_tvers = SMB_VERSION_24, 526 .st_libvers = SMB_VERSION, 527 .st_mktable = smbios_test_chassis_mktable_comps, 528 .st_canopen = B_TRUE, 529 .st_verify = smbios_test_chassis_verify_comps, 530 .st_desc = "chassis - 2.4 version with comps" 531 }, { 532 .st_entry = SMBIOS_ENTRY_POINT_30, 533 .st_tvers = SMB_VERSION, 534 .st_libvers = SMB_VERSION, 535 .st_mktable = smbios_test_chassis_mktable_sku_nocomps, 536 .st_canopen = B_TRUE, 537 .st_verify = smbios_test_chassis_verify_sku_nocomps, 538 .st_desc = "chassis - sku + comps" 539 }, { 540 .st_entry = SMBIOS_ENTRY_POINT_30, 541 .st_tvers = SMB_VERSION_25, 542 .st_libvers = SMB_VERSION, 543 .st_mktable = smbios_test_proc_mktable_25, 544 .st_canopen = B_TRUE, 545 .st_verify = smbios_test_proc_verify_25, 546 .st_desc = "SMBIOS 2.5 processor" 547 }, { 548 .st_entry = SMBIOS_ENTRY_POINT_30, 549 .st_tvers = SMB_VERSION_36, 550 .st_libvers = SMB_VERSION, 551 .st_mktable = smbios_test_proc_mktable_36, 552 .st_canopen = B_TRUE, 553 .st_verify = smbios_test_proc_verify_36, 554 .st_desc = "SMBIOS 3.6 processor" 555 }, { 556 .st_entry = SMBIOS_ENTRY_POINT_30, 557 .st_tvers = SMB_VERSION_36, 558 .st_libvers = SMB_VERSION_25, 559 .st_mktable = smbios_test_proc_mktable_36, 560 .st_canopen = B_TRUE, 561 .st_verify = smbios_test_proc_verify_36_25, 562 .st_desc = "SMBIOS 3.6 processor, 2.5 client" 563 }, { 564 .st_entry = SMBIOS_ENTRY_POINT_30, 565 .st_tvers = SMB_VERSION, 566 .st_libvers = SMB_VERSION, 567 .st_mktable = smbios_test_extmem_mktable_cs, 568 .st_canopen = B_TRUE, 569 .st_verify = smbios_test_extmem_verify_cs, 570 .st_desc = "SMBIOS Sun extended memory device with cs" 571 }, { 572 .st_entry = SMBIOS_ENTRY_POINT_30, 573 .st_tvers = SMB_VERSION, 574 .st_libvers = SMB_VERSION, 575 .st_mktable = smbios_test_extmem_mktable_nocs, 576 .st_canopen = B_TRUE, 577 .st_verify = smbios_test_extmem_verify_nocs, 578 .st_desc = "SMBIOS Sun extended memory device with no cs" 579 }, { 580 .st_entry = SMBIOS_ENTRY_POINT_30, 581 .st_tvers = SMB_VERSION, 582 .st_libvers = SMB_VERSION, 583 .st_mktable = smbios_test_extmem_mktable_invlen_cs, 584 .st_canopen = B_TRUE, 585 .st_verify = smbios_test_extmem_verify_invlen_cs, 586 .st_desc = "SMBIOS Sun extended memory device invalid cs length" 587 } 588 }; 589 590 static boolean_t 591 smbios_test_run_one(const smbios_test_t *test) 592 { 593 smbios_test_table_t *table = NULL; 594 smbios_hdl_t *hdl = NULL; 595 void *buf; 596 size_t len; 597 smbios_entry_t *entry; 598 int err = 0; 599 boolean_t ret = B_FALSE; 600 601 table = smbios_test_table_init(test->st_entry, test->st_tvers); 602 if (!test->st_mktable(table)) { 603 goto out; 604 } 605 606 smbios_test_table_snapshot(table, &entry, &buf, &len); 607 hdl = smbios_bufopen(entry, buf, len, test->st_libvers, SMB_FL_DEBUG, 608 &err); 609 if (test->st_canopen) { 610 if (hdl == NULL) { 611 warnx("failed to create table for test %s: %s", 612 test->st_desc, smbios_errmsg(err)); 613 goto out; 614 } 615 } else { 616 if (hdl != NULL) { 617 warnx("accidentally created table for test %s, " 618 "expected failure", test->st_desc); 619 } else { 620 ret = B_TRUE; 621 } 622 goto out; 623 } 624 625 if (test->st_verify(hdl)) { 626 ret = B_TRUE; 627 } 628 629 if (hdl != NULL && test_dirfd > -1) { 630 int fd; 631 char fname[PATH_MAX]; 632 633 (void) snprintf(fname, sizeof (fname), "%s.smbios", 634 test->st_desc); 635 fd = openat(test_dirfd, fname, O_RDWR | O_CREAT, 0644); 636 if (fd < 0) { 637 warn("failed to dump test %s, failed to open output " 638 "file", test->st_desc); 639 } else { 640 if (smbios_write(hdl, fd) != 0) { 641 warnx("failed to dump test %s: %s", 642 test->st_desc, 643 smbios_errmsg(smbios_errno(hdl))); 644 } else { 645 (void) close(fd); 646 } 647 } 648 } 649 out: 650 if (hdl != NULL) { 651 smbios_close(hdl); 652 } 653 654 if (table != NULL) { 655 smbios_test_table_fini(table); 656 } 657 658 if (ret) { 659 (void) printf("TEST PASSED: %s\n", test->st_desc); 660 } else { 661 (void) printf("TEST FAILED: %s\n", test->st_desc); 662 } 663 664 return (ret); 665 } 666 667 int 668 main(int argc, char *argv[]) 669 { 670 int ret = 0, c; 671 size_t i; 672 const char *outdir = NULL; 673 674 while ((c = getopt(argc, argv, ":d:")) != -1) { 675 switch (c) { 676 case 'd': 677 outdir = optarg; 678 break; 679 case '?': 680 errx(EXIT_FAILURE, "unknown option: -%c", optopt); 681 case ':': 682 errx(EXIT_FAILURE, "-%c requires an operand", optopt); 683 } 684 } 685 686 if (outdir != NULL) { 687 if ((test_dirfd = open(outdir, O_RDONLY)) < 0) { 688 err(EXIT_FAILURE, "failed to open %s", outdir); 689 } 690 } 691 692 for (i = 0; i < ARRAY_SIZE(smbios_tests); i++) { 693 if (!smbios_test_run_one(&smbios_tests[i])) { 694 ret = 1; 695 } 696 } 697 698 if (ret == 0) { 699 (void) printf("All tests passed successfully\n"); 700 } 701 702 return (ret); 703 } 704