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 2026 Oxide Computer Company
14 */
15
16 /*
17 * Tests for SMBIOS Baseboard, Type 2.
18 */
19
20 #include "smbios_test.h"
21
22 static const char *bb_mfg = "Symphonia";
23 static const char *bb_prod = "Abyss";
24 static const char *bb_version = "Arise";
25 static const char *bb_serial = "Vesperia";
26 static const char *bb_asset = "Xilia";
27 static const char *bb_location = "Destiny";
28 static const uint16_t bb_chassis = 0x4224;
29 static const uint8_t bb_flags = SMB_BBFL_MOTHERBOARD | SMB_BBFL_HOTSWAP;
30 static const uint8_t bb_type = SMB_BBT_CSWITCH;
31 static const uint16_t bb_ents[] = { 0x42, 0x169, 0x7777, UINT16_MAX };
32
33 boolean_t
smbios_test_bboard_mktable_short(smbios_test_table_t * table)34 smbios_test_bboard_mktable_short(smbios_test_table_t *table)
35 {
36 smb_header_t hdr;
37
38 hdr.smbh_type = SMB_TYPE_BASEBOARD;
39 hdr.smbh_len = sizeof (hdr);
40
41 (void) smbios_test_table_append(table, &hdr, sizeof (hdr));
42 smbios_test_table_append_eot(table);
43 return (B_TRUE);
44 }
45
46 boolean_t
smbios_test_bboard_mktable(smbios_test_table_t * table)47 smbios_test_bboard_mktable(smbios_test_table_t *table)
48 {
49 smb_bboard_t bboard;
50
51 bboard.smbbb_hdr.smbh_type = SMB_TYPE_BASEBOARD;
52 bboard.smbbb_hdr.smbh_len = sizeof (bboard);
53
54 bboard.smbbb_manufacturer = 1;
55 bboard.smbbb_product = 2;
56 bboard.smbbb_version = 3;
57 bboard.smbbb_serial = 4;
58 bboard.smbbb_asset = 5;
59 bboard.smbbb_flags = bb_flags;
60 bboard.smbbb_location = 6;
61 bboard.smbbb_chassis = bb_chassis;
62 bboard.smbbb_type = bb_type;
63 bboard.smbbb_cn = 0;
64
65 (void) smbios_test_table_append(table, &bboard, sizeof (bboard));
66 smbios_test_table_append_string(table, bb_mfg);
67 smbios_test_table_append_string(table, bb_prod);
68 smbios_test_table_append_string(table, bb_version);
69 smbios_test_table_append_string(table, bb_serial);
70 smbios_test_table_append_string(table, bb_asset);
71 smbios_test_table_append_string(table, bb_location);
72 smbios_test_table_str_fini(table);
73 smbios_test_table_append_eot(table);
74 return (B_TRUE);
75 }
76
77 boolean_t
smbios_test_bboard_mktable_ents(smbios_test_table_t * table)78 smbios_test_bboard_mktable_ents(smbios_test_table_t *table)
79 {
80 smb_bboard_t bboard;
81
82 bboard.smbbb_hdr.smbh_type = SMB_TYPE_BASEBOARD;
83 bboard.smbbb_hdr.smbh_len = sizeof (bboard) + sizeof (bb_ents);
84
85 bboard.smbbb_manufacturer = 1;
86 bboard.smbbb_product = 2;
87 bboard.smbbb_version = 3;
88 bboard.smbbb_serial = 4;
89 bboard.smbbb_asset = 5;
90 bboard.smbbb_flags = bb_flags;
91 bboard.smbbb_location = 6;
92 bboard.smbbb_chassis = bb_chassis;
93 bboard.smbbb_type = bb_type;
94 bboard.smbbb_cn = ARRAY_SIZE(bb_ents);
95
96 (void) smbios_test_table_append(table, &bboard, sizeof (bboard));
97 (void) smbios_test_table_append_raw(table, bb_ents, sizeof (bb_ents));
98 smbios_test_table_append_string(table, bb_mfg);
99 smbios_test_table_append_string(table, bb_prod);
100 smbios_test_table_append_string(table, bb_version);
101 smbios_test_table_append_string(table, bb_serial);
102 smbios_test_table_append_string(table, bb_asset);
103 smbios_test_table_append_string(table, bb_location);
104 smbios_test_table_str_fini(table);
105 smbios_test_table_append_eot(table);
106 return (B_TRUE);
107 }
108
109 boolean_t
smbios_test_bboard_mktable_short_ents(smbios_test_table_t * table)110 smbios_test_bboard_mktable_short_ents(smbios_test_table_t *table)
111 {
112 smb_bboard_t bboard;
113
114 bboard.smbbb_hdr.smbh_type = SMB_TYPE_BASEBOARD;
115 bboard.smbbb_hdr.smbh_len = sizeof (bboard) + sizeof (bb_ents) / 2;
116
117 bboard.smbbb_manufacturer = 1;
118 bboard.smbbb_product = 2;
119 bboard.smbbb_version = 3;
120 bboard.smbbb_serial = 4;
121 bboard.smbbb_asset = 5;
122 bboard.smbbb_flags = bb_flags;
123 bboard.smbbb_location = 6;
124 bboard.smbbb_chassis = bb_chassis;
125 bboard.smbbb_type = bb_type;
126 bboard.smbbb_cn = ARRAY_SIZE(bb_ents);
127
128 (void) smbios_test_table_append(table, &bboard, sizeof (bboard));
129 (void) smbios_test_table_append_raw(table, bb_ents, sizeof (bb_ents));
130 smbios_test_table_append_string(table, bb_mfg);
131 smbios_test_table_append_string(table, bb_prod);
132 smbios_test_table_append_string(table, bb_version);
133 smbios_test_table_append_string(table, bb_serial);
134 smbios_test_table_append_string(table, bb_asset);
135 smbios_test_table_append_string(table, bb_location);
136 smbios_test_table_str_fini(table);
137 smbios_test_table_append_eot(table);
138
139 return (B_TRUE);
140 }
141
142 static boolean_t
smbios_test_bboard_verify_base(smbios_hdl_t * hdl,smbios_struct_t * sp,uint_t nents)143 smbios_test_bboard_verify_base(smbios_hdl_t *hdl, smbios_struct_t *sp,
144 uint_t nents)
145 {
146 boolean_t ret = B_TRUE;
147 smbios_bboard_t bboard;
148
149 if (smbios_info_bboard(hdl, sp->smbstr_id, &bboard) != 0) {
150 warnx("failed to get baseboard information: %s",
151 smbios_errmsg(smbios_errno(hdl)));
152 return (B_FALSE);
153 }
154
155 if (bboard.smbb_chassis != bb_chassis) {
156 warnx("found wrong chassis hdl 0x%" _PRIxID ", expected 0x%x",
157 bboard.smbb_chassis, bb_chassis);
158 ret = B_FALSE;
159 }
160
161 if (bboard.smbb_flags != bb_flags) {
162 warnx("found wrong flags value 0x%x, expected 0x%x",
163 bboard.smbb_flags, bb_flags);
164 ret = B_FALSE;
165 }
166
167 if (bboard.smbb_type != bb_type) {
168 warnx("found wrong type value 0x%x, expected 0x%x",
169 bboard.smbb_type, bb_type);
170 ret = B_FALSE;
171 }
172
173 if (bboard.smbb_contn != nents) {
174 warnx("found wrong object count 0x%x, expected 0x%x",
175 bboard.smbb_contn, nents);
176 ret = B_FALSE;
177 }
178
179 return (ret);
180 }
181
182 static boolean_t
smbios_test_bboard_verify_common(smbios_hdl_t * hdl,smbios_struct_t * sp)183 smbios_test_bboard_verify_common(smbios_hdl_t *hdl, smbios_struct_t *sp)
184 {
185 boolean_t ret = B_TRUE;
186 smbios_info_t info;
187
188 if (smbios_info_common(hdl, sp->smbstr_id, &info) != 0) {
189 warnx("failed to get baseboard common information: %s",
190 smbios_errmsg(smbios_errno(hdl)));
191 return (B_FALSE);
192 }
193
194 if (strcmp(info.smbi_manufacturer, bb_mfg) != 0) {
195 warnx("found wrong manufacturer: expected %s, found %s",
196 bb_mfg, info.smbi_manufacturer);
197 ret = B_FALSE;
198 }
199
200 if (strcmp(info.smbi_product, bb_prod) != 0) {
201 warnx("found wrong product: expected %s, found %s",
202 bb_prod, info.smbi_product);
203 ret = B_FALSE;
204 }
205
206 if (strcmp(info.smbi_version, bb_version) != 0) {
207 warnx("found wrong version: expected %s, found %s",
208 bb_version, info.smbi_version);
209 ret = B_FALSE;
210 }
211
212 if (strcmp(info.smbi_serial, bb_serial) != 0) {
213 warnx("found wrong serial: expected %s, found %s",
214 bb_serial, info.smbi_serial);
215 ret = B_FALSE;
216 }
217
218 if (strcmp(info.smbi_asset, bb_asset) != 0) {
219 warnx("found wrong asset: expected %s, found %s",
220 bb_asset, info.smbi_asset);
221 ret = B_FALSE;
222 }
223
224 if (strcmp(info.smbi_location, bb_location) != 0) {
225 warnx("found wrong location: expected %s, found %s",
226 bb_location, info.smbi_location);
227 ret = B_FALSE;
228 }
229
230 if (*info.smbi_part != '\0') {
231 warnx("found unexpected part string: %s", info.smbi_part);
232 ret = B_FALSE;
233 }
234
235 return (ret);
236 }
237
238 boolean_t
smbios_test_bboard_verify_noents(smbios_hdl_t * hdl)239 smbios_test_bboard_verify_noents(smbios_hdl_t *hdl)
240 {
241 smbios_struct_t sp;
242 boolean_t ret = B_TRUE;
243 id_t ids[4];
244 int cret;
245
246 if (smbios_lookup_type(hdl, SMB_TYPE_BASEBOARD, &sp) == -1) {
247 warnx("failed to lookup SMBIOS baseboard: %s",
248 smbios_errmsg(smbios_errno(hdl)));
249 return (B_FALSE);
250 }
251
252 if (!smbios_test_bboard_verify_base(hdl, &sp, 0))
253 ret = B_FALSE;
254
255 if (!smbios_test_bboard_verify_common(hdl, &sp))
256 ret = B_FALSE;
257
258 cret = smbios_info_contains(hdl, sp.smbstr_id, 0, NULL);
259 if (cret != 0) {
260 warnx("got contains count of %d: expected 0 (no ids arg)",
261 cret);
262 ret = B_FALSE;
263 }
264
265 cret = smbios_info_contains(hdl, sp.smbstr_id, ARRAY_SIZE(ids), ids);
266 if (cret != 0) {
267 warnx("returned count of %d: expected 0 (with ids arg)",
268 cret);
269 ret = B_FALSE;
270 }
271
272 return (ret);
273 }
274
275 boolean_t
smbios_test_bboard_verify_ents(smbios_hdl_t * hdl)276 smbios_test_bboard_verify_ents(smbios_hdl_t *hdl)
277 {
278 smbios_struct_t sp;
279 boolean_t ret = B_TRUE;
280 id_t ids[ARRAY_SIZE(bb_ents)], lids[ARRAY_SIZE(bb_ents) * 4];
281 int cret;
282
283 if (smbios_lookup_type(hdl, SMB_TYPE_BASEBOARD, &sp) == -1) {
284 warnx("failed to lookup SMBIOS baseboard: %s",
285 smbios_errmsg(smbios_errno(hdl)));
286 return (B_FALSE);
287 }
288
289 if (!smbios_test_bboard_verify_base(hdl, &sp, ARRAY_SIZE(bb_ents)))
290 ret = B_FALSE;
291
292 if (!smbios_test_bboard_verify_common(hdl, &sp))
293 ret = B_FALSE;
294
295 (void) memset(ids, 0x23, sizeof (ids));
296 (void) memset(lids, 0x23, sizeof (lids));
297 cret = smbios_info_contains(hdl, sp.smbstr_id, 0, NULL);
298 if (cret != ARRAY_SIZE(bb_ents)) {
299 warnx("got contains count of %d: expected %zu (no ids arg)",
300 cret, ARRAY_SIZE(bb_ents));
301 ret = B_FALSE;
302 }
303
304 cret = smbios_info_contains(hdl, sp.smbstr_id, ARRAY_SIZE(ids), ids);
305 if (cret != ARRAY_SIZE(bb_ents)) {
306 warnx("returned count of %d: expected %zu (with ids arg)",
307 cret, ARRAY_SIZE(bb_ents));
308 ret = B_FALSE;
309 }
310
311 cret = smbios_info_contains(hdl, sp.smbstr_id, ARRAY_SIZE(lids), lids);
312 if (cret != ARRAY_SIZE(bb_ents)) {
313 warnx("returned count of %d: expected %zu (with lids arg)",
314 cret, ARRAY_SIZE(bb_ents));
315 ret = B_FALSE;
316 }
317
318 for (size_t i = 0; i < ARRAY_SIZE(bb_ents); i++) {
319 if (ids[i] != bb_ents[i]) {
320 warnx("ids[%zu] has wrong value 0x%" _PRIxID
321 ", expected 0x%x", i, ids[i], bb_ents[i]);
322 ret = B_FALSE;
323 }
324
325 if (lids[i] != bb_ents[i]) {
326 warnx("lids[%zu] has wrong value 0x%" _PRIxID
327 ", expected 0x%x", i, lids[i], bb_ents[i]);
328 ret = B_FALSE;
329 }
330 }
331
332 for (size_t i = ARRAY_SIZE(bb_ents); i < ARRAY_SIZE(lids); i++) {
333 if (lids[i] != 0x23232323) {
334 warnx("smbios_info_contains() clobbered entry %zu with "
335 "0x%" _PRIxID, i, lids[i]);
336 ret = B_FALSE;
337 }
338 }
339
340 return (ret);
341 }
342
343 boolean_t
smbios_test_bboard_verify_short(smbios_hdl_t * hdl)344 smbios_test_bboard_verify_short(smbios_hdl_t *hdl)
345 {
346 smbios_bboard_t bboard;
347 smbios_struct_t sp;
348 boolean_t ret = B_TRUE;
349
350 if (smbios_lookup_type(hdl, SMB_TYPE_BASEBOARD, &sp) == -1) {
351 warnx("failed to lookup SMBIOS baseboard: %s",
352 smbios_errmsg(smbios_errno(hdl)));
353 return (B_FALSE);
354 }
355
356 if (smbios_info_bboard(hdl, sp.smbstr_id, &bboard) != -1) {
357 warnx("accidentally parsed invalid baseboard data as valid");
358 ret = B_FALSE;
359 } else if (smbios_errno(hdl) != ESMB_SHORT) {
360 warnx("encountered wrong error for baseboard, expected: "
361 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
362 ret = B_FALSE;
363 }
364
365 if (smbios_info_contains(hdl, sp.smbstr_id, 0, NULL) != -1) {
366 warnx("smbios_info_contains() passed despite corrupt table");
367 ret = B_FALSE;
368 } else if (smbios_errno(hdl) != ESMB_SHORT) {
369 warnx("encountered wrong error for short contains, expected: "
370 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
371 ret = B_FALSE;
372 }
373
374 return (ret);
375 }
376
377 boolean_t
smbios_test_bboard_verify_short_ents(smbios_hdl_t * hdl)378 smbios_test_bboard_verify_short_ents(smbios_hdl_t *hdl)
379 {
380 smbios_struct_t sp;
381 boolean_t ret = B_TRUE;
382
383 if (smbios_lookup_type(hdl, SMB_TYPE_BASEBOARD, &sp) == -1) {
384 warnx("failed to lookup SMBIOS baseboard: %s",
385 smbios_errmsg(smbios_errno(hdl)));
386 return (B_FALSE);
387 }
388
389 /*
390 * We should be able to parse the base structure as we have enough data
391 * here. We skip trying to parse the common data as it technically fits
392 * in here, but the string pointers will be in the wrong spots; however,
393 * there's not a lot that we can do right now in the library about that.
394 */
395 if (!smbios_test_bboard_verify_base(hdl, &sp, ARRAY_SIZE(bb_ents)))
396 ret = B_FALSE;
397
398 if (smbios_info_contains(hdl, sp.smbstr_id, 0, NULL) != -1) {
399 warnx("smbios_info_contains() passed despite corrupt table");
400 ret = B_FALSE;
401 } else if (smbios_errno(hdl) != ESMB_SHORT) {
402 warnx("encountered wrong error for short contains, expected: "
403 "0x%x, found: 0x%x", ESMB_SHORT, smbios_errno(hdl));
404 ret = B_FALSE;
405 }
406
407 return (ret);
408 }
409