summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dmidecode.c137
-rw-r--r--dmidecode.h3
-rw-r--r--dmidecodemodule.c54
-rwxr-xr-xexample.py5
4 files changed, 120 insertions, 79 deletions
diff --git a/dmidecode.c b/dmidecode.c
index 0bffdda..9623595 100644
--- a/dmidecode.c
+++ b/dmidecode.c
@@ -68,8 +68,9 @@
#include "dmihelper.h"
-/*
-*/
+#define EFI_NOT_FOUND (-1)
+#define EFI_NO_SMBIOS (-2)
+
static const char *out_of_spec = "<OUT OF SPEC>";
static const char *bad_index = "<BAD INDEX>";
#define BAD_INDEX PyString_FromString("<BAD INDEX>")
@@ -4297,6 +4298,7 @@ static void dmi_table_string_py(const struct dmi_header *h, const u8 *data, PyOb
Py_DECREF(_val);
}
+/*
static void dmi_table_dump(u32 base, u16 len, const char *devmem)
{
u8 *buf;
@@ -4311,6 +4313,104 @@ static void dmi_table_dump(u32 base, u16 len, const char *devmem)
write_dump(32, len, buf, PyString_AS_STRING(opt.dumpfile), 0);
free(buf);
}
+*/
+
+/*
+ * Build a crafted entry point with table address hard-coded to 32,
+ * as this is where we will put it in the output file. We adjust the
+ * DMI checksum appropriately. The SMBIOS checksum needs no adjustment.
+ */
+static void overwrite_dmi_address(u8 *buf) {
+ buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32;
+ buf[0x08] = 32;
+ buf[0x09] = 0;
+ buf[0x0A] = 0;
+ buf[0x0B] = 0;
+}
+
+
+#define NON_LEGACY 0
+#define LEGACY 1
+int dumpling(u8 *buf, const char *dumpfile, u8 mode) {
+ u32 base;
+ u16 len;
+ if(mode != LEGACY) {
+ base = DWORD(buf+0x18);
+ len = WORD(buf+0x16);
+ } else {
+ base = DWORD(buf+0x08);
+ len = WORD(buf+0x06);
+ }
+
+ u8 *buff;
+ if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) {
+ //. Part 1.
+ printf("# Writing %d bytes to %s.\n", len, dumpfile);
+ write_dump(32, len, buf, dumpfile, 0);
+ free(buff);
+
+ //. Part 2.
+ if(mode != LEGACY) {
+ u8 crafted[32];
+ memcpy(crafted, buf, 32);
+ overwrite_dmi_address(crafted+0x10);
+ printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile);
+ write_dump(0, crafted[0x05], crafted, dumpfile, 1);
+ } else {
+ u8 crafted[16];
+ memcpy(crafted, buf, 16);
+ overwrite_dmi_address(crafted);
+ printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile);
+ write_dump(0, 0x0F, crafted, dumpfile, 1);
+ }
+ } else {
+ fprintf(stderr, "Failed to read table, sorry.\n");
+ }
+
+ //. TODO: Cleanup
+ return 1;
+}
+
+int dump(const char *dumpfile) {
+ /* On success, return found, otherwise return -1 */
+ int ret=0;
+ int found=0;
+ size_t fp;
+ int efi;
+ u8 *buf;
+
+ /* First try EFI (ia64, Intel-based Mac) */
+ efi = address_from_efi(&fp);
+ if(efi == EFI_NOT_FOUND) {
+ /* Fallback to memory scan (x86, x86_64) */
+ if((buf=mem_chunk(0xF0000, 0x10000, DEFAULT_MEM_DEV))!=NULL) {
+ for(fp=0; fp<=0xFFF0; fp+=16) {
+ if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) {
+ if(dumpling(buf+fp, dumpfile, NON_LEGACY)) found++;
+ fp+=16;
+ } else if(memcmp(buf+fp, "_DMI_", 5)==0) {
+ if(dumpling(buf+fp, dumpfile, LEGACY)) found++;
+ }
+ }
+ } else ret = -1;
+ } else if(efi == EFI_NO_SMBIOS) {
+ ret = -1;
+ } else {
+ if((buf=mem_chunk(fp, 0x20, DEFAULT_MEM_DEV))==NULL) ret = -1;
+ else if(dumpling(buf, dumpfile, NON_LEGACY)) found++;
+ }
+
+ if(ret==0) {
+ free(buf);
+
+ //. TODO: Exception
+ //dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G.");
+ if(!found) ret = -1;
+ }
+
+ return ret==0?found:ret;
+}
+
static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, PyObject *pydata) {
@@ -4393,7 +4493,7 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P
if(display) {
if(next-buf<=len) {
- /* TODO: DUMP
+ /* TODO: ...
if(opt.flags & FLAG_DUMP) {
PyDict_SetItem(hDict, PyString_FromString("lookup"), dmi_dump(&h));
} else {
@@ -4406,23 +4506,9 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P
PyDict_SetItem(hDict, PyString_FromString("data"), dmi_decode(&h, ver));
PyDict_SetItem(pydata, PyString_FromString(hid), hDict);
} else fprintf(stderr, "<TRUNCATED>");
- } else if(opt.string!=NULL && opt.string->type==h.type)
+ } else if(opt.string!=NULL && opt.string->type==h.type) {
dmi_table_string_py(&h, data, hDict, ver);
- /* && opt.string->offset<h.length) {
- if(opt.string->lookup!=NULL) {
- char _[512];
- strcpy(_, opt.string->lookup(data[opt.string->offset]));
- dmiSetItem(hDict, "lookup", _);
- } else if(opt.string->print!=NULL) {
- char _[512];
- opt.string->print(data+opt.string->offset, _);
- dmiSetItem(hDict, "print", _);
- } else {
- dmiSetItem(hDict, "lookup", dmi_string(&h, data[opt.string->offset]));
- //fprintf(stderr, "%s\n", dmi_string(&h, data[opt.string->offset]));
- }
}
- */
data=next;
i++;
@@ -4437,18 +4523,6 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, P
free(buf);
}
-/*
- * Build a crafted entry point with table address hard-coded to 32,
- * as this is where we will put it in the output file. We adjust the
- * DMI checksum appropriately. The SMBIOS checksum needs no adjustment.
- */
-static void overwrite_dmi_address(u8 *buf) {
- buf[0x05] += buf[0x08] + buf[0x09] + buf[0x0A] + buf[0x0B] - 32;
- buf[0x08] = 32;
- buf[0x09] = 0;
- buf[0x0A] = 0;
- buf[0x0B] = 0;
-}
int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata) {
@@ -4480,6 +4554,7 @@ int smbios_decode(u8 *buf, const char *devmem, PyObject* pydata) {
return 1;
}
+
int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata) {
if(pydata == NULL) return 1;
if(!checksum(buf, 0x0F)) return 0;
@@ -4503,8 +4578,6 @@ int legacy_decode(u8 *buf, const char *devmem, PyObject* pydata) {
/*******************************************************************************
** Probe for EFI interface
*/
-#define EFI_NOT_FOUND (-1)
-#define EFI_NO_SMBIOS (-2)
int address_from_efi(size_t *address) {
FILE *efi_systab;
const char *filename;
diff --git a/dmidecode.h b/dmidecode.h
index c8206cc..46f822f 100644
--- a/dmidecode.h
+++ b/dmidecode.h
@@ -38,3 +38,6 @@ const char *dmi_system_uuid(u8 *p);
PyObject *dmi_system_uuid_py(const u8 *p, u16 ver);
const char *dmi_chassis_type(u8 code);
int dmi_processor_frequency(const u8 *p);
+
+int dump(const char *dumpfile);
+int dumpling(u8 *buf, const char *devmem, u8 mode);
diff --git a/dmidecodemodule.c b/dmidecodemodule.c
index 860fff6..fc140eb 100644
--- a/dmidecodemodule.c
+++ b/dmidecodemodule.c
@@ -96,9 +96,7 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
efi = address_from_efi(&fp);
if(efi == EFI_NOT_FOUND) {
/* Fallback to memory scan (x86, x86_64) */
- if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))==NULL) {
- ret = 1;
- } else {
+ if((buf=mem_chunk(0xF0000, 0x10000, opt.devmem))!=NULL) {
for(fp=0; fp<=0xFFF0; fp+=16) {
if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0) {
if(smbios_decode(buf+fp, opt.devmem, pydata)) found++;
@@ -107,15 +105,12 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
if(legacy_decode(buf+fp, opt.devmem, pydata)) found++;
}
}
- }
+ } else ret = 1;
} else if(efi == EFI_NO_SMBIOS) {
ret = 1;
} else {
- if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) {
- ret = 1;
- } else {
- if(smbios_decode(buf, opt.devmem, pydata)) found++;
- }
+ if((buf=mem_chunk(fp, 0x20, opt.devmem))==NULL) ret = 1;
+ else if(smbios_decode(buf, opt.devmem, pydata)) found++;
//. TODO: dmiSetItem(pydata, "efi_address", efiAddress);
}
@@ -125,45 +120,10 @@ static PyObject* dmidecode_get(PyObject *self, const char* section) {
if(!found)
dmiSetItem(pydata, "detect", "No SMBIOS nor DMI entry point found, sorry G.");
}
-
-
free(opt.type);
- /*
- PyObject* raw = PyUnicode_Splitlines(Py_BuildValue("s", buffer), 1);
- int i;
- char* nextLine;
- for(i=0; i<PyList_Size(raw); i++) {
- nextLine = PyString_AS_STRING(PySequence_ITEM(raw, i));
- if(strstr(nextLine, "Handle") != NULL) {
- printf("woohoo!: %s\n", nextLine);
- } else {
- printf(" --> %i %s\n", i, nextLine);
- }
- }*/
-
- if(ret == 1) return NULL;
-
- /*
- PyObject* data = PyDict_New();
- PyObject* s = NULL;
- PyObject* d = NULL;
- PyObject* key = NULL;
- while(nextLine != NULL) {
- if(memcmp(nextLine, "Handle", 6) == 0) {
- key = PyInt_FromLong(strtol(nextLine+7, NULL, 16));
- d = PyList_New(0);
- PyDict_SetItem(data, key, d);
- } else if(key) {
- s = Py_BuildValue("s", nextLine);
- PyList_Append(d, s);
- }
- nextLine = strtok(NULL, "\n");
- }
- */
-
//muntrace();
- return pydata;
+ return (ret != 1)?pydata:NULL;
}
static PyObject* dmidecode_get_bios(PyObject *self, PyObject *args) { return dmidecode_get(self, "bios"); }
@@ -182,7 +142,9 @@ static PyObject* dmidecode_get_type(PyObject *self, PyObject *args) {
return Py_None;
}
-static PyObject* dmidecode_dump(PyObject *self, PyObject *args) { return Py_False; }
+static PyObject* dmidecode_dump(PyObject *self, PyObject *args) {
+ fprintf(stderr, ">>> %d <<<\n", dump(PyString_AS_STRING(opt.dumpfile)));
+}
static PyObject* dmidecode_load(PyObject *self, PyObject *args) { return Py_False; }
static PyObject* dmidecode_get_dev(PyObject *self, PyObject *null) {
diff --git a/example.py b/example.py
index 1ad161c..bccf31f 100755
--- a/example.py
+++ b/example.py
@@ -3,7 +3,10 @@ import dmidecode
import sys
print dmidecode.get_dev()
-print dmidecode.set_dev("/tmp/mem")
+print dmidecode.set_dev("private/mem-XXX")
+print dmidecode.dump()
+
+print dmidecode.set_dev("private/mem-001")
print dmidecode.get_dev()
print "*** bios ***\n"; dmidecode.bios()