From cea45a08550781c0041e09fdd168f3ff63d52da5 Mon Sep 17 00:00:00 2001 From: salar Date: Tue, 7 Jul 2020 17:48:50 +0430 Subject: [PATCH] make libdmi and implement C API --- Makefile | 50 +++++++++++++++++----- dmioem.c | 2 +- dmiopt.c | 2 +- dmioutput.c | 94 +++++++++++++++++++++++++++++------------ dmioutput.h | 5 ++- dmidecode.c => libdmi.c | 23 +++++++--- dmidecode.h => libdmi.h | 1 + main.c | 72 +++++++++++++++++++++++++++++++ types.h | 92 ++++++++++++++++++++++++++++++++++++++++ 9 files changed, 295 insertions(+), 46 deletions(-) rename dmidecode.c => libdmi.c (99%) rename dmidecode.h => libdmi.h (96%) create mode 100644 main.c diff --git a/Makefile b/Makefile index 7aa729d8..0e5f36e9 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ CFLAGS += -W -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual \ -Wcast-align -Wwrite-strings -Wmissing-prototypes -Winline -Wundef # Let lseek and mmap support 64-bit wide offsets -CFLAGS += -D_FILE_OFFSET_BITS=64 +CFLAGS += -D_FILE_OFFSET_BITS=64 -fPIC #CFLAGS += -DBIGENDIAN #CFLAGS += -DALIGNMENT_WORKAROUND @@ -31,11 +31,12 @@ CFLAGS += -D_FILE_OFFSET_BITS=64 LDFLAGS ?= DESTDIR = -prefix = /usr/local +prefix = /usr sbindir = $(prefix)/sbin mandir = $(prefix)/share/man man8dir = $(mandir)/man8 docdir = $(prefix)/share/doc/dmidecode +libdmidir = /libdmi INSTALL := install INSTALL_DATA := $(INSTALL) -m 644 @@ -47,6 +48,9 @@ RM := rm -f MACHINE ?= $(shell uname -m 2>/dev/null) # These programs are only useful on x86 +LIB-FILES := libdmi.so libdmi.a +OBJS := libdmi.o dmiopt.o dmioem.o dmioutput.o util.o +LIB-HEADERS := libdmi.h types.h PROGRAMS-i386 := biosdecode ownership vpddecode PROGRAMS-i486 := $(PROGRAMS-i386) PROGRAMS-i586 := $(PROGRAMS-i386) @@ -56,14 +60,14 @@ PROGRAMS-amd64 := $(PROGRAMS-x86_64) PROGRAMS := dmidecode $(PROGRAMS-$(MACHINE)) -all : $(PROGRAMS) +all : $(PROGRAMS) libdmi.so libdmi.a # # Programs # -dmidecode : dmidecode.o dmiopt.o dmioem.o dmioutput.o util.o - $(CC) $(LDFLAGS) dmidecode.o dmiopt.o dmioem.o dmioutput.o util.o -o $@ +dmidecode : dmidecode.o libdmi.o dmiopt.o dmioem.o util.o dmioutput.o + $(CC) $(LDFLAGS) dmidecode.o libdmi.o dmiopt.o dmioem.o util.o dmioutput.o -o $@ biosdecode : biosdecode.o util.o $(CC) $(LDFLAGS) biosdecode.o util.o -o $@ @@ -78,14 +82,18 @@ vpddecode : vpddecode.o vpdopt.o util.o # Objects # -dmidecode.o : dmidecode.c version.h types.h util.h config.h dmidecode.h \ +libdmi.o : libdmi.c version.h types.h util.h config.h libdmi.h \ dmiopt.h dmioem.h dmioutput.h $(CC) $(CFLAGS) -c $< -o $@ -dmiopt.o : dmiopt.c config.h types.h util.h dmidecode.h dmiopt.h +dmidecode.o : main.c libdmi.c version.h types.h util.h config.h libdmi.h \ + dmiopt.h dmioem.h $(CC) $(CFLAGS) -c $< -o $@ -dmioem.o : dmioem.c types.h dmidecode.h dmioem.h dmioutput.h +dmiopt.o : dmiopt.c config.h types.h util.h dmiopt.h + $(CC) $(CFLAGS) -c $< -o $@ + +dmioem.o : dmioem.c types.h dmioem.h $(CC) $(CFLAGS) -c $< -o $@ dmioutput.o : dmioutput.c types.h dmioutput.h @@ -106,6 +114,12 @@ vpdopt.o : vpdopt.c config.h util.h vpdopt.h util.o : util.c types.h util.h config.h $(CC) $(CFLAGS) -c $< -o $@ +libdmi.so : $(OBJS) + $(CC) $(CFLAGS) -shared $^ -o $@ + +libdmi.a : $(OBJS) + ar rcs $@ $^ + # # Commands # @@ -113,9 +127,9 @@ util.o : util.c types.h util.h config.h strip : $(PROGRAMS) strip $(PROGRAMS) -install : install-bin install-man install-doc +install : install-bin install-man install-doc install-lib -uninstall : uninstall-bin uninstall-man uninstall-doc +uninstall : uninstall-bin uninstall-man uninstall-doc uninstall-lib install-bin : $(PROGRAMS) $(INSTALL_DIR) $(DESTDIR)$(sbindir) @@ -126,6 +140,20 @@ uninstall-bin : for program in $(PROGRAMS) ; do \ $(RM) $(DESTDIR)$(sbindir)/$$program ; done +install-lib: + $(INSTALL_DIR) $(DESTDIR)$(prefix)/lib$(libdmidir) + $(INSTALL_DIR) $(DESTDIR)$(prefix)/include$(libdmidir) + for program in $(LIB-FILES) ; do \ + $(INSTALL_PROGRAM) $$program $(DESTDIR)$(prefix)/lib$(libdmidir)/ ; done + for program in $(LIB-HEADERS) ; do \ + $(INSTALL_PROGRAM) $$program $(DESTDIR)$(prefix)/include$(libdmidir)/ ; done + +uninstall-lib: + for program in $(LIB-FILES) ; do \ + $(RM) $(DESTDIR)$(prefix)/lib$(libdmidir)/$$program ; done + for program in $(LIB-HEADERS) ; do \ + $(RM) $(DESTDIR)$(prefix)/include$(libdmidir)/$$program ; done + install-man : $(INSTALL_DIR) $(DESTDIR)$(man8dir) for program in $(PROGRAMS) ; do \ @@ -145,4 +173,4 @@ uninstall-doc : $(RM) -r $(DESTDIR)$(docdir) clean : - $(RM) *.o $(PROGRAMS) core + $(RM) *.a *.so *.o $(PROGRAMS) core diff --git a/dmioem.c b/dmioem.c index 60b66741..022ea426 100644 --- a/dmioem.c +++ b/dmioem.c @@ -23,7 +23,7 @@ #include #include "types.h" -#include "dmidecode.h" +#include "libdmi.h" #include "dmioem.h" #include "dmioutput.h" diff --git a/dmiopt.c b/dmiopt.c index 1c3b7607..51a9cac9 100644 --- a/dmiopt.c +++ b/dmiopt.c @@ -28,7 +28,7 @@ #include "config.h" #include "types.h" #include "util.h" -#include "dmidecode.h" +#include "libdmi.h" #include "dmiopt.h" diff --git a/dmioutput.c b/dmioutput.c index 42f8d321..2a46c3ec 100644 --- a/dmioutput.c +++ b/dmioutput.c @@ -21,97 +21,130 @@ #include #include +#include +#include #include "dmioutput.h" +const size_t output_size = 4096 * sizeof(char); +const size_t outout_threshold = 4096; +size_t next_realloc_ratio = 1; +char* output; + +void pr_init() +{ + output = malloc(output_size); + output[0] = '\0'; +} +void pr_free() +{ + free(output); +} + +void output_realloc() +{ + if ( (next_realloc_ratio * output_size) - strlen(output) < outout_threshold) + { + next_realloc_ratio++; + output = realloc(output, next_realloc_ratio * output_size); + } +} + void pr_comment(const char *format, ...) { + output_realloc(); va_list args; - printf("# "); + sprintf(output + strlen(output), "# "); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_info(const char *format, ...) { + output_realloc(); va_list args; va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_handle(const struct dmi_header *h) { - printf("Handle 0x%04X, DMI type %d, %d bytes\n", - h->handle, h->type, h->length); + output_realloc(); + sprintf(output + strlen(output), "Handle 0x%04X, DMI type %d, %d bytes\n", + h->handle, h->type, h->length); } void pr_handle_name(const char *format, ...) { + output_realloc(); va_list args; va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_attr(const char *name, const char *format, ...) { + output_realloc(); va_list args; - printf("\t%s: ", name); + sprintf(output + strlen(output), "\t%s: ", name); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_subattr(const char *name, const char *format, ...) { + output_realloc(); va_list args; - printf("\t\t%s: ", name); + sprintf(output + strlen(output), "\t\t%s: ", name); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_list_start(const char *name, const char *format, ...) { + output_realloc(); va_list args; - printf("\t%s:", name); + sprintf(output + strlen(output), "\t%s:", name); /* format is optional, skip value if not provided */ if (format) { - printf(" "); + sprintf(output + strlen(output), " "); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); } - printf("\n"); - + sprintf(output + strlen(output), "\n"); } void pr_list_item(const char *format, ...) { + output_realloc(); va_list args; - printf("\t\t"); + sprintf(output + strlen(output), "\t\t"); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); } void pr_list_end(void) @@ -121,17 +154,24 @@ void pr_list_end(void) void pr_sep(void) { - printf("\n"); + output_realloc(); + sprintf(output + strlen(output), "\n"); } void pr_struct_err(const char *format, ...) { + output_realloc(); va_list args; - printf("\t"); + sprintf(output + strlen(output), "\t"); va_start(args, format); - vprintf(format, args); + vsprintf(output + strlen(output), format, args); va_end(args); - printf("\n"); + sprintf(output + strlen(output), "\n"); +} + +char* get_output() +{ + return output; } diff --git a/dmioutput.h b/dmioutput.h index a492ec0e..807b9e14 100644 --- a/dmioutput.h +++ b/dmioutput.h @@ -19,8 +19,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "dmidecode.h" +#include "libdmi.h" +void pr_init(); +void pr_free(); void pr_comment(const char *format, ...); void pr_info(const char *format, ...); void pr_handle(const struct dmi_header *h); @@ -32,3 +34,4 @@ void pr_list_item(const char *format, ...); void pr_list_end(void); void pr_sep(void); void pr_struct_err(const char *format, ...); +char* get_output(); diff --git a/dmidecode.c b/libdmi.c similarity index 99% rename from dmidecode.c rename to libdmi.c index 981fe969..c525fadb 100644 --- a/dmidecode.c +++ b/libdmi.c @@ -77,7 +77,7 @@ #include "config.h" #include "types.h" #include "util.h" -#include "dmidecode.h" +#include "libdmi.h" #include "dmiopt.h" #include "dmioem.h" #include "dmioutput.h" @@ -5563,8 +5563,9 @@ static int address_from_efi(off_t *address) return ret; } -int main(int argc, char * const argv[]) +int procces(int argc, char * const argv[]) { + pr_init(); int ret = 0; /* Returned value */ int found = 0; off_t fp; @@ -5751,14 +5752,26 @@ int main(int argc, char * const argv[]) } } #endif - + done: if (!found && !(opt.flags & FLAG_QUIET)) pr_comment("No SMBIOS nor DMI entry point found, sorry."); - free(buf); exit_free: free(opt.type); - return ret; } + +char* decode_types(int argc, int* argv) +{ + char* args[3] = {"dmidecode", "-t", ""}; + char* type_ids = malloc(1000); + type_ids[0] = '\0'; + for (int i=0; i < argc; i++) + { + sprintf(type_ids + strlen(type_ids), "%d,", argv[i]); + } + args[2] = type_ids; + procces(3,args); + return get_output(); +} \ No newline at end of file diff --git a/dmidecode.h b/libdmi.h similarity index 96% rename from dmidecode.h rename to libdmi.h index 1dc59a7e..7ef50533 100644 --- a/dmidecode.h +++ b/libdmi.h @@ -33,5 +33,6 @@ struct dmi_header int is_printable(const u8 *data, int len); const char *dmi_string(const struct dmi_header *dm, u8 s); +char* decode_types(int argc, int* argv); #endif diff --git a/main.c b/main.c new file mode 100644 index 00000000..d8c12009 --- /dev/null +++ b/main.c @@ -0,0 +1,72 @@ +/* + * DMI Decode + * + * Copyright (C) 2000-2002 Alan Cox + * Copyright (C) 2002-2020 Jean Delvare + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * For the avoidance of doubt the "preferred form" of this code is one which + * is in an open unpatent encumbered format. Where cryptographic key signing + * forms part of the process of creating an executable the information + * including keys needed to generate an equivalently functional executable + * are deemed to be part of the source code. + * + * Unless specified otherwise, all references are aimed at the "System + * Management BIOS Reference Specification, Version 3.2.0" document, + * available from http://www.dmtf.org/standards/smbios. + * + * Note to contributors: + * Please reference every value you add or modify, especially if the + * information does not come from the above mentioned specification. + * + * Additional references: + * - Intel AP-485 revision 36 + * "Intel Processor Identification and the CPUID Instruction" + * http://www.intel.com/support/processors/sb/cs-009861.htm + * - DMTF Common Information Model + * CIM Schema version 2.19.1 + * http://www.dmtf.org/standards/cim/ + * - IPMI 2.0 revision 1.0 + * "Intelligent Platform Management Interface Specification" + * http://developer.intel.com/design/servers/ipmi/spec.htm + * - AMD publication #25481 revision 2.28 + * "CPUID Specification" + * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25481.pdf + * - BIOS Integrity Services Application Programming Interface version 1.0 + * http://www.intel.com/design/archives/wfm/downloads/bisspec.htm + * - DMTF DSP0239 version 1.1.0 + * "Management Component Transport Protocol (MCTP) IDs and Codes" + * http://www.dmtf.org/standards/pmci + * - "TPM Main, Part 2 TPM Structures" + * Specification version 1.2, level 2, revision 116 + * https://trustedcomputinggroup.org/tpm-main-specification/ + * - "PC Client Platform TPM Profile (PTP) Specification" + * Family "2.0", Level 00, Revision 00.43, January 26, 2015 + * https://trustedcomputinggroup.org/pc-client-platform-tpm-profile-ptp-specification/ + * - "RedFish Host Interface Specification" (DMTF DSP0270) + * https://www.dmtf.org/sites/default/files/DSP0270_1.0.1.pdf + */ + +#include "libdmi.h" +#include "dmioutput.h" + +int main(int argc, char * const argv[]) +{ + int ret = procces(argc, argv); + printf(get_output()); + pr_free(); + return ret; +} diff --git a/types.h b/types.h index 51c32d71..0c15b365 100644 --- a/types.h +++ b/types.h @@ -42,6 +42,98 @@ static inline u64 U64(u32 low, u32 high) } #endif +static const char* dmi_types_value[] = { + "BIOS", + "System", + "Baseboard", + "Chassis", + "Processor", + "Memory Controller", + "Memory Module", + "Cache", + "Port Connector", + "System Slots", + "On Board Devices", + "OEM Strings", + "System Configuration Options", + "BIOS Language", + "Group Associations", + "System Event Log", + "Physical Memory Array", + "Memory Device", + "32-bit Memory Error", + "Memory Array Mapped Address", + "Memory Device Mapped Address", + "Built-in Pointing Device", + "Portable Battery", + "System Reset", + "Hardware Security", + "System Power Controls", + "Voltage Probe", + "Cooling Device", + "Temperature Probe", + "Electrical Current Probe", + "Out-of-band Remote Access", + "Boot Integrity Services", + "System Boot", + "64-bit Memory Error", + "Management Device", + "Management Device Component", + "Management Device Threshold Data", + "Memory Channel", + "IPMI Device", + "Power Supply", + "Additional Information", + "Onboard Devices Extended Information", + "Management Controller Host Interface" +}; + +enum dmi_types{ + BIOS, + SYSTEM, + BASEBOARD, + CHASSIS, + PROCESSOR, + MEMORY_CONTROLLER, + MEMORY_MODULE, + CACHE, + PORT_CONNECTOR, + SYSTEM_SLOTS, + ON_BOARD_DEVICES, + OEM_STRINGS, + SYSTEM_CONFIGURATION_OPTIONS, + BIOS_LANGUAGE, + GROUP_ASSOCIATIONS, + SYSTEM_EVENT_LOG, + PHYSICAL_MEMORY_ARRAY, + MEMORY_DEVICE, + MEMORY_ERROR_32_BIT, + MEMORY_ARRAY_MAPPED_ADDRESS, + MEMORY_DEVICE_MAPPED_ADDRESS, + BUILT_IN_POINTING_DEVICE, + PORTABLE_BATTERY, + SYSTEM_RESET, + HARDWARE_SECURITY, + SYSTEM_POWER_CONTROLS, + VOLTAGE_PROBE, + COOLING_DEVICE, + TEMPERATURE_PROBE, + ELECTRICAL_CURRENT_PROBE, + OUT_OF_BAND_REMOTE_ACCESS, + BOOT_INTEGRITY_SERVICES, + SYSTEM_BOOT, + MEMORY_ERROR_64_BIT, + MANAGEMENT_DEVICE, + MANAGEMENT_DEVICE_COMPONENT, + MANAGEMENT_DEVICE_THRESHOLD_DATA, + MEMORY_CHANNEL, + IPMI_DEVICE, + POWER_SUPPLY, + ADDITIONAL_INFORMATION, + ONBOARD_DEVICES_EXTENDED_INFORMATION, + MANAGEMENT_CONTROLLER_HOST_INTERFACE +}; + /* * Per SMBIOS v2.8.0 and later, all structures assume a little-endian * ordering convention.