25#ifndef LAZYBIOS_INTERNAL_H
26#define LAZYBIOS_INTERNAL_H
38#if defined(__MINGW32__)
39__attribute__((
format(gnu_printf, 2, 3)))
40#elif defined(__GNUC__)
41__attribute__((
format(printf, 2, 3)))
46 fprintf(stderr,
"%s", prefix);
47 vfprintf(stderr,
fmt, args);
48 fprintf(stderr,
"\n");
54# define lb_log(...) ((void)0)
55# define lb_dbg(...) ((void)0)
57#elif defined(LAZYBIOS_DEBUG)
58# define lb_log(...) lazybios_log_internal("[lazybios] ", __VA_ARGS__)
59# define lb_dbg(...) lazybios_log_internal("[lazybios-dbg] ", __VA_ARGS__)
62# define lb_log(...) lazybios_log_internal("[lazybios] ", __VA_ARGS__)
63# define lb_dbg(...) ((void)0)
80#if defined(__MINGW32__)
81__attribute__((
format(gnu_printf, 4, 5)))
82#elif defined(__GNUC__)
83__attribute__((
format(printf, 4, 5)))
86 if (!buf || buf_len == 0 || *len + 1 >= buf_len)
return;
88 size_t remaining = buf_len - *len;
97 if (!strchr(
fmt,
'%')) {
98 size_t n = strlen(
fmt);
99 if (n >= remaining) n = remaining - 1;
100 memcpy(buf + *len,
fmt, n);
101 buf[*len + n] =
'\0';
108 int written = vsnprintf(buf + *len, remaining,
fmt, args);
111 if (written < 0)
return;
112 *len += ((size_t)written >= remaining) ? remaining - 1 : (size_t)written;
122#define LAZYBIOS_DECODER_BUF_SIZE 1024
134 if (!src)
return NULL;
135 size_t n = strlen(src) + 1;
136 char* out = malloc(n);
137 if (out) memcpy(out, src, n);
142#define SMBIOS_HEADER_SIZE 4
145#define LINUX_SYSFS_SMBIOS_ENTRY "/sys/firmware/dmi/tables/smbios_entry_point"
148#define LINUX_SYSFS_DMI_TABLE "/sys/firmware/dmi/tables/DMI"
151#define DEV_MEM "/dev/mem"
153#define SMBIOS_TYPE_BIOS 0
154#define SMBIOS_TYPE_SYSTEM 1
155#define SMBIOS_TYPE_BASEBOARD 2
156#define SMBIOS_TYPE_CHASSIS 3
157#define SMBIOS_TYPE_PROCESSOR 4
158#define SMBIOS_TYPE_MEMORY_CONTROLLER 5
159#define SMBIOS_TYPE_MEMORY_MODULE 6
160#define SMBIOS_TYPE_CACHES 7
161#define SMBIOS_TYPE_PORT_CONNECTOR 8
162#define SMBIOS_TYPE_SYSTEM_SLOTS 9
163#define SMBIOS_TYPE_ONBOARD_DEVICES 10
164#define SMBIOS_TYPE_OEM_STRINGS 11
165#define SMBIOS_TYPE_SYSTEM_CONFIGURATION_OPTIONS 12
166#define SMBIOS_TYPE_FIRMWARE_LANGUAGE_INFORMATION 13
167#define SMBIOS_TYPE_GROUP_ASSOCIATIONS 14
168#define SMBIOS_TYPE_SYSTEM_EVENT_LOG 15
169#define SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY 16
170#define SMBIOS_TYPE_MEMORY_DEVICE 17
171#define SMBIOS_TYPE_32BIT_MEMORY_ERROR_INFORMATION 18
172#define SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS 19
173#define SMBIOS_TYPE_MEMORY_DEVICE_MAPPED_ADDRESS 20
174#define SMBIOS_TYPE_BUILT_IN_POINTING_DEVICE 21
175#define SMBIOS_TYPE_PORTABLE_BATTERY 22
176#define SMBIOS_TYPE_SYSTEM_RESET 23
177#define SMBIOS_TYPE_HARDWARE_SECURITY 24
178#define SMBIOS_TYPE_SYSTEM_POWER_CONTROLS 25
179#define SMBIOS_TYPE_VOLTAGE_PROBE 26
180#define SMBIOS_TYPE_COOLING_DEVICE 27
181#define SMBIOS_TYPE_TEMPERATURE_PROBE 28
182#define SMBIOS_TYPE_ELECTRICAL_CURRENT_PROBE 29
183#define SMBIOS_TYPE_OUT_OF_BAND_REMOTE_ACCESS 30
184#define SMBIOS_TYPE_BOOT_INTEGRITY_SERVICES_ENTRY_POINT 31
185#define SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION 32
186#define SMBIOS_TYPE_64BIT_MEMORY_ERROR_INFORMATION 33
187#define SMBIOS_TYPE_MANAGEMENT_DEVICE 34
188#define SMBIOS_TYPE_MANAGEMENT_DEVICE_COMPONENT 35
189#define SMBIOS_TYPE_MANAGEMENT_DEVICE_THRESHOLD_DATA 36
190#define SMBIOS_TYPE_MEMORY_CHANNEL 37
191#define SMBIOS_TYPE_IPMI_DEVICE_INFORMATION 38
192#define SMBIOS_TYPE_SYSTEM_POWER_SUPPLY 39
193#define SMBIOS_TYPE_ADDITIONAL_INFORMATION 40
194#define SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION 41
195#define SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE 42
196#define SMBIOS_TYPE_TPM_DEVICE 43
197#define SMBIOS_TYPE_PROCESSOR_ADDITIONAL_INFORMATION 44
198#define SMBIOS_TYPE_FIRMWARE_INVENTORY_INFORMATION 45
199#define SMBIOS_TYPE_STRING_PROPERTY 46
200#define SMBIOS_TYPE_END 127
203#define SMBIOS_OEM_HP_TYPE204 204
207#define SMBIOS_OEM_DELL_TYPE177 177
208#define SMBIOS_OEM_DELL_TYPE212 212
209#define SMBIOS_OEM_DELL_TYPE218 218
212#define SMBIOS3_ANCHOR "_SM3_"
213#define SMBIOS3_ANCHOR_OFFSET 0x00
214#define SMBIOS3_CHECKSUM_OFFSET 0x05
215#define SMBIOS3_LENGTH_OFFSET 0x06
216#define SMBIOS3_MAJOR_OFFSET 0x07
217#define SMBIOS3_MINOR_OFFSET 0x08
218#define SMBIOS3_DOCREV_OFFSET 0x09
219#define SMBIOS3_REVISION_OFFSET 0x0A
220#define SMBIOS3_RESERVED_OFFSET 0x0B
221#define SMBIOS3_TABLE_MAX_SIZE_OFFSET 0x0C
222#define SMBIOS3_TABLE_ADDRESS_OFFSET 0x10
223#define SMBIOS3_ENTRY_POINT_LENGTH 0x18
224#define SMBIOS3_ANCHOR_SIZE 5
226#define SMBIOS2_ANCHOR "_SM_"
227#define SMBIOS2_INTERMEDIATE_ANCHOR "_DMI_"
228#define SMBIOS2_ANCHOR_OFFSET 0x00
229#define SMBIOS2_CHECKSUM_OFFSET 0x04
230#define SMBIOS2_LENGTH_OFFSET 0x05
231#define SMBIOS2_MAJOR_OFFSET 0x06
232#define SMBIOS2_MINOR_OFFSET 0x07
233#define SMBIOS2_MAX_STRUCTURE_SIZE_OFFSET 0x08
234#define SMBIOS2_REVISION_OFFSET 0x0A
235#define SMBIOS2_FORMATTED_AREA_OFFSET 0x0B
236#define SMBIOS2_INTERMEDIATE_ANCHOR_OFFSET 0x10
237#define SMBIOS2_INTERMEDIATE_CHECKSUM_OFFSET 0x15
238#define SMBIOS2_TABLE_LENGTH_OFFSET 0x16
239#define SMBIOS2_TABLE_ADDRESS_OFFSET 0x18
240#define SMBIOS2_STRUCTURE_COUNT_OFFSET 0x1C
241#define SMBIOS2_BCD_REVISION_OFFSET 0x1E
242#define SMBIOS2_ENTRY_POINT_LENGTH 0x1F
243#define SMBIOS2_ENTRY_POINT_LENGTH_V21 0x1E
244#define SMBIOS2_ANCHOR_SIZE 4
245#define SMBIOS2_INTERMEDIATE_ANCHOR_SIZE 5
246#define SMBIOS2_FORMATTED_AREA_SIZE 5
249#define LAZYBIOS_MARK_PRESENT(record, field) do { \
250 (record)->field_status.field = (lazybiosFieldStatus_t)LAZYBIOS_FIELD_PRESENT; \
254#define LAZYBIOS_MARK_ABSENT(record, field) do { \
255 (record)->field_status.field = (lazybiosFieldStatus_t)LAZYBIOS_FIELD_ABSENT; \
259#define LAZYBIOS_MARK_UNREACHABLE(record, field) do { \
260 (record)->field_status.field = (lazybiosFieldStatus_t)LAZYBIOS_FIELD_UNREACHABLE; \
264#define LAZYBIOS_CLAMP_STRUCTURE_LENGTH(len, p, end) do { \
265 if ((size_t)((end) - (p)) < (size_t)(len)) { \
266 (len) = (uint8_t)((end) - (p)); \
286int lazybiosLoadRawBuffers(lazybiosCTX_t* ctx,
const uint8_t* entry_data,
size_t entry_len,
const uint8_t* dmi_data,
size_t dmi_len);
294int lazybiosGetSingleFileLayout(
const uint8_t* entry_data,
size_t available,
size_t file_len,
size_t* entry_len,
size_t* table_offset,
size_t* table_len);
313const uint8_t*
DMINext(
const uint8_t* p,
const uint8_t* end);
350#define READSTR(record, field, len, offset, p, end) do { \
351 if ((len) > (offset)) { \
352 (record)->field = DMIString((p), (len), (p)[(offset)], (end)); \
353 if ((record)->field != NULL) { \
354 LAZYBIOS_MARK_PRESENT((record), field); \
356 LAZYBIOS_MARK_ABSENT((record), field); \
359 (record)->field = NULL; \
360 LAZYBIOS_MARK_ABSENT((record), field); \
364#define READU8(record, field, len, offset, p) do { \
365 if ((len) > (offset)) { \
366 (record)->field = (p)[(offset)]; \
367 LAZYBIOS_MARK_PRESENT((record), field); \
369 (record)->field = 0; \
370 LAZYBIOS_MARK_ABSENT((record), field); \
374#define READU16(record, field, len, offset, p) do { \
375 if ((size_t)(len) >= (size_t)(offset) + sizeof(uint16_t)) { \
376 memcpy(&(record)->field, (p) + (offset), sizeof(uint16_t)); \
377 LAZYBIOS_MARK_PRESENT((record), field); \
379 (record)->field = 0; \
380 LAZYBIOS_MARK_ABSENT((record), field); \
384#define READU32(record, field, len, offset, p) do { \
385 if ((size_t)(len) >= (size_t)(offset) + sizeof(uint32_t)) { \
386 memcpy(&(record)->field, (p) + (offset), sizeof(uint32_t)); \
387 LAZYBIOS_MARK_PRESENT((record), field); \
389 (record)->field = 0; \
390 LAZYBIOS_MARK_ABSENT((record), field); \
394#define READU64(record, field, len, offset, p) do { \
395 if ((size_t)(len) >= (size_t)(offset) + sizeof(uint64_t)) { \
396 memcpy(&(record)->field, (p) + (offset), sizeof(uint64_t)); \
397 LAZYBIOS_MARK_PRESENT((record), field); \
399 (record)->field = 0; \
400 LAZYBIOS_MARK_ABSENT((record), field); \
406int lazybiosLinux(lazybiosCTX_t* ctx);
409#if defined(OS_WINDOWS)
411int lazybiosWindows(lazybiosCTX_t* ctx);
416int lazybiosMacOS(lazybiosCTX_t* ctx);
419#if defined(OS_OPENBSD)
421int lazybiosOpenBSD(lazybiosCTX_t* ctx);
424#if defined(OS_FREEBSD)
426int lazybiosFreeBSD(lazybiosCTX_t* ctx);
429#if defined(OS_NETBSD)
431int lazybiosNetBSD(lazybiosCTX_t* ctx);
436int lazybiosSunOS(lazybiosCTX_t* ctx);
439#if defined(OS_DRAGONFLY)
441int lazybiosDragonFly(lazybiosCTX_t* ctx);
446int lazybiosHaiku(lazybiosCTX_t* ctx);
451int lazybiosBeOS(lazybiosCTX_t* ctx);
454#if defined(OS_REACTOS)
456int lazybiosReactOS(lazybiosCTX_t* ctx);
461int lazybiosQNX(lazybiosCTX_t* ctx);
466int lazybiosMINIX(lazybiosCTX_t* ctx);
469#if defined(OS_GENERIC)
471int lazybiosGeneric(lazybiosCTX_t* ctx);
474#if defined(OS_HAIKU) || defined(OS_BEOS) || defined(OS_GENERIC) || \
475 defined(OS_QNX) || defined(OS_MINIX)
477int lazybiosLoadLegacyPhysicalMemory(lazybiosCTX_t* ctx,
478 const char*
const* device_paths,
size_t device_count,
479 const char* platform_name);
char const int const cJSON_bool format
lazybiosSMBIOSVersionTag
Identifies the SMBIOS entry point layout stored in a DMI container.
Public API for lazybios. Include this and nothing else.
#define LAZYBIOS_WARN_UNUSED
Expands to nothing on compilers without a return-value check.
int lazybiosGetSMBIOSTableLocation(const uint8_t *entry_data, size_t available, size_t *entry_len, uint64_t *table_address, size_t *table_len)
Extracts an SMBIOS table address and length from an entry point.
static char * lazybiosDup(const char *src)
Duplicates a NUL-terminated string with malloc.
const uint8_t * DMINext(const uint8_t *p, const uint8_t *end)
Locates the next SMBIOS structure in a DMI table.
int lazybiosParseEntry(lazybiosCTX_t *ctx, const uint8_t *entry_buf, size_t buf_len)
Validates and identifies an SMBIOS entry point.
int lazybiosLoadRawBuffers(lazybiosCTX_t *ctx, const uint8_t *entry_data, size_t entry_len, const uint8_t *dmi_data, size_t dmi_len)
Copies validated raw entry-point and DMI-table buffers into a context.
const char * DMIString(const uint8_t *p, uint8_t length, uint8_t index, const uint8_t *end)
Copies a string from an SMBIOS structure's string-set.
static void lazybios_log_internal(const char *prefix, const char *fmt,...)
static void lazybiosDecoderAppend(char *buf, size_t buf_len, size_t *len, const char *fmt,...)
Appends formatted text to a decoder output buffer.
int lazybiosFindSMBIOSEntryPoint(const uint8_t *image, size_t image_len, size_t *entry_offset, size_t *entry_len)
Finds a valid SMBIOS entry point within a memory image.
LAZYBIOS_WARN_UNUSED int lazybiosSingleFile(lazybiosCTX_t *ctx, const char *bin_path)
Loads SMBIOS entry point and DMI data from one merged file.
int lazybiosInspectEntryPoint(const uint8_t *entry_data, size_t available, lazybiosEntryInspection *inspection)
Inspects and validates an SMBIOS 2.x or 3.x entry point.
LAZYBIOS_WARN_UNUSED int lazybiosFile(lazybiosCTX_t *ctx, const char *entry_path, const char *dmi_path)
Loads an SMBIOS entry point and DMI table from separate files.
int lazybiosGetSingleFileLayout(const uint8_t *entry_data, size_t available, size_t file_len, size_t *entry_len, size_t *table_offset, size_t *table_len)
Determines the entry-point and table layout in a combined dump file.
size_t lazybiosCountStructsByType(const lazybiosDMI_t *DMIData, uint8_t target_type)
Counts SMBIOS structures having a specified type identifier.
int lazybiosLoadWindowsRawSMBIOSData(lazybiosCTX_t *ctx, const uint8_t *raw_data, size_t raw_len)
Loads the Windows raw SMBIOS table format into a context.
Owns raw DMI table data and its parsed SMBIOS entry point.
int intermediate_checksum_valid
lazybiosSMBIOSVersionTag tag