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 2011-01-22 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>
58 #define SMBIOS_MAX_SIZE 4096
59 #define SMBIOS_MAX_HANDLE 0x50
60 #define DMIDECODE_PATH "/usr/sbin/dmidecode"
61 #define DMIDECODE "dmidecode"
64 * dmidecode --dump-bin dmidecode.bin
66 int genSmbiosFileByDmidecode(char * filename) {
71 /* must be a root user */
73 // DEBUG("UID %d\n",uid);
75 DEBUG("must be a root user to run dmidecode\n");
87 execl(DMIDECODE_PATH, DMIDECODE, "--dump-bin", filename, NULL);
93 waitpid(pid, &status, 0);
94 // DEBUG("status = %d\n", status);
95 if (WIFEXITED(status)) {
97 TODO("Exit status %d\n", WEXITSTATUS(status));
99 } else if (WIFSIGNALED(status)) {
100 ERROR("Signal status %d\n", WIFSIGNALED(status));
115 * dmidecode --dump-bin dmidecode.bin
117 * SMBIOS data -> malloc -> data
120 int readSmbiosFile(char * filename, BYTE **data, int *len) {
124 int rc = PTS_SUCCESS;
126 buf = xmalloc(SMBIOS_MAX_SIZE); // TODO check the filesize
131 if ((fp = fopen(filename, "rb")) == NULL) {
132 ERROR("%s missing\n", filename);
133 rc = PTS_INTERNAL_ERROR;
137 size = fread(buf, 1, SMBIOS_MAX_SIZE, fp); // TODO(munetoh) check the file size
153 * http://en.wikipedia.org/wiki/System_Management_BIOS
154 * http://dmtf.org/standards/smbios
156 * Lenovo - sensitive data of SMBIOS in IML is masked
158 int printSmbios(BYTE *data, int length) {
165 BYTE *eod = data + length;
170 if ((ptr[0] == 0x5f) && (ptr[1] == 0x53) && (ptr[2] == 0x4d) && (ptr[3] == 0x5f)) {
172 str_length = ptr[0x16] + (ptr[0x17]<<8);
173 str_num = ptr[0x1C] + (ptr[0x1D]<<8);
174 printf(NLS(MS_OPENPTS, OPENPTS_SMBIOS_STRUCTURES,
175 "%d structures occupying %d bytes.\n"), str_num, str_length);
176 eod = ptr + str_length + 32;
186 handle = ptr[2] + ptr[3]*256;
187 printf(NLS(MS_OPENPTS, OPENPTS_SMBIOS_HANDLE,
188 "Handle 0x%04x, DMI type %d(0x%x), %d bytes\n"), handle, type, type, len);
189 printHex(NLS(MS_OPENPTS, OPENPTS_SMBIOS_HEAD, " head"), ptr, len, "\n");
192 printf(NLS(MS_OPENPTS, OPENPTS_SMBIOS_END_OF_TABLE, "End Of Table\n"));
193 // printf("%ld\n", ptr - data);
200 if (handle != handle_old +1) {
205 printf(NLS(MS_OPENPTS, OPENPTS_SMBIOS_END_OF_TABLE, "End Of Table\n"));
210 while (!((*ptr == 0) && (*(ptr+1) == 0) && (*(ptr + 2) != 0))) {
219 printHex(NLS(MS_OPENPTS, OPENPTS_SMBIOS_BODY, " body"), strings, ptr - strings, "\n");
227 if (cnt > SMBIOS_MAX_HANDLE) {
239 #define SMBIOS_MAX_HANDLE 0x50
241 * SMBIOS -> properties
243 * IR:core:ComponentID < Core Integrity Schema 3.1.2
244 * ---------------------------------------
251 * VersionMajor bios.version.major=3
252 * VersionMinor bios.version.minor=8
253 * VersionBuild bios.date=08/20/2009
254 * VersionString bios.version=6DET58WW (3.08 )
258 * ----------------------------------------
260 * ---------------------------------------
261 * Name bios.vendor.name=LENOVO
263 * IR:core:SmiVendorID bios.vendor.smi=19046 << IANA.ORG
264 * ---------------------------------------
266 * # => PTS_ComponentId
269 int parseSmbios(OPENPTS_CONTEXT *ctx, BYTE *data, int length) {
275 BYTE *strings[10]; // TODO size
276 BYTE *eod = data + length;
281 OPENPTS_CONFIG *conf = ctx->conf;
284 if ((ptr[0] == 0x5f) && (ptr[1] == 0x53) && (ptr[2] == 0x4d) && (ptr[3] == 0x5f)) {
286 str_length = ptr[0x16] + (ptr[0x17]<<8);
287 // str_num = ptr[0x1C] + (ptr[0x1D]<<8);
288 // printf("%d structures occupying %d bytes.\n", str_num, str_length);
289 eod = ptr + str_length + 32;
298 /* walk on structures */
302 handle = ptr[2] + ptr[3]*256;
303 // printf("Handle 0x%04x, DMI type %d(0x%x), %d bytes\n", handle, type,type, len);
304 // printHex(" head",ptr, len, "\n");
307 // printf("End Of Table\n");
308 // printf("%ld\n", ptr - data);
316 if (handle != handle_old +1) {
321 // printf("End Of Table\n");
326 while (!((*ptr == 0) && (*(ptr+1) == 0) && (*(ptr + 2) != 0))) {
331 if ((*ptr != 0) && (*(ptr+1) == 0)) {
332 scnt++; // TODO check max
333 strings[scnt] = ptr + 2;
339 // printHex(" body", strings[0], ptr - strings[0], "\n");
340 // printf(" scnt %d\n",scnt);
341 // for (i=0;i<scnt;i++) {
342 // printf(" %d %s\n",i, strings[i]);
347 case 0x0: /* BIOS Information */
348 conf->bios_vendor = smalloc_assert((char*)strings[0]);
349 conf->bios_version = smalloc_assert((char*)strings[1]);
361 if (cnt > SMBIOS_MAX_HANDLE) {