1#include <stdlib.h> 2#include <string.h> 3 4#define ldmilib_c /* Define the library */ 5 6/* Include the Lua API header files */ 7#include "lua.h" 8#include "lauxlib.h" 9#include "lualib.h" 10#include "dmi/dmi.h" 11 12static void add_string_item(lua_State *L, const char *item, const char *value_str) { 13 lua_pushstring(L,item); 14 lua_pushstring(L,value_str); 15 lua_settable(L,-3); 16} 17 18static void add_int_item(lua_State *L, const char *item, int value_int) { 19 lua_pushstring(L,item); 20 lua_pushnumber(L,value_int); 21 lua_settable(L,-3); 22} 23 24typedef int (*table_fn)(lua_State*, s_dmi*); 25 26/* Add a Lua_String entry to the table on stack 27 xxx_P is the poiter version (i.e., pBase is a pointer) 28 xxx_S is the staic version (i.e., Base is the struct) 29*/ 30#define LUA_ADD_STR_P(pLua_state, pBase, Field) \ 31 add_string_item(pLua_state, #Field, pBase->Field); 32#define LUA_ADD_STR_S(pLua_state, Base, Field) \ 33 add_string_item(pLua_state, #Field, Base.Field); 34 35/* Add a Lua_Number entry to the table on stack 36 xxx_P is the poiter version (i.e., pBase is a pointer) 37 xxx_S is the staic version (i.e., Base is the struct) 38*/ 39#define LUA_ADD_NUM_P(pLua_state, pBase, Field) \ 40 add_int_item(pLua_state, #Field, pBase->Field); 41#define LUA_ADD_NUM_S(pLua_state, Base, Field) \ 42 add_int_item(pLua_state, #Field, Base.Field); 43 44/* Add a sub-DMI table to the table on stack 45 All (*table_fn)() have to be named as get_<tabel_name>_table() for this 46 macro to work. For example, for the bios subtable, the table_fn is 47 get_bios_table() and the subtable name is "bios". 48 All (*table_fn)() have to return 1 if a subtable is created on the stack 49 or 0 if the subtable is not created (no corresponding dim subtable found). 50*/ 51#define LUA_ADD_TABLE(pLua_state, pDmi, tb_name) \ 52 add_dmi_sub_table(pLua_state, pDmi, #tb_name, get_ ## tb_name ## _table); 53 54 55static void add_dmi_sub_table(lua_State *L, s_dmi *dmi_ptr, char *table_name, 56 table_fn get_table_fn) 57{ 58 if (get_table_fn(L, dmi_ptr)) { /* only adding it when it is there */ 59 lua_pushstring(L, table_name); 60 lua_insert(L, -2); 61 lua_settable(L,-3); 62 } 63} 64 65 66void get_bool_table(lua_State *L, const char *str_table[], int n_elem, 67 bool *bool_table) 68{ 69 int i; 70 for (i = 0; i < n_elem; i++) { 71 if (!str_table[i] || !*str_table[i]) /* aviod NULL/empty string */ 72 continue; 73 74 lua_pushstring(L, str_table[i]); 75 lua_pushboolean(L, bool_table[i]); 76 lua_settable(L,-3); 77 } 78} 79 80 81/* 82** {====================================================== 83** DMI subtables 84** ======================================================= 85*/ 86static int get_bios_table(lua_State *L, s_dmi *dmi_ptr) 87{ 88 s_bios *bios = &dmi_ptr->bios; 89 90 if (!bios->filled) 91 return 0; 92 /* bios */ 93 lua_newtable(L); 94 LUA_ADD_STR_P(L, bios, vendor) 95 LUA_ADD_STR_P(L, bios, version) 96 LUA_ADD_STR_P(L, bios, release_date) 97 LUA_ADD_STR_P(L, bios, bios_revision) 98 LUA_ADD_STR_P(L, bios, firmware_revision) 99 LUA_ADD_NUM_P(L, bios, address) 100 LUA_ADD_NUM_P(L, bios, runtime_size) 101 LUA_ADD_STR_P(L, bios, runtime_size_unit) 102 LUA_ADD_NUM_P(L, bios, rom_size) 103 LUA_ADD_STR_P(L, bios, rom_size_unit) 104 105 /* bios characteristics */ 106 lua_pushstring(L, "chars"); 107 lua_newtable(L); 108 get_bool_table(L, bios_charac_strings, 109 sizeof(s_characteristics)/sizeof(bool), 110 (bool *)(&bios->characteristics)); 111 get_bool_table(L, bios_charac_x1_strings, 112 sizeof(s_characteristics_x1)/sizeof(bool), 113 (bool *)(&bios->characteristics_x1)); 114 get_bool_table(L, bios_charac_x2_strings, 115 sizeof(s_characteristics_x2)/sizeof(bool), 116 (bool *)(&bios->characteristics_x2)); 117 lua_settable(L,-3); 118 119 return 1; 120} 121 122 123static int get_system_table(lua_State *L, s_dmi *dmi_ptr) 124{ 125 s_system *system = &dmi_ptr->system; 126 127 if (!system->filled) 128 return 0; 129 /* system */ 130 lua_newtable(L); 131 LUA_ADD_STR_P(L, system, manufacturer) 132 LUA_ADD_STR_P(L, system, product_name) 133 LUA_ADD_STR_P(L, system, version) 134 LUA_ADD_STR_P(L, system, serial) 135 LUA_ADD_STR_P(L, system, uuid) 136 LUA_ADD_STR_P(L, system, wakeup_type) 137 LUA_ADD_STR_P(L, system, sku_number) 138 LUA_ADD_STR_P(L, system, family) 139 LUA_ADD_STR_P(L, system, system_boot_status) 140 LUA_ADD_STR_P(L, system, configuration_options) 141 142 /* system reset */ 143 if (system->system_reset.filled) { 144 lua_pushstring(L, "reset"); 145 lua_newtable(L); 146 LUA_ADD_NUM_S(L, system->system_reset, status) 147 LUA_ADD_NUM_S(L, system->system_reset, watchdog) 148 LUA_ADD_STR_S(L, system->system_reset, boot_option) 149 LUA_ADD_STR_S(L, system->system_reset, boot_option_on_limit) 150 LUA_ADD_STR_S(L, system->system_reset, reset_count) 151 LUA_ADD_STR_S(L, system->system_reset, reset_limit) 152 LUA_ADD_STR_S(L, system->system_reset, timer_interval) 153 LUA_ADD_STR_S(L, system->system_reset, timeout) 154 lua_settable(L,-3); 155 } 156 157 return 1; 158} 159 160 161static int get_base_board_table(lua_State *L, s_dmi *dmi_ptr) 162{ 163 s_base_board *base_board = &dmi_ptr->base_board; 164 int n_dev = sizeof(base_board->devices_information) / 165 sizeof(base_board->devices_information[0]); 166 int i, j, has_dev; 167 168 if (!base_board->filled) 169 return 0; 170 /* base_board */ 171 lua_newtable(L); 172 LUA_ADD_STR_P(L, base_board, manufacturer) 173 LUA_ADD_STR_P(L, base_board, product_name) 174 LUA_ADD_STR_P(L, base_board, version) 175 LUA_ADD_STR_P(L, base_board, serial) 176 LUA_ADD_STR_P(L, base_board, asset_tag) 177 LUA_ADD_STR_P(L, base_board, location) 178 LUA_ADD_STR_P(L, base_board, type) 179 180 /* base board features */ 181 lua_pushstring(L, "features"); 182 lua_newtable(L); 183 get_bool_table(L, base_board_features_strings, 184 sizeof(s_base_board_features)/sizeof(bool), 185 (bool *)(&base_board->features)); 186 lua_settable(L,-3); 187 188 /* on-board devices */ 189 for (has_dev = 0, i = 0; i < n_dev; i++) 190 if (*base_board->devices_information[i].type) 191 has_dev++; 192 193 if (has_dev) { 194 lua_pushstring(L, "devices"); 195 lua_newtable(L); 196 for (i = 0, j = 1; i < n_dev; i++) { 197 if (!*base_board->devices_information[i].type) /* empty device */ 198 continue; 199 200 lua_pushinteger(L, j++); 201 lua_newtable(L); 202 LUA_ADD_STR_S(L, base_board->devices_information[i], type) 203 LUA_ADD_STR_S(L, base_board->devices_information[i], description) 204 LUA_ADD_NUM_S(L, base_board->devices_information[i], status) 205 lua_settable(L,-3); 206 } 207 lua_settable(L,-3); 208 } 209 210 return 1; 211} 212 213 214static int get_chassis_table(lua_State *L, s_dmi *dmi_ptr) 215{ 216 s_chassis *chassis = &dmi_ptr->chassis; 217 218 if (!chassis->filled) 219 return 0; 220 /* chassis */ 221 lua_newtable(L); 222 LUA_ADD_STR_P(L, chassis, manufacturer) 223 LUA_ADD_STR_P(L, chassis, type) 224 LUA_ADD_STR_P(L, chassis, lock) 225 LUA_ADD_STR_P(L, chassis, version) 226 LUA_ADD_STR_P(L, chassis, serial) 227 LUA_ADD_STR_P(L, chassis, asset_tag) 228 LUA_ADD_STR_P(L, chassis, boot_up_state) 229 LUA_ADD_STR_P(L, chassis, power_supply_state) 230 LUA_ADD_STR_P(L, chassis, thermal_state) 231 LUA_ADD_STR_P(L, chassis, security_status) 232 LUA_ADD_STR_P(L, chassis, oem_information) 233 LUA_ADD_NUM_P(L, chassis, height) 234 LUA_ADD_NUM_P(L, chassis, nb_power_cords) 235 236 return 1; 237} 238 239 240static int get_processor_table(lua_State *L, s_dmi *dmi_ptr) 241{ 242 s_processor *processor = &dmi_ptr->processor; 243 s_signature *signature = &processor->signature; 244 245 if (!processor->filled) 246 return 0; 247 /* processor */ 248 lua_newtable(L); 249 LUA_ADD_STR_P(L, processor, socket_designation) 250 LUA_ADD_STR_P(L, processor, type) 251 LUA_ADD_STR_P(L, processor, family) 252 LUA_ADD_STR_P(L, processor, manufacturer) 253 LUA_ADD_STR_P(L, processor, version) 254 LUA_ADD_NUM_P(L, processor, external_clock) 255 LUA_ADD_NUM_P(L, processor, max_speed) 256 LUA_ADD_NUM_P(L, processor, current_speed) 257 LUA_ADD_NUM_P(L, processor, voltage_mv) 258 LUA_ADD_STR_P(L, processor, status) 259 LUA_ADD_STR_P(L, processor, upgrade) 260 LUA_ADD_STR_P(L, processor, cache1) 261 LUA_ADD_STR_P(L, processor, cache2) 262 LUA_ADD_STR_P(L, processor, cache3) 263 LUA_ADD_STR_P(L, processor, serial) 264 LUA_ADD_STR_P(L, processor, part_number) 265 LUA_ADD_STR_P(L, processor, id) 266 LUA_ADD_NUM_P(L, processor, core_count) 267 LUA_ADD_NUM_P(L, processor, core_enabled) 268 LUA_ADD_NUM_P(L, processor, thread_count) 269 270 /* processor signature */ 271 lua_pushstring(L, "signature"); 272 lua_newtable(L); 273 LUA_ADD_NUM_P(L, signature, type) 274 LUA_ADD_NUM_P(L, signature, family) 275 LUA_ADD_NUM_P(L, signature, model) 276 LUA_ADD_NUM_P(L, signature, stepping) 277 LUA_ADD_NUM_P(L, signature, minor_stepping) 278 lua_settable(L,-3); 279 280 /* processor flags */ 281 lua_pushstring(L, "flags"); 282 lua_newtable(L); 283 get_bool_table(L, cpu_flags_strings, 284 sizeof(s_dmi_cpu_flags)/sizeof(bool), 285 (bool *)(&processor->cpu_flags)); 286 lua_settable(L,-3); 287 288 return 1; 289} 290 291 292static int get_battery_table(lua_State *L, s_dmi *dmi_ptr) 293{ 294 s_battery *battery = &dmi_ptr->battery; 295 296 if (!battery->filled) 297 return 0; 298 /* battery */ 299 lua_newtable(L); 300 LUA_ADD_STR_P(L, battery, location) 301 LUA_ADD_STR_P(L, battery, manufacturer) 302 LUA_ADD_STR_P(L, battery, manufacture_date) 303 LUA_ADD_STR_P(L, battery, serial) 304 LUA_ADD_STR_P(L, battery, name) 305 LUA_ADD_STR_P(L, battery, chemistry) 306 LUA_ADD_STR_P(L, battery, design_capacity) 307 LUA_ADD_STR_P(L, battery, design_voltage) 308 LUA_ADD_STR_P(L, battery, sbds) 309 LUA_ADD_STR_P(L, battery, sbds_serial) 310 LUA_ADD_STR_P(L, battery, maximum_error) 311 LUA_ADD_STR_P(L, battery, sbds_manufacture_date) 312 LUA_ADD_STR_P(L, battery, sbds_chemistry) 313 LUA_ADD_STR_P(L, battery, oem_info) 314 315 return 1; 316} 317 318 319static int get_memory_table(lua_State *L, s_dmi *dmi_ptr) 320{ 321 s_memory *memory = dmi_ptr->memory; 322 int i, j, n_mem = dmi_ptr->memory_count; 323 324 if (n_mem <= 0) /* no memory info */ 325 return 0; 326 327 /* memory */ 328 lua_newtable(L); 329 for (j = 1, i = 0; i < n_mem; i++) { 330 if (!memory[i].filled) 331 continue; 332 333 lua_pushinteger(L, j++); 334 lua_newtable(L); 335 LUA_ADD_STR_S(L, memory[i], manufacturer) 336 LUA_ADD_STR_S(L, memory[i], error) 337 LUA_ADD_STR_S(L, memory[i], total_width) 338 LUA_ADD_STR_S(L, memory[i], data_width) 339 LUA_ADD_STR_S(L, memory[i], size) 340 LUA_ADD_STR_S(L, memory[i], form_factor) 341 LUA_ADD_STR_S(L, memory[i], device_set) 342 LUA_ADD_STR_S(L, memory[i], device_locator) 343 LUA_ADD_STR_S(L, memory[i], bank_locator) 344 LUA_ADD_STR_S(L, memory[i], type) 345 LUA_ADD_STR_S(L, memory[i], type_detail) 346 LUA_ADD_STR_S(L, memory[i], speed) 347 LUA_ADD_STR_S(L, memory[i], serial) 348 LUA_ADD_STR_S(L, memory[i], asset_tag) 349 LUA_ADD_STR_S(L, memory[i], part_number) 350 lua_settable(L,-3); 351 } 352 return 1; 353} 354 355 356static int get_memory_module_table(lua_State *L, s_dmi *dmi_ptr) 357{ 358 s_memory_module *memory_module = dmi_ptr->memory_module; 359 int i, j, n_mem = dmi_ptr->memory_module_count; 360 361 if (n_mem <= 0) /* no memory module info */ 362 return 0; 363 364 /* memory module */ 365 lua_newtable(L); 366 for (j = 1, i = 0; i < n_mem; i++) { 367 if (!memory_module[i].filled) 368 continue; 369 370 lua_pushinteger(L, j++); 371 lua_newtable(L); 372 LUA_ADD_STR_S(L, memory_module[i], socket_designation) 373 LUA_ADD_STR_S(L, memory_module[i], bank_connections) 374 LUA_ADD_STR_S(L, memory_module[i], speed) 375 LUA_ADD_STR_S(L, memory_module[i], type) 376 LUA_ADD_STR_S(L, memory_module[i], installed_size) 377 LUA_ADD_STR_S(L, memory_module[i], enabled_size) 378 LUA_ADD_STR_S(L, memory_module[i], error_status) 379 lua_settable(L,-3); 380 } 381 return 1; 382} 383 384 385static int get_cache_table(lua_State *L, s_dmi *dmi_ptr) 386{ 387 s_cache *cache = dmi_ptr->cache; 388 int i, n_cache = dmi_ptr->cache_count; 389 390 if (n_cache <= 0) /* no cache info */ 391 return 0; 392 393 /* memory */ 394 lua_newtable(L); 395 for (i = 0; i < n_cache; i++) { 396 lua_pushinteger(L, i + 1); 397 lua_newtable(L); 398 LUA_ADD_STR_S(L, cache[i], socket_designation) 399 LUA_ADD_STR_S(L, cache[i], configuration) 400 LUA_ADD_STR_S(L, cache[i], mode) 401 LUA_ADD_STR_S(L, cache[i], location) 402 LUA_ADD_NUM_S(L, cache[i], installed_size) 403 LUA_ADD_NUM_S(L, cache[i], max_size) 404 LUA_ADD_STR_S(L, cache[i], supported_sram_types) 405 LUA_ADD_STR_S(L, cache[i], installed_sram_types) 406 LUA_ADD_NUM_S(L, cache[i], speed) 407 LUA_ADD_STR_S(L, cache[i], error_correction_type) 408 LUA_ADD_STR_S(L, cache[i], system_type) 409 LUA_ADD_STR_S(L, cache[i], associativity) 410 lua_settable(L,-3); 411 } 412 return 1; 413} 414 415 416static int get_hardware_security_table(lua_State *L, s_dmi *dmi_ptr) 417{ 418 if (!dmi_ptr->hardware_security.filled) 419 return 0; 420 /* hardware_security */ 421 lua_newtable(L); 422 LUA_ADD_STR_S(L, dmi_ptr->hardware_security, power_on_passwd_status) 423 LUA_ADD_STR_S(L, dmi_ptr->hardware_security, keyboard_passwd_status) 424 LUA_ADD_STR_S(L, dmi_ptr->hardware_security, administrator_passwd_status) 425 LUA_ADD_STR_S(L, dmi_ptr->hardware_security, front_panel_reset_status) 426 427 return 1; 428} 429 430 431static int get_dmi_info_table(lua_State *L, s_dmi *dmi_ptr) 432{ 433 dmi_table *dmitable = &dmi_ptr->dmitable; 434 435 /* dmi info */ 436 lua_newtable(L); 437 LUA_ADD_NUM_P(L, dmitable, num) 438 LUA_ADD_NUM_P(L, dmitable, len) 439 LUA_ADD_NUM_P(L, dmitable, ver) 440 LUA_ADD_NUM_P(L, dmitable, base) 441 LUA_ADD_NUM_P(L, dmitable, major_version) 442 LUA_ADD_NUM_P(L, dmitable, minor_version) 443 444 return 1; 445} 446 447 448static int get_ipmi_table(lua_State *L, s_dmi *dmi_ptr) 449{ 450 s_ipmi *ipmi = &dmi_ptr->ipmi; 451 452 if (!ipmi->filled) 453 return 0; 454 /* ipmi */ 455 lua_newtable(L); 456 LUA_ADD_STR_P(L, ipmi, interface_type) 457 LUA_ADD_NUM_P(L, ipmi, major_specification_version) 458 LUA_ADD_NUM_P(L, ipmi, minor_specification_version) 459 LUA_ADD_NUM_P(L, ipmi, I2C_slave_address) 460 LUA_ADD_NUM_P(L, ipmi, nv_address) 461 LUA_ADD_NUM_P(L, ipmi, base_address) 462 LUA_ADD_NUM_P(L, ipmi, irq) 463 464 return 1; 465} 466/* 467** {====================================================== 468** End of DMI subtables 469** ======================================================= 470*/ 471 472 473static int dmi_gettable(lua_State *L) 474{ 475 s_dmi dmi; 476 477 lua_newtable(L); 478 479 if ( ! dmi_iterate(&dmi) ) { 480 printf("No DMI Structure found\n"); 481 return -1; 482 } 483 484 parse_dmitable(&dmi); 485 486 LUA_ADD_NUM_S(L, dmi, memory_module_count) 487 LUA_ADD_NUM_S(L, dmi, memory_count) 488 LUA_ADD_NUM_S(L, dmi, cache_count) 489 LUA_ADD_STR_S(L, dmi, oem_strings) 490 491 LUA_ADD_TABLE(L, &dmi, bios) 492 LUA_ADD_TABLE(L, &dmi, system) 493 LUA_ADD_TABLE(L, &dmi, base_board) 494 LUA_ADD_TABLE(L, &dmi, chassis) 495 LUA_ADD_TABLE(L, &dmi, processor) 496 LUA_ADD_TABLE(L, &dmi, battery) 497 LUA_ADD_TABLE(L, &dmi, memory) 498 LUA_ADD_TABLE(L, &dmi, memory_module) 499 LUA_ADD_TABLE(L, &dmi, cache) 500 LUA_ADD_TABLE(L, &dmi, ipmi) 501 LUA_ADD_TABLE(L, &dmi, hardware_security) 502 LUA_ADD_TABLE(L, &dmi, dmi_info) 503 504 /* set global variable: lua_setglobal(L, "dmitable"); */ 505 506 /* return number of return values on stack */ 507 return 1; 508} 509 510 511static int dmi_supported(lua_State *L) 512{ 513 s_dmi dmi; 514 515 if ( dmi_iterate(&dmi) ) { 516 lua_pushboolean(L, 1); 517 } else { 518 lua_pushboolean(L, 0); 519 } 520 return 1; 521} 522 523 524static const luaL_Reg dmilib[] = { 525 {"gettable", dmi_gettable}, 526 {"supported", dmi_supported}, 527 {NULL, NULL} 528}; 529 530 531LUALIB_API int luaopen_dmi (lua_State *L) { 532 luaL_newlib(L, dmilib); 533 return 1; 534} 535 536