2 * This file is part of the OpenPTS project.
4 * The Initial Developer of the Original Code is International
5 * Business Machines Corporation. Portions created by IBM
6 * Corporation are Copyright (C) 2010 International Business
7 * Machines Corporation. All Rights Reserved.
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the Common Public License as published by
11 * IBM Corporation; either version 1 of the License, or (at your option)
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * Common Public License for more details.
19 * You should have received a copy of the Common Public License
20 * along with this program; if not, a copy can be viewed at
21 * http://www.opensource.org/licenses/cpl1.0.php.
26 * \brief parse SMBIOS info
27 * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
29 * cleanup 2012-01-05 SM
31 * SMBIOS Info in BIOS IML -> platform properties
33 * TODO not work yet:-(
34 * SMBIOS info in the IML has been masked.
35 * It masks sensitive information in the SMBIOS data blob.
36 * However this makes hard to parse the ASN.1 structure.
45 #include <sys/types.h>
46 #include <sys/socket.h>
48 #include <netinet/in.h>
57 #define SMBIOS_MAX_SIZE 4096
58 #define SMBIOS_MAX_HANDLE 0x50
59 #define DMIDECODE_PATH "/usr/sbin/dmidecode"
60 #define DMIDECODE "dmidecode"
63 * dmidecode --dump-bin dmidecode.bin
65 int genSmbiosFileByDmidecode(char * filename) {
70 /* must be a root user */
73 DEBUG("must be a root user to run dmidecode\n");
80 LOG(LOG_ERR, "fork() fail");
85 execl(DMIDECODE_PATH, DMIDECODE, "--dump-bin", filename, NULL);
91 waitpid(pid, &status, 0);
92 // DEBUG("status = %d\n", status);
93 if (WIFEXITED(status)) {
95 LOG(LOG_TODO, "Exit status %d\n", WEXITSTATUS(status));
96 return PTS_SUCCESS; // 1
97 } else if (WIFSIGNALED(status)) {
98 LOG(LOG_ERR, "Signal status %d\n", WIFSIGNALED(status));
101 LOG(LOG_ERR, "Bad exit");
113 * dmidecode --dump-bin dmidecode.bin
115 * SMBIOS data -> malloc -> data
118 int readSmbiosFile(char * filename, BYTE **data, int *len) {
122 int rc = PTS_SUCCESS;
125 if (filename == NULL) {
126 LOG(LOG_ERR, "null input");
130 // TODO(munetoh) check the file size
131 buf = xmalloc(SMBIOS_MAX_SIZE);
133 LOG(LOG_ERR, "no memory");
137 if ((fp = fopen(filename, "rb")) == NULL) {
138 LOG(LOG_ERR, "%s missing\n", filename);
139 rc = PTS_INTERNAL_ERROR;
143 size = fread(buf, 1, SMBIOS_MAX_SIZE, fp);
159 * http://en.wikipedia.org/wiki/System_Management_BIOS
160 * http://dmtf.org/standards/smbios
162 * Lenovo - sensitive data of SMBIOS in IML is masked
164 int printSmbios(BYTE *data, int length) {
171 BYTE *eod = data + length;
176 if ((ptr[0] == 0x5f) && (ptr[1] == 0x53) && (ptr[2] == 0x4d) && (ptr[3] == 0x5f)) {
178 str_length = ptr[0x16] + (ptr[0x17]<<8);
179 str_num = ptr[0x1C] + (ptr[0x1D]<<8);
180 eod = ptr + str_length + 32;
188 handle = ptr[2] + ptr[3]*256;
198 if (handle != handle_old +1) {
208 while (!((*ptr == 0) && (*(ptr+1) == 0) && (*(ptr + 2) != 0))) {
222 if (cnt > SMBIOS_MAX_HANDLE) {
234 #define SMBIOS_MAX_HANDLE 0x50
236 * SMBIOS -> properties
238 * IR:core:ComponentID < Core Integrity Schema 3.1.2
239 * ---------------------------------------
246 * VersionMajor bios.version.major=3
247 * VersionMinor bios.version.minor=8
248 * VersionBuild bios.date=08/20/2009
249 * VersionString bios.version=6DET58WW (3.08 )
253 * ----------------------------------------
255 * ---------------------------------------
256 * Name bios.vendor.name=LENOVO
258 * IR:core:SmiVendorID bios.vendor.smi=19046 << IANA.ORG
259 * ---------------------------------------
261 * # => PTS_ComponentId
264 int parseSmbios(OPENPTS_CONTEXT *ctx, BYTE *data, int length) {
270 BYTE *strings[10]; // TODO size
271 BYTE *eod = data + length;
275 OPENPTS_CONFIG *conf = ctx->conf;
278 if ((ptr[0] == 0x5f) && (ptr[1] == 0x53) && (ptr[2] == 0x4d) && (ptr[3] == 0x5f)) {
280 str_length = ptr[0x16] + (ptr[0x17]<<8);
281 // str_num = ptr[0x1C] + (ptr[0x1D]<<8);
282 eod = ptr + str_length + 32;
291 /* walk on structures */
295 handle = ptr[2] + ptr[3]*256;
306 if (handle != handle_old +1) {
315 while (!((*ptr == 0) && (*(ptr+1) == 0) && (*(ptr + 2) != 0))) {
320 if ((*ptr != 0) && (*(ptr+1) == 0)) {
321 scnt++; // TODO check max
322 strings[scnt] = ptr + 2;
330 case 0x0: /* BIOS Information */
331 conf->bios_vendor = smalloc_assert((char*)strings[0]);
332 conf->bios_version = smalloc_assert((char*)strings[1]);
344 if (cnt > SMBIOS_MAX_HANDLE) {