#include <stdlib.h> #include <string.h> #define ldmilib_c /* Define the library */ /* Include the Lua API header files */ #include "lua.h" #include "lauxlib.h" #include "lualib.h" #include "dmi/dmi.h" static void add_string_item(lua_State *L, const char *item, const char *value_str) { lua_pushstring(L,item); lua_pushstring(L,value_str); lua_settable(L,-3); } static void add_int_item(lua_State *L, const char *item, int value_int) { lua_pushstring(L,item); lua_pushnumber(L,value_int); lua_settable(L,-3); } typedef int (*table_fn)(lua_State*, s_dmi*); /* Add a Lua_String entry to the table on stack xxx_P is the poiter version (i.e., pBase is a pointer) xxx_S is the staic version (i.e., Base is the struct) */ #define LUA_ADD_STR_P(pLua_state, pBase, Field) \ add_string_item(pLua_state, #Field, pBase->Field); #define LUA_ADD_STR_S(pLua_state, Base, Field) \ add_string_item(pLua_state, #Field, Base.Field); /* Add a Lua_Number entry to the table on stack xxx_P is the poiter version (i.e., pBase is a pointer) xxx_S is the staic version (i.e., Base is the struct) */ #define LUA_ADD_NUM_P(pLua_state, pBase, Field) \ add_int_item(pLua_state, #Field, pBase->Field); #define LUA_ADD_NUM_S(pLua_state, Base, Field) \ add_int_item(pLua_state, #Field, Base.Field); /* Add a sub-DMI table to the table on stack All (*table_fn)() have to be named as get_<tabel_name>_table() for this macro to work. For example, for the bios subtable, the table_fn is get_bios_table() and the subtable name is "bios". All (*table_fn)() have to return 1 if a subtable is created on the stack or 0 if the subtable is not created (no corresponding dim subtable found). */ #define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \ add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table); static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name, table_fn get_table_fn) { if (get_table_fn(L, dmi_ptr)) { /* only adding it when it is there */ lua_pushstring(L, table_name); lua_insert(L, -2); lua_settable(L,-3); } } void get_bool_table(lua_State *L, const char *str_table[], int n_elem, bool *bool_table) { int i; for (i = 0; i < n_elem; i++) { if (!str_table[i] || !*str_table[i]) /* aviod NULL/empty string */ continue; lua_pushstring(L, str_table[i]); lua_pushboolean(L, bool_table[i]); lua_settable(L,-3); } } /* ** {====================================================== ** DMI subtables ** ======================================================= */ static int get_bios_table(lua_State *L, s_dmi *dmi_ptr) { s_bios *bios = &dmi_ptr->bios; if (!bios->filled) return 0; /* bios */ lua_newtable(L); LUA_ADD_STR_P(L, bios, vendor) LUA_ADD_STR_P(L, bios, version) LUA_ADD_STR_P(L, bios, release_date) LUA_ADD_STR_P(L, bios, bios_revision) LUA_ADD_STR_P(L, bios, firmware_revision) LUA_ADD_NUM_P(L, bios, address) LUA_ADD_NUM_P(L, bios, runtime_size) LUA_ADD_STR_P(L, bios, runtime_size_unit) LUA_ADD_NUM_P(L, bios, rom_size) LUA_ADD_STR_P(L, bios, rom_size_unit) /* bios characteristics */ lua_pushstring(L, "chars"); lua_newtable(L); get_bool_table(L, bios_charac_strings, sizeof(s_characteristics)/sizeof(bool), (bool *)(&bios->characteristics)); get_bool_table(L, bios_charac_x1_strings, sizeof(s_characteristics_x1)/sizeof(bool), (bool *)(&bios->characteristics_x1)); get_bool_table(L, bios_charac_x2_strings, sizeof(s_characteristics_x2)/sizeof(bool), (bool *)(&bios->characteristics_x2)); lua_settable(L,-3); return 1; } static int get_system_table(lua_State *L, s_dmi *dmi_ptr) { s_system *system = &dmi_ptr->system; if (!system->filled) return 0; /* system */ lua_newtable(L); LUA_ADD_STR_P(L, system, manufacturer) LUA_ADD_STR_P(L, system, product_name) LUA_ADD_STR_P(L, system, version) LUA_ADD_STR_P(L, system, serial) LUA_ADD_STR_P(L, system, uuid) LUA_ADD_STR_P(L, system, wakeup_type) LUA_ADD_STR_P(L, system, sku_number) LUA_ADD_STR_P(L, system, family) LUA_ADD_STR_P(L, system, system_boot_status) LUA_ADD_STR_P(L, system, configuration_options) /* system reset */ if (system->system_reset.filled) { lua_pushstring(L, "reset"); lua_newtable(L); LUA_ADD_NUM_S(L, system->system_reset, status) LUA_ADD_NUM_S(L, system->system_reset, watchdog) LUA_ADD_STR_S(L, system->system_reset, boot_option) LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit) LUA_ADD_STR_S(L, system->system_reset, reset_count) LUA_ADD_STR_S(L, system->system_reset, reset_limit) LUA_ADD_STR_S(L, system->system_reset, timer_interval) LUA_ADD_STR_S(L, system->system_reset, timeout) lua_settable(L,-3); } return 1; } static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr) { s_base_board *base_board = &dmi_ptr->base_board; int n_dev = sizeof(base_board->devices_information) / sizeof(base_board->devices_information[0]); int i, j, has_dev; if (!base_board->filled) return 0; /* base_board */ lua_newtable(L); LUA_ADD_STR_P(L, base_board, manufacturer) LUA_ADD_STR_P(L, base_board, product_name) LUA_ADD_STR_P(L, base_board, version) LUA_ADD_STR_P(L, base_board, serial) LUA_ADD_STR_P(L, base_board, asset_tag) LUA_ADD_STR_P(L, base_board, location) LUA_ADD_STR_P(L, base_board, type) /* base board features */ lua_pushstring(L, "features"); lua_newtable(L); get_bool_table(L, base_board_features_strings, sizeof(s_base_board_features)/sizeof(bool), (bool *)(&base_board->features)); lua_settable(L,-3); /* on-board devices */ for (has_dev = 0, i = 0; i < n_dev; i++) if (*base_board->devices_information[i].type) has_dev++; if (has_dev) { lua_pushstring(L, "devices"); lua_newtable(L); for (i = 0, j = 1; i < n_dev; i++) { if (!*base_board->devices_information[i].type) /* empty device */ continue; lua_pushinteger(L, j++); lua_newtable(L); LUA_ADD_STR_S(L, base_board->devices_information[i], type) LUA_ADD_STR_S(L, base_board->devices_information[i], description) LUA_ADD_NUM_S(L, base_board->devices_information[i], status) lua_settable(L,-3); } lua_settable(L,-3); } return 1; } static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr) { s_chassis *chassis = &dmi_ptr->chassis; if (!chassis->filled) return 0; /* chassis */ lua_newtable(L); LUA_ADD_STR_P(L, chassis, manufacturer) LUA_ADD_STR_P(L, chassis, type) LUA_ADD_STR_P(L, chassis, lock) LUA_ADD_STR_P(L, chassis, version) LUA_ADD_STR_P(L, chassis, serial) LUA_ADD_STR_P(L, chassis, asset_tag) LUA_ADD_STR_P(L, chassis, boot_up_state) LUA_ADD_STR_P(L, chassis, power_supply_state) LUA_ADD_STR_P(L, chassis, thermal_state) LUA_ADD_STR_P(L, chassis, security_status) LUA_ADD_STR_P(L, chassis, oem_information) LUA_ADD_NUM_P(L, chassis, height) LUA_ADD_NUM_P(L, chassis, nb_power_cords) return 1; } static int get_processor_table(lua_State *L, s_dmi *dmi_ptr) { s_processor *processor = &dmi_ptr->processor; s_signature *signature = &processor->signature; if (!processor->filled) return 0; /* processor */ lua_newtable(L); LUA_ADD_STR_P(L, processor, socket_designation) LUA_ADD_STR_P(L, processor, type) LUA_ADD_STR_P(L, processor, family) LUA_ADD_STR_P(L, processor, manufacturer) LUA_ADD_STR_P(L, processor, version) LUA_ADD_NUM_P(L, processor, external_clock) LUA_ADD_NUM_P(L, processor, max_speed) LUA_ADD_NUM_P(L, processor, current_speed) LUA_ADD_NUM_P(L, processor, voltage_mv) LUA_ADD_STR_P(L, processor, status) LUA_ADD_STR_P(L, processor, upgrade) LUA_ADD_STR_P(L, processor, cache1) LUA_ADD_STR_P(L, processor, cache2) LUA_ADD_STR_P(L, processor, cache3) LUA_ADD_STR_P(L, processor, serial) LUA_ADD_STR_P(L, processor, part_number) LUA_ADD_STR_P(L, processor, id) LUA_ADD_NUM_P(L, processor, core_count) LUA_ADD_NUM_P(L, processor, core_enabled) LUA_ADD_NUM_P(L, processor, thread_count) /* processor signature */ lua_pushstring(L, "signature"); lua_newtable(L); LUA_ADD_NUM_P(L, signature, type) LUA_ADD_NUM_P(L, signature, family) LUA_ADD_NUM_P(L, signature, model) LUA_ADD_NUM_P(L, signature, stepping) LUA_ADD_NUM_P(L, signature, minor_stepping) lua_settable(L,-3); /* processor flags */ lua_pushstring(L, "flags"); lua_newtable(L); get_bool_table(L, cpu_flags_strings, sizeof(s_dmi_cpu_flags)/sizeof(bool), (bool *)(&processor->cpu_flags)); lua_settable(L,-3); return 1; } static int get_battery_table(lua_State *L, s_dmi *dmi_ptr) { s_battery *battery = &dmi_ptr->battery; if (!battery->filled) return 0; /* battery */ lua_newtable(L); LUA_ADD_STR_P(L, battery, location) LUA_ADD_STR_P(L, battery, manufacturer) LUA_ADD_STR_P(L, battery, manufacture_date) LUA_ADD_STR_P(L, battery, serial) LUA_ADD_STR_P(L, battery, name) LUA_ADD_STR_P(L, battery, chemistry) LUA_ADD_STR_P(L, battery, design_capacity) LUA_ADD_STR_P(L, battery, design_voltage) LUA_ADD_STR_P(L, battery, sbds) LUA_ADD_STR_P(L, battery, sbds_serial) LUA_ADD_STR_P(L, battery, maximum_error) LUA_ADD_STR_P(L, battery, sbds_manufacture_date) LUA_ADD_STR_P(L, battery, sbds_chemistry) LUA_ADD_STR_P(L, battery, oem_info) return 1; } static int get_memory_table(lua_State *L, s_dmi *dmi_ptr) { s_memory *memory = dmi_ptr->memory; int i, j, n_mem = dmi_ptr->memory_count; if (n_mem <= 0) /* no memory info */ return 0; /* memory */ lua_newtable(L); for (j = 1, i = 0; i < n_mem; i++) { if (!memory[i].filled) continue; lua_pushinteger(L, j++); lua_newtable(L); LUA_ADD_STR_S(L, memory[i], manufacturer) LUA_ADD_STR_S(L, memory[i], error) LUA_ADD_STR_S(L, memory[i], total_width) LUA_ADD_STR_S(L, memory[i], data_width) LUA_ADD_STR_S(L, memory[i], size) LUA_ADD_STR_S(L, memory[i], form_factor) LUA_ADD_STR_S(L, memory[i], device_set) LUA_ADD_STR_S(L, memory[i], device_locator) LUA_ADD_STR_S(L, memory[i], bank_locator) LUA_ADD_STR_S(L, memory[i], type) LUA_ADD_STR_S(L, memory[i], type_detail) LUA_ADD_STR_S(L, memory[i], speed) LUA_ADD_STR_S(L, memory[i], serial) LUA_ADD_STR_S(L, memory[i], asset_tag) LUA_ADD_STR_S(L, memory[i], part_number) lua_settable(L,-3); } return 1; } static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr) { s_memory_module *memory_module = dmi_ptr->memory_module; int i, j, n_mem = dmi_ptr->memory_module_count; if (n_mem <= 0) /* no memory module info */ return 0; /* memory module */ lua_newtable(L); for (j = 1, i = 0; i < n_mem; i++) { if (!memory_module[i].filled) continue; lua_pushinteger(L, j++); lua_newtable(L); LUA_ADD_STR_S(L, memory_module[i], socket_designation) LUA_ADD_STR_S(L, memory_module[i], bank_connections) LUA_ADD_STR_S(L, memory_module[i], speed) LUA_ADD_STR_S(L, memory_module[i], type) LUA_ADD_STR_S(L, memory_module[i], installed_size) LUA_ADD_STR_S(L, memory_module[i], enabled_size) LUA_ADD_STR_S(L, memory_module[i], error_status) lua_settable(L,-3); } return 1; } static int get_cache_table(lua_State *L, s_dmi *dmi_ptr) { s_cache *cache = dmi_ptr->cache; int i, n_cache = dmi_ptr->cache_count; if (n_cache <= 0) /* no cache info */ return 0; /* memory */ lua_newtable(L); for (i = 0; i < n_cache; i++) { lua_pushinteger(L, i + 1); lua_newtable(L); LUA_ADD_STR_S(L, cache[i], socket_designation) LUA_ADD_STR_S(L, cache[i], configuration) LUA_ADD_STR_S(L, cache[i], mode) LUA_ADD_STR_S(L, cache[i], location) LUA_ADD_NUM_S(L, cache[i], installed_size) LUA_ADD_NUM_S(L, cache[i], max_size) LUA_ADD_STR_S(L, cache[i], supported_sram_types) LUA_ADD_STR_S(L, cache[i], installed_sram_types) LUA_ADD_NUM_S(L, cache[i], speed) LUA_ADD_STR_S(L, cache[i], error_correction_type) LUA_ADD_STR_S(L, cache[i], system_type) LUA_ADD_STR_S(L, cache[i], associativity) lua_settable(L,-3); } return 1; } static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr) { if (!dmi_ptr->hardware_security.filled) return 0; /* hardware_security */ lua_newtable(L); LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status) LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status) LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status) LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status) return 1; } static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr) { dmi_table *dmitable = &dmi_ptr->dmitable; /* dmi info */ lua_newtable(L); LUA_ADD_NUM_P(L, dmitable, num) LUA_ADD_NUM_P(L, dmitable, len) LUA_ADD_NUM_P(L, dmitable, ver) LUA_ADD_NUM_P(L, dmitable, base) LUA_ADD_NUM_P(L, dmitable, major_version) LUA_ADD_NUM_P(L, dmitable, minor_version) return 1; } static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr) { s_ipmi *ipmi = &dmi_ptr->ipmi; if (!ipmi->filled) return 0; /* ipmi */ lua_newtable(L); LUA_ADD_STR_P(L, ipmi, interface_type) LUA_ADD_NUM_P(L, ipmi, major_specification_version) LUA_ADD_NUM_P(L, ipmi, minor_specification_version) LUA_ADD_NUM_P(L, ipmi, I2C_slave_address) LUA_ADD_NUM_P(L, ipmi, nv_address) LUA_ADD_NUM_P(L, ipmi, base_address) LUA_ADD_NUM_P(L, ipmi, irq) return 1; } /* ** {====================================================== ** End of DMI subtables ** ======================================================= */ static int dmi_gettable(lua_State *L) { s_dmi dmi; lua_newtable(L); if ( ! dmi_iterate(&dmi) ) { printf("No DMI Structure found\n"); return -1; } parse_dmitable(&dmi); LUA_ADD_NUM_S(L, dmi, memory_module_count) LUA_ADD_NUM_S(L, dmi, memory_count) LUA_ADD_NUM_S(L, dmi, cache_count) LUA_ADD_STR_S(L, dmi, oem_strings) LUA_ADD_TABLE(L, &dmi, bios) LUA_ADD_TABLE(L, &dmi, system) LUA_ADD_TABLE(L, &dmi, base_board) LUA_ADD_TABLE(L, &dmi, chassis) LUA_ADD_TABLE(L, &dmi, processor) LUA_ADD_TABLE(L, &dmi, battery) LUA_ADD_TABLE(L, &dmi, memory) LUA_ADD_TABLE(L, &dmi, memory_module) LUA_ADD_TABLE(L, &dmi, cache) LUA_ADD_TABLE(L, &dmi, ipmi) LUA_ADD_TABLE(L, &dmi, hardware_security) LUA_ADD_TABLE(L, &dmi, dmi_info) /* set global variable: lua_setglobal(L, "dmitable"); */ /* return number of return values on stack */ return 1; } static int dmi_supported(lua_State *L) { s_dmi dmi; if ( dmi_iterate(&dmi) ) { lua_pushboolean(L, 1); } else { lua_pushboolean(L, 0); } return 1; } static const luaL_Reg dmilib[] = { {"gettable", dmi_gettable}, {"supported", dmi_supported}, {NULL, NULL} }; LUALIB_API int luaopen_dmi (lua_State *L) { luaL_newlib(L, dmilib); return 1; }