1 1.5 riastrad /* $NetBSD: showvar.c,v 1.5 2025/03/02 01:07:11 riastradh Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Redistribution and use in source and binary forms, with or without 5 1.1 christos * modification, are permitted provided that the following conditions 6 1.1 christos * are met: 7 1.1 christos * 1. Redistributions of source code must retain the above copyright 8 1.1 christos * notice, this list of conditions and the following disclaimer. 9 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright 10 1.1 christos * notice, this list of conditions and the following disclaimer in the 11 1.1 christos * documentation and/or other materials provided with the distribution. 12 1.1 christos * 13 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 14 1.1 christos * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 1.1 christos * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 1.1 christos * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 1.1 christos * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 1.1 christos * SUCH DAMAGE. 24 1.1 christos */ 25 1.1 christos 26 1.1 christos #include <sys/cdefs.h> 27 1.1 christos #ifndef lint 28 1.5 riastrad __RCSID("$NetBSD: showvar.c,v 1.5 2025/03/02 01:07:11 riastradh Exp $"); 29 1.1 christos #endif /* not lint */ 30 1.1 christos 31 1.1 christos #include <sys/efiio.h> 32 1.1 christos #include <sys/ioctl.h> 33 1.1 christos #include <sys/uuid.h> 34 1.1 christos 35 1.1 christos #include <assert.h> 36 1.1 christos #include <ctype.h> 37 1.1 christos #include <err.h> 38 1.1 christos #include <errno.h> 39 1.1 christos #include <fcntl.h> 40 1.1 christos #include <getopt.h> 41 1.1 christos #include <limits.h> 42 1.1 christos #include <regex.h> 43 1.1 christos #include <stdarg.h> 44 1.1 christos #include <stdbool.h> 45 1.1 christos #include <stddef.h> 46 1.1 christos #include <stdio.h> 47 1.1 christos #include <stdlib.h> 48 1.1 christos #include <string.h> 49 1.1 christos #include <unistd.h> 50 1.1 christos #include <util.h> 51 1.1 christos 52 1.1 christos #include "efiio.h" 53 1.1 christos #include "defs.h" 54 1.1 christos #include "bootvar.h" 55 1.1 christos #include "certs.h" 56 1.1 christos #include "devpath.h" 57 1.1 christos #include "getvars.h" 58 1.1 christos #include "showvar.h" 59 1.1 christos #include "utils.h" 60 1.1 christos 61 1.1 christos #define EFI_OS_INDICATIONS_BOOT_TO_FW_UI __BIT(0) 62 1.1 christos #define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION __BIT(1) 63 1.1 christos #define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED __BIT(2) 64 1.1 christos #define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED __BIT(3) 65 1.1 christos #define EFI_OS_INDICATIONS_CAPSULE_RESULT_VAR_SUPPORTED __BIT(4) 66 1.1 christos #define EFI_OS_INDICATIONS_START_OS_RECOVERY __BIT(5) 67 1.1 christos #define EFI_OS_INDICATIONS_START_PLATFORM_RECOVERY __BIT(6) 68 1.1 christos #define EFI_OS_INDICATIONS_JSON_CONFIG_DATA_REFRESH __BIT(7) 69 1.1 christos #define OS_INDICATIONS_BITS \ 70 1.1 christos "\177\020" \ 71 1.1 christos "b\x0""BootFWui\0" \ 72 1.1 christos "b\x1""TimeStamp\0" \ 73 1.1 christos "b\x2""FileCap\0" \ 74 1.1 christos "b\x3""FMPCap\0" \ 75 1.1 christos "b\x4""CapResVar\0" \ 76 1.1 christos "b\x5""StartOsRecovery\0" \ 77 1.1 christos "b\x6""StartPltformRec\0" \ 78 1.1 christos "b\x7""JSONConfig\0" \ 79 1.1 christos 80 1.1 christos //******************************************************** 81 1.1 christos // Boot Option Attributes 82 1.1 christos //******************************************************** 83 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_KEY __BIT(0) // 0x00000001 84 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_APP __BIT(1) // 0x00000002 85 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_SYSPREP __BIT(4) // 0x00000010 86 1.1 christos #define EFI_BOOT_OPTION_SUPPORT_COUNT __BITS(8,9) // 0x00000300 87 1.1 christos // All values 0x00000200-0x00001F00 are reserved 88 1.1 christos #define BOOT_OPTION_SUPPORT_BITS \ 89 1.1 christos "\177\020" \ 90 1.1 christos "b\x0""Key\0" \ 91 1.1 christos "b\x1""App\0" \ 92 1.1 christos "b\x4""SysPrep\0" \ 93 1.1 christos "f\x8\x2""Count\0" 94 1.1 christos 95 1.1 christos /************************************************************************/ 96 1.1 christos 97 1.1 christos static int 98 1.1 christos show_filelist_data(efi_var_t *v, bool dbg) 99 1.1 christos { 100 1.1 christos char *dmsg, *path; 101 1.1 christos 102 1.1 christos path = devpath_parse(v->ev.data, v->ev.datasize, dbg ? &dmsg : NULL); 103 1.1 christos printf("%s: %s\n", v->name, path); 104 1.1 christos free(path); 105 1.1 christos if (dbg) { 106 1.1 christos printf("%s", dmsg); 107 1.1 christos free(dmsg); 108 1.1 christos } 109 1.1 christos return 0; 110 1.1 christos } 111 1.1 christos 112 1.1 christos static int 113 1.2 christos show_asciiz_data(efi_var_t *v, bool dbg __unused) 114 1.1 christos { 115 1.1 christos char *cp, *ep; 116 1.1 christos 117 1.1 christos printf("%s: ", v->name); 118 1.1 christos 119 1.1 christos cp = v->ev.data; 120 1.1 christos ep = cp + v->ev.datasize; 121 1.1 christos for (/*EMPTY*/; cp < ep; cp += strlen(cp) + 1) { 122 1.1 christos printf("%s\n", cp); 123 1.1 christos } 124 1.1 christos if (cp != ep) 125 1.1 christos warnx("short asciiz data\n"); 126 1.1 christos return 0; 127 1.1 christos } 128 1.1 christos 129 1.1 christos static int 130 1.2 christos show_array8_data(efi_var_t *v, bool dbg __unused) 131 1.1 christos { 132 1.1 christos size_t cnt, i; 133 1.1 christos uint8_t *array = v->ev.data; 134 1.1 christos 135 1.1 christos printf("%s: ", v->name); 136 1.1 christos 137 1.1 christos cnt = v->ev.datasize / sizeof(array[0]); 138 1.1 christos i = 0; 139 1.1 christos for (;;) { 140 1.1 christos printf("%02x", array[i]); 141 1.1 christos if (++i == cnt) { 142 1.1 christos printf("\n"); 143 1.1 christos break; 144 1.1 christos } 145 1.1 christos printf(","); 146 1.1 christos } 147 1.1 christos return 0; 148 1.1 christos } 149 1.1 christos 150 1.1 christos static int 151 1.2 christos show_array16_data(efi_var_t *v, bool dbg __unused) 152 1.1 christos { 153 1.1 christos size_t cnt, i; 154 1.1 christos uint16_t *array = v->ev.data; 155 1.1 christos 156 1.1 christos printf("%s: ", v->name); 157 1.1 christos 158 1.1 christos cnt = v->ev.datasize / sizeof(array[0]); 159 1.1 christos i = 0; 160 1.1 christos for (;;) { 161 1.1 christos printf("%04X", array[i]); 162 1.1 christos if (++i == cnt) { 163 1.1 christos printf("\n"); 164 1.1 christos break; 165 1.1 christos } 166 1.1 christos printf(","); 167 1.1 christos } 168 1.1 christos return 0; 169 1.1 christos } 170 1.1 christos 171 1.1 christos static int 172 1.1 christos show_uuid_array_data(efi_var_t *v, bool dbg) 173 1.1 christos { 174 1.1 christos size_t cnt, i; 175 1.1 christos uuid_t *array = v->ev.data; 176 1.1 christos const char *name; 177 1.1 christos 178 1.1 christos printf("%s: ", v->name); 179 1.1 christos 180 1.1 christos cnt = v->ev.datasize / sizeof(array[0]); 181 1.1 christos 182 1.1 christos for (i = 0; i < cnt; i++) { 183 1.1 christos name = get_cert_name(&array[i]); 184 1.1 christos printf("%s%c", name, i + 1 < cnt ? ' ' : '\n'); 185 1.1 christos } 186 1.1 christos 187 1.1 christos if (dbg) { 188 1.1 christos for (i = 0; i < cnt; i++) { 189 1.1 christos printf(" "); 190 1.1 christos uuid_printf(&array[i]); 191 1.1 christos name = get_cert_name(&array[i]); 192 1.1 christos printf(" %s\n", name ? name : "unknown"); 193 1.1 christos } 194 1.1 christos } 195 1.1 christos return 0; 196 1.1 christos } 197 1.1 christos 198 1.1 christos /************************************************************************/ 199 1.1 christos 200 1.1 christos static int 201 1.1 christos show_key_data(efi_var_t *v, bool dbg) 202 1.1 christos { 203 1.1 christos typedef union { 204 1.1 christos struct { 205 1.1 christos uint32_t Revision : 8; 206 1.1 christos uint32_t ShiftPressed : 1; 207 1.1 christos uint32_t ControlPressed : 1; 208 1.1 christos uint32_t AltPressed : 1; 209 1.1 christos uint32_t LogoPressed : 1; 210 1.1 christos uint32_t MenuPressed : 1; 211 1.1 christos uint32_t SysReqPressed : 1; 212 1.1 christos uint32_t Reserved : 16; 213 1.1 christos uint32_t InputKeyCount : 2; 214 1.1 christos #define BOOT_KEY_OPTION_BITS \ 215 1.1 christos "\177\020" \ 216 1.1 christos "f\x00\x08""Rev\0" \ 217 1.1 christos "b\x08""SHFT\0" \ 218 1.1 christos "b\x09""CTRL\0" \ 219 1.1 christos "b\x0a""ALT\0" \ 220 1.1 christos "b\x0b""LOGO\0" \ 221 1.1 christos "b\x0c""MENU\0" \ 222 1.1 christos "b\x0d""SysReq\0" \ 223 1.1 christos /* "f\x0e\x10""Rsvd\0" */ \ 224 1.1 christos "f\x1e\x02""KeyCnt\0" 225 1.1 christos } Options; 226 1.1 christos uint32_t PackedValue; 227 1.1 christos } __packed EFI_BOOT_KEY_DATA; 228 1.1 christos typedef struct { 229 1.1 christos uint16_t ScanCode; 230 1.1 christos uint16_t UnicodeChar; 231 1.1 christos } __packed EFI_INPUT_KEY; 232 1.1 christos typedef struct _EFI_KEY_OPTION { 233 1.1 christos EFI_BOOT_KEY_DATA KeyData; 234 1.1 christos uint32_t BootOptionCrc; 235 1.1 christos uint16_t BootOption; 236 1.1 christos EFI_INPUT_KEY Keys[3]; 237 1.1 christos uint16_t DescLocation; /* XXX: a guess! Not documented */ 238 1.1 christos uint8_t UndocData[]; 239 1.1 christos } __packed EFI_KEY_OPTION; 240 1.1 christos union { 241 1.1 christos EFI_KEY_OPTION *ko; 242 1.1 christos uint8_t *bp; 243 1.1 christos } u = { .bp = v->ev.data, }; 244 1.1 christos char buf[256], c, *cp, *desc; 245 1.5 riastrad uint i; 246 1.1 christos 247 1.1 christos printf("%s:", v->name); 248 1.1 christos 249 1.1 christos /* 250 1.1 christos * Note: DescLocation is not documented in the UEFI spec, so 251 1.1 christos * do some sanity checking before using it. 252 1.1 christos */ 253 1.1 christos desc = NULL; 254 1.1 christos if (offsetof(EFI_KEY_OPTION, UndocData) < v->ev.datasize && 255 1.1 christos u.ko->DescLocation + sizeof(uint16_t) < v->ev.datasize) { 256 1.1 christos size_t sz = v->ev.datasize - u.ko->DescLocation; 257 1.1 christos desc = ucs2_to_utf8((uint16_t *)&u.bp[u.ko->DescLocation], 258 1.1 christos sz, NULL, NULL); 259 1.1 christos printf(" %s", desc); 260 1.1 christos } 261 1.1 christos 262 1.1 christos /* 263 1.1 christos * Parse the KeyData 264 1.1 christos */ 265 1.1 christos snprintb(buf, sizeof(buf), BOOT_KEY_OPTION_BITS, 266 1.1 christos u.ko->KeyData.PackedValue); 267 1.1 christos 268 1.1 christos /* 269 1.1 christos * Skip over the raw value 270 1.1 christos */ 271 1.1 christos c = '\0'; 272 1.1 christos if ((cp = strchr(buf, ',')) || (cp = strchr(buf, '<'))) { 273 1.1 christos c = *cp; 274 1.1 christos *cp = '<'; 275 1.1 christos } 276 1.1 christos else 277 1.1 christos cp = buf; 278 1.1 christos 279 1.1 christos printf("\tBoot%04X \t%s", u.ko->BootOption, cp); 280 1.1 christos 281 1.1 christos if (c != '\0') 282 1.1 christos *cp = c; /* restore the buffer */ 283 1.4 riastrad 284 1.5 riastrad for (i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++) 285 1.1 christos printf(" {%04x, %04x}", u.ko->Keys[i].ScanCode, 286 1.1 christos u.ko->Keys[i].UnicodeChar); 287 1.1 christos printf("\n"); 288 1.1 christos 289 1.1 christos if (dbg) { 290 1.1 christos printf(" KeyData: %s\n", buf); 291 1.1 christos printf(" BootOptionCrc: 0x%08x\n", u.ko->BootOptionCrc); 292 1.1 christos printf(" BootOption: Boot%04X\n", u.ko->BootOption); 293 1.5 riastrad for (i = 0; i < u.ko->KeyData.Options.InputKeyCount; i++) { 294 1.1 christos printf(" Keys[%u].ScanCode: 0x%04x\n", i, 295 1.4 riastrad u.ko->Keys[i].ScanCode); 296 1.1 christos printf(" Keys[%u].UnicodeChar: 0x%04x\n", i, 297 1.4 riastrad u.ko->Keys[i].UnicodeChar); 298 1.1 christos } 299 1.1 christos if (desc) 300 1.1 christos printf(" Desc: %s\n", desc); 301 1.1 christos } 302 1.1 christos free(desc); 303 1.1 christos return 0; 304 1.1 christos } 305 1.1 christos 306 1.1 christos /************************************************************************/ 307 1.1 christos 308 1.1 christos static char * 309 1.1 christos format_optional_data(char *od, size_t sz) 310 1.1 christos { 311 1.1 christos char *bp; 312 1.1 christos size_t i; 313 1.1 christos 314 1.1 christos bp = emalloc(sz + 1); 315 1.1 christos 316 1.1 christos for (i = 0; i < sz; i++) { 317 1.1 christos char c = od[i]; 318 1.2 christos bp[i] = isprint((unsigned char)c) ? c : '.'; 319 1.1 christos } 320 1.1 christos bp[i] = '\0'; 321 1.1 christos return bp; 322 1.1 christos } 323 1.1 christos 324 1.1 christos static int 325 1.3 christos show_boot_data(efi_var_t *v, uint debug, uint max_namelen) 326 1.1 christos { 327 1.1 christos struct { 328 1.1 christos char *name; 329 1.1 christos uint32_t Attributes; 330 1.1 christos char *Description; 331 1.1 christos devpath_t *devpath; 332 1.1 christos char *OptionalData; 333 1.1 christos size_t OptionalDataSize; 334 1.1 christos } info; 335 1.1 christos union { 336 1.1 christos char *cp; 337 1.1 christos boot_var_t *bb; 338 1.1 christos } u = { .cp = v->ev.data, }; 339 1.1 christos char *args, *dmsg, *path; 340 1.1 christos size_t sz; 341 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT; 342 1.1 christos bool verbose = debug & (DEBUG_MASK | DEBUG_VERBOSE_BIT); 343 1.1 christos 344 1.1 christos memset(&info, 0, sizeof(info)); 345 1.1 christos info.name = v->name; 346 1.1 christos info.Attributes = u.bb->Attributes; 347 1.1 christos sz = (v->ev.datasize - sizeof(*u.bb)) / sizeof(uint16_t); 348 1.1 christos sz = (ucs2nlen(u.bb->Description, sz) + 1) * sizeof(uint16_t); 349 1.1 christos info.Description = ucs2_to_utf8(u.bb->Description, sz, NULL, NULL); 350 1.1 christos info.devpath = (devpath_t *)((uint8_t *)u.bb->Description + sz); 351 1.1 christos info.OptionalData = (char *)info.devpath + u.bb->FilePathListLength; 352 1.1 christos 353 1.1 christos char *ep = u.cp + v->ev.datasize; 354 1.1 christos 355 1.1 christos assert(info.OptionalData <= u.cp + v->ev.datasize); 356 1.1 christos 357 1.1 christos if (info.OptionalData <= u.cp + v->ev.datasize) { 358 1.1 christos info.OptionalDataSize = (size_t)(ep - info.OptionalData); 359 1.1 christos } 360 1.1 christos else { 361 1.1 christos printf("ARG!!! " 362 1.1 christos "FilePahList[] extends past end of data by %zd bytes\n", 363 1.1 christos info.OptionalData - ep); 364 1.1 christos info.OptionalDataSize = 0; 365 1.1 christos } 366 1.1 christos printf("%s%c %-*s", v->name, 367 1.1 christos IS_ACTIVE(info.Attributes) ? '*' : ' ', 368 1.1 christos max_namelen, info.Description); 369 1.1 christos 370 1.1 christos dmsg = NULL; 371 1.1 christos if (verbose) { 372 1.1 christos path = devpath_parse(info.devpath, u.bb->FilePathListLength, 373 1.1 christos dbg ? &dmsg : NULL); 374 1.1 christos 375 1.1 christos args = format_optional_data(info.OptionalData, 376 1.1 christos info.OptionalDataSize); 377 1.4 riastrad 378 1.1 christos printf("\t%s%s", path, args);/* XXX: make this conditional on verbose? */ 379 1.1 christos free(args); 380 1.1 christos free(path); 381 1.1 christos } 382 1.1 christos 383 1.1 christos printf("\n"); 384 1.1 christos 385 1.1 christos if (dbg) { 386 1.1 christos char attr_str[256]; 387 1.4 riastrad 388 1.1 christos snprintb(attr_str, sizeof(attr_str), 389 1.1 christos LOAD_OPTION_BITS, info.Attributes); 390 1.1 christos printf(" Attr: %s\n", attr_str); 391 1.1 christos printf(" Description: %s\n", info.Description); 392 1.1 christos assert(dmsg != NULL); 393 1.1 christos printf("%s", dmsg); 394 1.1 christos if (info.OptionalDataSize > 0) { 395 1.1 christos show_data((void *)info.OptionalData, 396 1.1 christos info.OptionalDataSize, " ExtraData: "); 397 1.1 christos } 398 1.1 christos free(dmsg); 399 1.1 christos } 400 1.1 christos 401 1.1 christos free(info.Description); 402 1.1 christos return 0; 403 1.4 riastrad } 404 1.1 christos 405 1.1 christos /************************************************************************/ 406 1.1 christos 407 1.1 christos static int 408 1.2 christos show_OsIndications_data(efi_var_t *e, bool dbg __unused) 409 1.1 christos { 410 1.1 christos uint64_t OsIndications; 411 1.1 christos char buf[256]; 412 1.1 christos 413 1.1 christos assert(e->ev.datasize == 8); 414 1.1 christos OsIndications = *(uint64_t *)e->ev.data; 415 1.1 christos snprintb(buf, sizeof(buf), OS_INDICATIONS_BITS, OsIndications); 416 1.1 christos printf("%s:\t%s\n", e->name, buf); 417 1.1 christos return 0; 418 1.1 christos } 419 1.1 christos 420 1.1 christos static int 421 1.2 christos show_BootOptionSupport_data(efi_var_t *e, bool dbg __unused) 422 1.1 christos { 423 1.1 christos uint32_t boot_option_support; 424 1.1 christos char buf[256]; 425 1.1 christos 426 1.1 christos assert(e->ev.datasize == 4); 427 1.1 christos boot_option_support = *(uint32_t *)e->ev.data; 428 1.1 christos snprintb(buf, sizeof(buf), BOOT_OPTION_SUPPORT_BITS, 429 1.1 christos boot_option_support); 430 1.1 christos printf("%s:\t%s\n", e->name, buf); 431 1.1 christos return 0; 432 1.1 christos } 433 1.1 christos 434 1.1 christos static int 435 1.2 christos show_Timeout_data(efi_var_t *e, bool dbg __unused) 436 1.1 christos { 437 1.1 christos uint16_t *timeout = e->ev.data; 438 1.1 christos 439 1.1 christos if (e->ev.datasize != 2) 440 1.1 christos printf("bad timeout datasize: %zu\n", e->ev.datasize); 441 1.1 christos else 442 1.1 christos printf("Timeout: %u seconds\n", *timeout); 443 1.1 christos return 0; 444 1.1 christos } 445 1.1 christos 446 1.1 christos PUBLIC int 447 1.1 christos show_generic_data(efi_var_t *e, uint var_width) 448 1.1 christos { 449 1.1 christos char uuid_str[UUID_STR_LEN]; 450 1.1 christos char attr_str[256]; 451 1.1 christos 452 1.1 christos uuid_snprintf(uuid_str, sizeof(uuid_str), &e->ev.vendor); 453 1.1 christos snprintb(attr_str, sizeof(attr_str), EFI_VAR_ATTR_BITS, e->ev.attrib); 454 1.1 christos printf("%-*s %s %5zu %s\n", var_width, e->name, uuid_str, 455 1.1 christos e->ev.datasize, attr_str); 456 1.1 christos 457 1.1 christos return 0; 458 1.1 christos } 459 1.1 christos 460 1.1 christos /************************************************************************/ 461 1.1 christos 462 1.1 christos struct vartbl { 463 1.1 christos const char *name; 464 1.1 christos int (*fn)(efi_var_t *, bool); 465 1.1 christos }; 466 1.1 christos 467 1.1 christos static int 468 1.1 christos varcmpsortfn(const void *a, const void *b) 469 1.1 christos { 470 1.1 christos const struct vartbl *p = a; 471 1.1 christos const struct vartbl *q = b; 472 1.1 christos 473 1.1 christos return strcmp(p->name, q->name); 474 1.1 christos } 475 1.1 christos 476 1.1 christos static int 477 1.1 christos varcmpsrchfn(const void *a, const void *b) 478 1.1 christos { 479 1.1 christos const struct vartbl *q = b; 480 1.1 christos 481 1.1 christos return strcmp(a, q->name); 482 1.1 christos } 483 1.1 christos 484 1.1 christos PUBLIC int 485 1.3 christos show_variable(efi_var_t *v, uint debug, uint max_namelen) 486 1.1 christos { 487 1.1 christos #define REGEXP_BOOTXXXX "^((Key)|(Boot)|(lBoot)|(Driver)|(SysPrep)|(OsRecovery))[0-9,A-F]{4}$" 488 1.1 christos static regex_t preg = { .re_magic = 0, }; 489 1.1 christos static struct vartbl *tp, tbl[] = { 490 1.1 christos { "AuditMode", show_array8_data, }, 491 1.1 christos { "BootCurrent", show_array16_data, }, 492 1.1 christos { "BootNext", show_array16_data, }, 493 1.1 christos { "BootOptionSupport", show_BootOptionSupport_data, }, 494 1.1 christos { "BootOrder", show_array16_data, }, 495 1.1 christos { "BootOrderDefault", show_array16_data, }, 496 1.1 christos { "db", show_cert_data, }, 497 1.1 christos { "dbDefault", show_cert_data, }, 498 1.1 christos { "dbr", show_cert_data, }, 499 1.1 christos { "dbrDefault", show_cert_data, }, 500 1.1 christos { "dbt", show_cert_data, }, 501 1.1 christos { "dbtDefault", show_cert_data, }, 502 1.1 christos { "dbx", show_cert_data, }, 503 1.1 christos { "dbxDefault", show_cert_data, }, 504 1.1 christos { "devdbDefault", show_cert_data, }, 505 1.1 christos { "ConIn", show_filelist_data, }, 506 1.1 christos { "ConInDev", show_filelist_data, }, 507 1.1 christos { "ConOut", show_filelist_data, }, 508 1.1 christos { "ConOutDev", show_filelist_data, }, 509 1.1 christos { "DriverOrder", show_array16_data, }, 510 1.1 christos { "ErrOut", show_filelist_data, }, 511 1.1 christos { "ErrOutDev", show_filelist_data, }, 512 1.1 christos { "KEK", show_cert_data, }, 513 1.1 christos { "KEKDefault", show_cert_data, }, 514 1.1 christos { "OsIndications", show_OsIndications_data, }, 515 1.1 christos { "OsIndicationsSupported", show_OsIndications_data, }, 516 1.1 christos { "PK", show_cert_data, }, 517 1.1 christos { "PKDefault", show_cert_data, }, 518 1.1 christos { "PlatformLang", show_asciiz_data, }, 519 1.1 christos { "PlatformLangCodes", show_asciiz_data, }, 520 1.1 christos { "ProtectedBootOptions", show_array16_data, }, 521 1.1 christos { "SecureBoot", show_array8_data, }, 522 1.1 christos { "SetupMode", show_array8_data, }, 523 1.1 christos { "SignatureSupport", show_uuid_array_data, }, 524 1.1 christos { "SysPrepOrder", show_array16_data, }, 525 1.1 christos { "Timeout", show_Timeout_data, }, 526 1.1 christos { "VendorKeys", show_array8_data, }, 527 1.1 christos }; 528 1.1 christos bool dbg = debug & DEBUG_STRUCT_BIT; 529 1.1 christos int rv; 530 1.1 christos 531 1.1 christos if (preg.re_magic == 0) { 532 1.1 christos const char *regexp = REGEXP_BOOTXXXX; 533 1.1 christos if (regcomp(&preg, regexp, REG_EXTENDED) != 0) 534 1.1 christos err(EXIT_FAILURE, "regcomp: %s", regexp); 535 1.1 christos 536 1.1 christos qsort(tbl, __arraycount(tbl), sizeof(*tbl), varcmpsortfn); 537 1.1 christos } 538 1.1 christos 539 1.1 christos if (debug & DEBUG_EFI_IOC_BIT) { 540 1.1 christos rv = show_generic_data(v, max_namelen); 541 1.1 christos if (debug & DEBUG_VERBOSE_BIT) 542 1.1 christos return rv; 543 1.1 christos } 544 1.1 christos 545 1.1 christos if (regexec(&preg, v->name, 0, NULL, 0) == 0) { /* matched */ 546 1.1 christos if (v->name[0] == 'K') 547 1.1 christos rv = show_key_data(v, dbg); 548 1.1 christos else 549 1.1 christos rv = show_boot_data(v, debug, max_namelen); 550 1.1 christos } 551 1.1 christos else { 552 1.1 christos tp = bsearch(v->name, tbl, __arraycount(tbl), sizeof(*tbl), 553 1.1 christos varcmpsrchfn); 554 1.1 christos 555 1.1 christos if (tp != NULL) 556 1.1 christos rv = tp->fn(v, dbg); 557 1.1 christos else if(!(debug & DEBUG_EFI_IOC_BIT)) 558 1.1 christos rv = show_generic_data(v, max_namelen); 559 1.1 christos } 560 1.1 christos if (debug & DEBUG_DATA_BIT) 561 1.1 christos show_data(v->ev.data, v->ev.datasize, " "); 562 1.1 christos 563 1.1 christos return rv; 564 1.1 christos } 565