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 2024 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 *
_umem_debug_init(void)34 _umem_debug_init(void)
35 {
36 return ("default,verbose");
37 }
38
39 const char *
_umem_logging_init(void)40 _umem_logging_init(void)
41 {
42 return ("fail,contents");
43 }
44
45 smbios_test_table_t *
smbios_test_table_init(smbios_entry_point_t type,uint_t version)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 *
smbios_test_table_append_common(smbios_test_table_t * table,const void * buf,size_t len)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
smbios_test_table_append_raw(smbios_test_table_t * table,const void * buf,size_t len)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
smbios_test_table_append_string(smbios_test_table_t * table,const char * str)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
smbios_test_table_str_fini(smbios_test_table_t * table)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
smbios_test_table_append(smbios_test_table_t * table,const void * buf,size_t len)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
smbios_test_table_append_eot(smbios_test_table_t * table)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
smbios_test_table_checksum(const uint8_t * buf,size_t len)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
smbios_test_table_snapshot(smbios_test_table_t * table,smbios_entry_t ** entryp,void ** bufp,size_t * lenp)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
smbios_test_table_fini(smbios_test_table_t * table)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_24,
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_base,
506 .st_desc = "chassis - basic 2.4 version"
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_part,
512 .st_canopen = B_TRUE,
513 .st_verify = smbios_test_chassis_verify_base,
514 .st_desc = "chassis - hv 2.4 version"
515 }, {
516 .st_entry = SMBIOS_ENTRY_POINT_30,
517 .st_tvers = SMB_VERSION_27,
518 .st_libvers = SMB_VERSION,
519 .st_mktable = smbios_test_chassis_mktable_part,
520 .st_canopen = B_TRUE,
521 .st_verify = smbios_test_chassis_verify_base,
522 .st_desc = "chassis - hv 2.7 version"
523 }, {
524 .st_entry = SMBIOS_ENTRY_POINT_30,
525 .st_tvers = SMB_VERSION,
526 .st_libvers = SMB_VERSION,
527 .st_mktable = smbios_test_chassis_mktable_sku_nocomps,
528 .st_canopen = B_TRUE,
529 .st_verify = smbios_test_chassis_verify_sku_nocomps,
530 .st_desc = "chassis - sku, but no components"
531 }, {
532 .st_entry = SMBIOS_ENTRY_POINT_30,
533 .st_tvers = SMB_VERSION_24,
534 .st_libvers = SMB_VERSION,
535 .st_mktable = smbios_test_chassis_mktable_comps,
536 .st_canopen = B_TRUE,
537 .st_verify = smbios_test_chassis_verify_comps,
538 .st_desc = "chassis - 2.4 version with comps"
539 }, {
540 .st_entry = SMBIOS_ENTRY_POINT_30,
541 .st_tvers = SMB_VERSION,
542 .st_libvers = SMB_VERSION,
543 .st_mktable = smbios_test_chassis_mktable_sku_nocomps,
544 .st_canopen = B_TRUE,
545 .st_verify = smbios_test_chassis_verify_sku_nocomps,
546 .st_desc = "chassis - sku + comps"
547 }, {
548 .st_entry = SMBIOS_ENTRY_POINT_30,
549 .st_tvers = SMB_VERSION_25,
550 .st_libvers = SMB_VERSION,
551 .st_mktable = smbios_test_proc_mktable_25,
552 .st_canopen = B_TRUE,
553 .st_verify = smbios_test_proc_verify_25,
554 .st_desc = "SMBIOS 2.5 processor"
555 }, {
556 .st_entry = SMBIOS_ENTRY_POINT_30,
557 .st_tvers = SMB_VERSION_36,
558 .st_libvers = SMB_VERSION,
559 .st_mktable = smbios_test_proc_mktable_36,
560 .st_canopen = B_TRUE,
561 .st_verify = smbios_test_proc_verify_36,
562 .st_desc = "SMBIOS 3.6 processor"
563 }, {
564 .st_entry = SMBIOS_ENTRY_POINT_30,
565 .st_tvers = SMB_VERSION_36,
566 .st_libvers = SMB_VERSION_25,
567 .st_mktable = smbios_test_proc_mktable_36,
568 .st_canopen = B_TRUE,
569 .st_verify = smbios_test_proc_verify_36_25,
570 .st_desc = "SMBIOS 3.6 processor, 2.5 client"
571 }, {
572 .st_entry = SMBIOS_ENTRY_POINT_30,
573 .st_tvers = SMB_VERSION_38,
574 .st_libvers = SMB_VERSION,
575 .st_mktable = smbios_test_proc_mktable_38,
576 .st_canopen = B_TRUE,
577 .st_verify = smbios_test_proc_verify_38,
578 .st_desc = "SMBIOS 3.8 processor"
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_cs,
584 .st_canopen = B_TRUE,
585 .st_verify = smbios_test_extmem_verify_cs,
586 .st_desc = "SMBIOS Sun extended memory device with cs"
587 }, {
588 .st_entry = SMBIOS_ENTRY_POINT_30,
589 .st_tvers = SMB_VERSION,
590 .st_libvers = SMB_VERSION,
591 .st_mktable = smbios_test_extmem_mktable_nocs,
592 .st_canopen = B_TRUE,
593 .st_verify = smbios_test_extmem_verify_nocs,
594 .st_desc = "SMBIOS Sun extended memory device with no cs"
595 }, {
596 .st_entry = SMBIOS_ENTRY_POINT_30,
597 .st_tvers = SMB_VERSION,
598 .st_libvers = SMB_VERSION,
599 .st_mktable = smbios_test_extmem_mktable_invlen_cs,
600 .st_canopen = B_TRUE,
601 .st_verify = smbios_test_extmem_verify_invlen_cs,
602 .st_desc = "SMBIOS Sun extended memory device invalid cs length"
603 },
604 {
605 .st_entry = SMBIOS_ENTRY_POINT_30,
606 .st_tvers = SMB_VERSION,
607 .st_libvers = SMB_VERSION,
608 .st_mktable = smbios_test_addinfo_mktable_noent,
609 .st_canopen = B_TRUE,
610 .st_verify = smbios_test_addinfo_verify_noent,
611 .st_desc = "additional information - no entries"
612 }, {
613 .st_entry = SMBIOS_ENTRY_POINT_30,
614 .st_tvers = SMB_VERSION,
615 .st_libvers = SMB_VERSION,
616 .st_mktable = smbios_test_addinfo_mktable_ents,
617 .st_canopen = B_TRUE,
618 .st_verify = smbios_test_addinfo_verify_ents,
619 .st_desc = "additional information - multiple entries"
620 }, {
621 .st_entry = SMBIOS_ENTRY_POINT_30,
622 .st_tvers = SMB_VERSION,
623 .st_libvers = SMB_VERSION,
624 .st_mktable = smbios_test_addinfo_mktable_invlen_base,
625 .st_canopen = B_TRUE,
626 .st_verify = smbios_test_addinfo_verify_invlen_base,
627 .st_desc = "additional information - invalid length: base"
628 }, {
629 .st_entry = SMBIOS_ENTRY_POINT_30,
630 .st_tvers = SMB_VERSION,
631 .st_libvers = SMB_VERSION,
632 .st_mktable = smbios_test_addinfo_mktable_invlen_ent,
633 .st_canopen = B_TRUE,
634 .st_verify = smbios_test_addinfo_verify_invlen_ent,
635 .st_desc = "additional information - invalid length: base entry"
636 }, {
637 .st_entry = SMBIOS_ENTRY_POINT_30,
638 .st_tvers = SMB_VERSION,
639 .st_libvers = SMB_VERSION,
640 .st_mktable = smbios_test_addinfo_mktable_invlen_multient,
641 .st_canopen = B_TRUE,
642 .st_verify = smbios_test_addinfo_verify_invlen_multient,
643 .st_desc = "additional information - invalid length: multiple "
644 "entries"
645 }, {
646 .st_entry = SMBIOS_ENTRY_POINT_30,
647 .st_tvers = SMB_VERSION,
648 .st_libvers = SMB_VERSION,
649 .st_mktable = smbios_test_addinfo_mktable_invlen_entdata,
650 .st_canopen = B_TRUE,
651 .st_verify = smbios_test_addinfo_verify_invlen_entdata,
652 .st_desc = "additional information - invalid length: entry data"
653 }
654 /* XXX Missing an addinfo ent call with the wrong type to verify */
655 };
656
657 static boolean_t
smbios_test_run_one(const smbios_test_t * test)658 smbios_test_run_one(const smbios_test_t *test)
659 {
660 smbios_test_table_t *table = NULL;
661 smbios_hdl_t *hdl = NULL;
662 void *buf;
663 size_t len;
664 smbios_entry_t *entry;
665 int err = 0;
666 boolean_t ret = B_FALSE;
667
668 table = smbios_test_table_init(test->st_entry, test->st_tvers);
669 if (!test->st_mktable(table)) {
670 goto out;
671 }
672
673 smbios_test_table_snapshot(table, &entry, &buf, &len);
674 hdl = smbios_bufopen(entry, buf, len, test->st_libvers, SMB_FL_DEBUG,
675 &err);
676 if (test->st_canopen) {
677 if (hdl == NULL) {
678 warnx("failed to create table for test %s: %s",
679 test->st_desc, smbios_errmsg(err));
680 goto out;
681 }
682 } else {
683 if (hdl != NULL) {
684 warnx("accidentally created table for test %s, "
685 "expected failure", test->st_desc);
686 } else {
687 ret = B_TRUE;
688 }
689 goto out;
690 }
691
692 if (test->st_verify(hdl)) {
693 ret = B_TRUE;
694 }
695
696 if (hdl != NULL && test_dirfd > -1) {
697 int fd;
698 char fname[PATH_MAX];
699
700 (void) snprintf(fname, sizeof (fname), "%s.smbios",
701 test->st_desc);
702 fd = openat(test_dirfd, fname, O_RDWR | O_CREAT, 0644);
703 if (fd < 0) {
704 warn("failed to dump test %s, failed to open output "
705 "file", test->st_desc);
706 } else {
707 if (smbios_write(hdl, fd) != 0) {
708 warnx("failed to dump test %s: %s",
709 test->st_desc,
710 smbios_errmsg(smbios_errno(hdl)));
711 } else {
712 (void) close(fd);
713 }
714 }
715 }
716 out:
717 if (hdl != NULL) {
718 smbios_close(hdl);
719 }
720
721 if (table != NULL) {
722 smbios_test_table_fini(table);
723 }
724
725 if (ret) {
726 (void) printf("TEST PASSED: %s\n", test->st_desc);
727 } else {
728 (void) printf("TEST FAILED: %s\n", test->st_desc);
729 }
730
731 return (ret);
732 }
733
734 int
main(int argc,char * argv[])735 main(int argc, char *argv[])
736 {
737 int ret = 0, c;
738 size_t i;
739 const char *outdir = NULL;
740
741 while ((c = getopt(argc, argv, ":d:")) != -1) {
742 switch (c) {
743 case 'd':
744 outdir = optarg;
745 break;
746 case '?':
747 errx(EXIT_FAILURE, "unknown option: -%c", optopt);
748 case ':':
749 errx(EXIT_FAILURE, "-%c requires an operand", optopt);
750 }
751 }
752
753 if (outdir != NULL) {
754 if ((test_dirfd = open(outdir, O_RDONLY)) < 0) {
755 err(EXIT_FAILURE, "failed to open %s", outdir);
756 }
757 }
758
759 for (i = 0; i < ARRAY_SIZE(smbios_tests); i++) {
760 if (!smbios_test_run_one(&smbios_tests[i])) {
761 ret = 1;
762 }
763 }
764
765 if (ret == 0) {
766 (void) printf("All tests passed successfully\n");
767 }
768
769 return (ret);
770 }
771