diff options
author | David Sommerseth <davids@redhat.com> | 2009-06-18 14:53:29 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2009-06-18 15:03:24 +0200 |
commit | 3849ca0a4abf5eb661758e1341a6e595d3013c2c (patch) | |
tree | d5f69c0231a687b81c2334f2094f56606bfe906a | |
parent | cb94510ce84cea18a675f1984cc8a3c955e6a2a4 (diff) | |
download | python-dmidecode-3849ca0a4abf5eb661758e1341a6e595d3013c2c.tar.gz python-dmidecode-3849ca0a4abf5eb661758e1341a6e595d3013c2c.tar.xz python-dmidecode-3849ca0a4abf5eb661758e1341a6e595d3013c2c.zip |
Splitted out SMBIOS/DMI dump functions from dmidecode.c to separate files
-rw-r--r-- | src/dmidecode.c | 164 | ||||
-rw-r--r-- | src/dmidecode.h | 4 | ||||
-rw-r--r-- | src/dmidecodemodule.c | 3 | ||||
-rw-r--r-- | src/dmidump.c | 155 | ||||
-rw-r--r-- | src/dmidump.h | 37 | ||||
-rw-r--r-- | src/efi.c | 83 | ||||
-rw-r--r-- | src/efi.h | 35 | ||||
-rw-r--r-- | src/setup-dbg.py | 4 | ||||
-rw-r--r-- | src/setup.py | 4 |
9 files changed, 320 insertions, 169 deletions
diff --git a/src/dmidecode.c b/src/dmidecode.c index 003e9ff..9a35ecb 100644 --- a/src/dmidecode.c +++ b/src/dmidecode.c @@ -84,13 +84,11 @@ #include "dmixml.h" #include "dmidecode.h" #include "dmioem.h" +#include "efi.h" +#include "dmidump.h" #include "dmihelper.h" -#define EFI_NOT_FOUND (-1) -#define EFI_NO_SMBIOS (-2) - - /******************************************************************************* ** Type-independant Stuff */ @@ -4830,123 +4828,6 @@ void to_dmi_header(struct dmi_header *h, u8 * data) h->data = data; } -/* - * 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 == NON_LEGACY) { - if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 || - !checksum(buf + 0x10, 0x0F)) - return 0; - base = DWORD(buf + 0x18); - len = WORD(buf + 0x16); - } else { - if(!checksum(buf, 0x0F)) - return 0; - base = DWORD(buf + 0x08); - len = WORD(buf + 0x06); - } - - u8 *buff; - - if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { - //. Part 1. -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", len, dumpfile); -#endif - write_dump(32, len, buff, dumpfile, 0); - free(buff); - - //. Part 2. - if(mode != LEGACY) { - u8 crafted[32]; - - memcpy(crafted, buf, 32); - overwrite_dmi_address(crafted + 0x10); -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); -#endif - write_dump(0, crafted[0x05], crafted, dumpfile, 1); - } else { - u8 crafted[16]; - - memcpy(crafted, buf, 16); - overwrite_dmi_address(crafted); -#ifdef NDEBUG - printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); -#endif - 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); - if(!found) { - ret = -1; - } - } - - return ret == 0 ? found : ret; -} - dmi_codes_major *find_dmiMajor(const struct dmi_header *h) { @@ -5200,44 +5081,3 @@ int legacy_decode(int type, u8 *buf, const char *devmem, xmlNode *xmlnode) return check; } -/******************************************************************************* -** Probe for EFI interface -*/ -int address_from_efi(size_t * address) -{ - FILE *efi_systab; - const char *filename; - char linebuf[64]; - int ret; - - *address = 0; /* Prevent compiler warning */ - - /* - ** Linux <= 2.6.6: /proc/efi/systab - ** Linux >= 2.6.7: /sys/firmware/efi/systab - */ - if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL - && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { - /* No EFI interface, fallback to memory scan */ - return EFI_NOT_FOUND; - } - ret = EFI_NO_SMBIOS; - while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { - char *addrp = strchr(linebuf, '='); - - *(addrp++) = '\0'; - if(strcmp(linebuf, "SMBIOS") == 0) { - *address = strtoul(addrp, NULL, 0); - printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); - ret = 0; - break; - } - } - if(fclose(efi_systab) != 0) - perror(filename); - - if(ret == EFI_NO_SMBIOS) - fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); - - return ret; -} diff --git a/src/dmidecode.h b/src/dmidecode.h index 81cd249..10412c6 100644 --- a/src/dmidecode.h +++ b/src/dmidecode.h @@ -31,7 +31,6 @@ struct dmi_header { void dmi_dump(xmlNode *node, struct dmi_header * h); xmlNode *dmi_decode(xmlNode *parent_n, dmi_codes_major *dmiMajor, struct dmi_header * h, u16 ver); -int address_from_efi(size_t * address); void to_dmi_header(struct dmi_header *h, u8 * data); xmlNode *smbios_decode_get_version(u8 * buf, const char *devmem); @@ -43,6 +42,3 @@ const char *dmi_string(const struct dmi_header *dm, u8 s); void dmi_system_uuid(xmlNode *node, const u8 * p, u16 ver); void dmi_chassis_type(xmlNode *node, 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/src/dmidecodemodule.c b/src/dmidecodemodule.c index 7e7d0a3..1f37dc3 100644 --- a/src/dmidecodemodule.c +++ b/src/dmidecodemodule.c @@ -49,6 +49,7 @@ #include "dmixml.h" #include "dmierror.h" #include "version.h" +#include "dmidump.h" #include <mcheck.h> static void init(options *opt) @@ -567,7 +568,7 @@ static PyObject *dmidecode_dump(PyObject * self, PyObject * null) stat(f, &_buf); if( (access(f, F_OK) != 0) || ((access(f, W_OK) == 0) && S_ISREG(_buf.st_mode)) ) { - if( dump(f) ) { + if( dump(DEFAULT_MEM_DEV, f) ) { Py_RETURN_TRUE; } } diff --git a/src/dmidump.c b/src/dmidump.c new file mode 100644 index 0000000..4ecbb4d --- /dev/null +++ b/src/dmidump.c @@ -0,0 +1,155 @@ +/* Simple program for dumping DMI/SMBIOS data + * Based on code from python-dmidecode/dmidecode.c + * + * Copyright 2009 David Sommerseth <davids@redhat.com> + * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org> + * Copyright 2000-2002 Alan Cox <alan@redhat.com> + * + * + * 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. + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "types.h" +#include "util.h" + +#include "dmidump.h" +#include "efi.h" + +/* + * 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 dumpling(u8 * buf, const char *dumpfile, u8 mode) +{ + u32 base; + u16 len; + + if(mode == NON_LEGACY) { + if(!checksum(buf, buf[0x05]) || !memcmp(buf + 0x10, "_DMI_", 5) == 0 || + !checksum(buf + 0x10, 0x0F)) + return 0; + base = DWORD(buf + 0x18); + len = WORD(buf + 0x16); + } else { + if(!checksum(buf, 0x0F)) + return 0; + base = DWORD(buf + 0x08); + len = WORD(buf + 0x06); + } + + u8 *buff; + + if((buff = mem_chunk(base, len, DEFAULT_MEM_DEV)) != NULL) { + //. Part 1. +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", len, dumpfile); +#endif + write_dump(32, len, buff, dumpfile, 0); + free(buff); + + //. Part 2. + if(mode != LEGACY) { + u8 crafted[32]; + + memcpy(crafted, buf, 32); + overwrite_dmi_address(crafted + 0x10); +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", crafted[0x05], dumpfile); +#endif + write_dump(0, crafted[0x05], crafted, dumpfile, 1); + } else { + u8 crafted[16]; + + memcpy(crafted, buf, 16); + overwrite_dmi_address(crafted); +#ifdef NDEBUG + printf("# Writing %d bytes to %s.\n", 0x0F, dumpfile); +#endif + write_dump(0, 0x0F, crafted, dumpfile, 1); + } + } else { + fprintf(stderr, "Failed to read table, sorry.\n"); + } + + //. TODO: Cleanup + return 1; +} + + +int dump(const char *memdev, 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, memdev)) != 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, memdev)) == NULL) + ret = -1; + else if(dumpling(buf, dumpfile, NON_LEGACY)) + found++; + } + + if(ret == 0) { + free(buf); + if(!found) { + ret = -1; + } + } + + return ret == 0 ? found : ret; +} +#endif diff --git a/src/dmidump.h b/src/dmidump.h new file mode 100644 index 0000000..3c12248 --- /dev/null +++ b/src/dmidump.h @@ -0,0 +1,37 @@ +/* Simple program for dumping DMI/SMBIOS data + * Based on code from python-dmidecode/dmidecode.c + * + * Copyright 2009 David Sommerseth <davids@redhat.com> + * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org> + * Copyright 2000-2002 Alan Cox <alan@redhat.com> + * + * + * 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. + */ + +#ifndef _DMIDUMP_H + +#define NON_LEGACY 0 +#define LEGACY 1 + +int dump(const char *memdev, const char *dumpfile); + +#endif diff --git a/src/efi.c b/src/efi.c new file mode 100644 index 0000000..9802171 --- /dev/null +++ b/src/efi.c @@ -0,0 +1,83 @@ +/* + * Copyright 2009 David Sommerseth <davids@redhat.com> + * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org> + * Copyright 2000-2002 Alan Cox <alan@redhat.com> + * + * + * 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "efi.h" + +/** + * @file xmlpythonizer.c + * @brief Helper function for EFI support + * @author Jean Delvare <khali@linux-fr.org> + * @author Alan Cox <alan@redhat.com> + */ + +/** + * Probe for EFI interface + * @param size_t* + * @return returns EFI_NOT_FOUND or EFI_NO_SMBIOS + */ +int address_from_efi(size_t * address) +{ + FILE *efi_systab; + const char *filename; + char linebuf[64]; + int ret; + + *address = 0; /* Prevent compiler warning */ + + /* + ** Linux <= 2.6.6: /proc/efi/systab + ** Linux >= 2.6.7: /sys/firmware/efi/systab + */ + if((efi_systab = fopen(filename = "/sys/firmware/efi/systab", "r")) == NULL + && (efi_systab = fopen(filename = "/proc/efi/systab", "r")) == NULL) { + /* No EFI interface, fallback to memory scan */ + return EFI_NOT_FOUND; + } + ret = EFI_NO_SMBIOS; + while((fgets(linebuf, sizeof(linebuf) - 1, efi_systab)) != NULL) { + char *addrp = strchr(linebuf, '='); + + *(addrp++) = '\0'; + if(strcmp(linebuf, "SMBIOS") == 0) { + *address = strtoul(addrp, NULL, 0); + printf("# SMBIOS entry point at 0x%08lx\n", (unsigned long)*address); + ret = 0; + break; + } + } + if(fclose(efi_systab) != 0) + perror(filename); + + if(ret == EFI_NO_SMBIOS) + fprintf(stderr, "%s: SMBIOS entry point missing\n", filename); + + return ret; +} + diff --git a/src/efi.h b/src/efi.h new file mode 100644 index 0000000..240fb01 --- /dev/null +++ b/src/efi.h @@ -0,0 +1,35 @@ +/* + * Copyright 2009 David Sommerseth <davids@redhat.com> + * Copyright 2002-2008 Jean Delvare <khali@linux-fr.org> + * Copyright 2000-2002 Alan Cox <alan@redhat.com> + * + * + * 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. + */ + +#ifndef _EFI_H +#define _EFI_H +#define EFI_NOT_FOUND (-1) +#define EFI_NO_SMBIOS (-2) + +int address_from_efi(size_t * address); + +#endif diff --git a/src/setup-dbg.py b/src/setup-dbg.py index 38ba6df..4077eaf 100644 --- a/src/setup-dbg.py +++ b/src/setup-dbg.py @@ -68,7 +68,9 @@ setup( "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", - "src/xmlpythonizer.c" + "src/xmlpythonizer.c", + "src/efi.c", + "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, diff --git a/src/setup.py b/src/setup.py index a8ab032..75be21b 100644 --- a/src/setup.py +++ b/src/setup.py @@ -68,7 +68,9 @@ setup( "src/dmidecode.c", "src/dmixml.c", "src/dmierror.c", - "src/xmlpythonizer.c" + "src/xmlpythonizer.c", + "src/efi.c", + "src/dmidump.c" ], include_dirs = incdir, library_dirs = libdir, |