summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorGordon Willem Klok <gwk@cvs.openbsd.org>2006-05-19 04:49:18 +0000
committerGordon Willem Klok <gwk@cvs.openbsd.org>2006-05-19 04:49:18 +0000
commit1680cee234b9729971e5d38d2cfb6d5a01334ecf (patch)
tree705ba781dbce915199d85a3f991227102745dc37 /sys
parente7089e4cecc151618db90764e4c2bf9649b535ab (diff)
Smbios cleanup
Improve the heuristics a little and extend them to the version and serial number fields. Clean the strings of leading/trailing space and deal with strings which consist entirely of space. Use fixed buffers for strings instead of using pointers into the table. ok deraadt@, and tested by many.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/bios.c108
-rw-r--r--sys/arch/amd64/include/smbiosvar.h4
-rw-r--r--sys/arch/i386/i386/bios.c104
-rw-r--r--sys/arch/i386/include/smbiosvar.h2
4 files changed, 146 insertions, 72 deletions
diff --git a/sys/arch/amd64/amd64/bios.c b/sys/arch/amd64/amd64/bios.c
index 6557d0d670d..63090800f13 100644
--- a/sys/arch/amd64/amd64/bios.c
+++ b/sys/arch/amd64/amd64/bios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bios.c,v 1.7 2006/05/11 23:22:13 deraadt Exp $ */
+/* $OpenBSD: bios.c,v 1.8 2006/05/19 04:49:17 gwk Exp $ */
/*
* Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca>
*
@@ -39,6 +39,7 @@ struct bios_softc {
void smbios_info(char *);
int bios_match(struct device *, void *, void *);
void bios_attach(struct device *, struct device *, void *);
+char *fixstring(char *);
struct cfattach bios_ca = {
sizeof(struct bios_softc), bios_match, bios_attach
@@ -56,7 +57,9 @@ extern char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
const char *smbios_uninfo[] = {
"System",
- "Not Specified"
+ "Not ",
+ "To be",
+ "SYS-"
};
int
@@ -185,7 +188,7 @@ smbios_find_table(u_int8_t type, struct smbtable *st)
}
char *
-smbios_get_string(struct smbtable *st, u_int8_t indx)
+smbios_get_string(struct smbtable *st, u_int8_t indx, char *dest, size_t len)
{
u_int8_t *va, *end;
char *ret = NULL;
@@ -196,26 +199,61 @@ smbios_get_string(struct smbtable *st, u_int8_t indx)
for (i = 1; va < end && i < indx && *va; i++)
while (*va++)
;
- if (i == indx)
- ret = (char *)va;
+ if (i == indx) {
+ if (va + len < end) {
+ ret = dest;
+ bcopy(va, ret, len);
+ ret[len-1] = '\0';
+ }
+ }
return ret;
}
+char *
+fixstring(char *s)
+{
+ char *p, *e;
+ int i;
+
+ for (i = 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]); i++)
+ if ((strncmp(s, smbios_uninfo[i], strlen(smbios_uninfo[i])))==0)
+ return NULL;
+ /*
+ * Remove leading and trailing whitespace
+ */
+ for (p = s; *p == ' '; p++)
+ ;
+ /*
+ * Special case entire string is whitespace
+ */
+ if (p == s + strlen(s))
+ return NULL;
+ for (e = s + strlen(s) - 1; e > s && *e == ' '; e--)
+ ;
+ if (p > s || e < s + strlen(s) - 1) {
+ bcopy(p, s, e-p + 1);
+ s[e - p + 1] = '\0';
+ }
+
+ return s;
+}
+
void
-smbios_info(char * str)
+smbios_info(char* str)
{
+ static char vend[40], prod[30], ver[30], ser[20];
struct smbtable stbl, btbl;
struct smbios_sys *sys;
struct smbios_board *board;
int i, uuidf, havebb;
+ char *p;
if (smbios_entry.mjr < 2)
return;
/*
- * According to the spec the system table among others are required to
- * be present, if it is not we dont bother with this smbios
- * implementation.
+ * According to the spec the system table among others is required,
+ * if it is not we do not bother with this smbios implementation.
*/
stbl.cookie = btbl.cookie = 0;
if (!smbios_find_table(SMBIOS_TYPE_SYSTEM, &stbl))
@@ -233,36 +271,36 @@ smbios_info(char * str)
* perhaps naieve belief that motherboard vendors will supply this
* information.
*/
- if ((hw_vendor = smbios_get_string(&stbl, sys->vendor)) != NULL) {
- for (i = 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]);
- i++) {
- if ((strncmp(hw_vendor, smbios_uninfo[i],
- strlen(smbios_uninfo[i]))) == 0) {
- if (havebb)
- hw_vendor = smbios_get_string(&btbl,
- board->vendor);
- break;
- }
+ if ((p = smbios_get_string(&stbl, sys->vendor, vend, sizeof(vend))) !=
+ NULL)
+ hw_vendor = fixstring(p);
+ if (hw_vendor == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->vendor, vend,
+ sizeof(vend))) != NULL)
+ hw_vendor = fixstring(p);
}
- } else
- hw_vendor = smbios_get_string(&btbl, board->vendor);
- if ((hw_prod = smbios_get_string(&stbl, sys->product)) != NULL) {
- for (i = 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]);
- i++) {
- if ((strncmp(hw_prod, smbios_uninfo[i],
- strlen(smbios_uninfo[i]))) == 0) {
- if (havebb)
- hw_prod = smbios_get_string(&btbl,
- board->product);
- break;
- }
+ }
+ if ((p = smbios_get_string(&stbl, sys->product, prod, sizeof(prod))) !=
+ NULL)
+ hw_prod = fixstring(p);
+ if (hw_prod == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->product, prod,
+ sizeof(prod))) != NULL)
+ hw_prod = fixstring(p);
}
- } else
- hw_prod = smbios_get_string(&btbl, board->product);
+ }
if (hw_vendor != NULL && hw_prod != NULL)
printf("\n%s: %s %s", str, hw_vendor, hw_prod);
- hw_ver = smbios_get_string(&stbl, sys->version);
- hw_serial = smbios_get_string(&stbl, sys->serial);
+ if ((p = smbios_get_string(&stbl, sys->version, ver, sizeof(ver))) !=
+ NULL) {
+ hw_ver = fixstring(p);
+ }
+ if ((p = smbios_get_string(&stbl, sys->serial, ser, sizeof(ser))) !=
+ NULL) {
+ hw_serial = fixstring(p);
+ }
if (smbios_entry.mjr > 2 || (smbios_entry.mjr == 2 &&
smbios_entry.min >= 1)) {
/*
diff --git a/sys/arch/amd64/include/smbiosvar.h b/sys/arch/amd64/include/smbiosvar.h
index 370e3a76580..7f60d238a9a 100644
--- a/sys/arch/amd64/include/smbiosvar.h
+++ b/sys/arch/amd64/include/smbiosvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: smbiosvar.h,v 1.2 2006/05/10 01:39:04 krw Exp $ */
+/* $OpenBSD: smbiosvar.h,v 1.3 2006/05/19 04:49:17 gwk Exp $ */
/*
* Copyright (c) 2006 Gordon Willem Klok <gklok@cogeco.ca>
* Copyright (c) 2005 Jordan Hargrave
@@ -202,6 +202,6 @@ struct smbios_ipmi {
} __packed;
int smbios_find_table(u_int8_t, struct smbtable *);
-char * smbios_get_string(struct smbtable *, u_int8_t);
+char *smbios_get_string(struct smbtable *, u_int8_t, char *, size_t);
#endif
diff --git a/sys/arch/i386/i386/bios.c b/sys/arch/i386/i386/bios.c
index e3d9d4e8ceb..d34c1e2fcd0 100644
--- a/sys/arch/i386/i386/bios.c
+++ b/sys/arch/i386/i386/bios.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bios.c,v 1.63 2006/05/11 23:19:36 deraadt Exp $ */
+/* $OpenBSD: bios.c,v 1.64 2006/05/19 04:49:17 gwk Exp $ */
/*
* Copyright (c) 1997-2001 Michael Shalayeff
@@ -68,6 +68,7 @@ struct bios_softc {
int biosprobe(struct device *, void *, void *);
void biosattach(struct device *, struct device *, void *);
int bios_print(void *, const char *);
+char *fixstring(char *);
struct cfattach bios_ca = {
sizeof(struct bios_softc), biosprobe, biosattach
@@ -104,7 +105,9 @@ bios_diskinfo_t *bios_getdiskinfo(dev_t);
extern char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
const char *smbios_uninfo[] = {
"System",
- "Not Specified"
+ "Not ",
+ "To be",
+ "SYS-"
};
@@ -680,7 +683,7 @@ smbios_find_table(u_int8_t type, struct smbtable *st)
}
char *
-smbios_get_string(struct smbtable *st, u_int8_t indx)
+smbios_get_string(struct smbtable *st, u_int8_t indx, char *dest, size_t len)
{
u_int8_t *va, *end;
char *ret = NULL;
@@ -691,26 +694,61 @@ smbios_get_string(struct smbtable *st, u_int8_t indx)
for (i = 1; va < end && i < indx && *va; i++)
while (*va++)
;
- if (i == indx)
- ret = (char *)va;
+ if (i == indx) {
+ if (va + len < end) {
+ ret = dest;
+ bcopy(va, ret, len);
+ ret[len - 1] = '\0';
+ }
+ }
return ret;
}
+char *
+fixstring(char *s)
+{
+ char *p, *e;
+ int i;
+
+ for (i= 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]); i++)
+ if ((strncmp(s, smbios_uninfo[i], strlen(smbios_uninfo[i])))==0)
+ return NULL;
+ /*
+ * Remove leading and trailing whitespace
+ */
+ for (p = s; *p == ' '; p++)
+ ;
+ /*
+ * Special case entire string is whitespace
+ */
+ if (p == s + strlen(s))
+ return NULL;
+ for (e = s + strlen(s) - 1; e > s && *e == ' '; e--)
+ ;
+ if (p > s || e < s + strlen(s) - 1) {
+ bcopy(p, s, e-p + 1);
+ s[e - p + 1] = '\0';
+ }
+
+ return s;
+}
+
void
smbios_info(char * str)
{
+ static char vend[40], prod[30], ver[30], ser[20];
struct smbtable stbl, btbl;
struct smbios_sys *sys;
struct smbios_board *board;
int i, uuidf, havebb;
+ char *p;
if (smbios_entry.mjr < 2)
return;
/*
- * According to the spec the system table among others are required to
- * be present, if it is not we dont bother with this smbios
- * implementation.
+ * According to the spec the system table among others is required,
+ * if it is not we do not bother with this smbios implementation.
*/
stbl.cookie = btbl.cookie = 0;
if (!smbios_find_table(SMBIOS_TYPE_SYSTEM, &stbl))
@@ -728,36 +766,34 @@ smbios_info(char * str)
* perhaps naieve belief that motherboard vendors will supply this
* information.
*/
- if ((hw_vendor = smbios_get_string(&stbl, sys->vendor)) != NULL) {
- for (i = 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]);
- i++) {
- if ((strncmp(hw_vendor, smbios_uninfo[i],
- strlen(smbios_uninfo[i]))) == 0) {
- if (havebb)
- hw_vendor = smbios_get_string(&btbl,
- board->vendor);
- break;
- }
+ if ((p = smbios_get_string(&stbl, sys->vendor, vend, sizeof(vend))) !=
+ NULL)
+ hw_vendor = fixstring(p);
+ if (hw_vendor == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->vendor, vend,
+ sizeof(vend))) != NULL)
+ hw_vendor = fixstring(p);
}
- } else
- hw_vendor = smbios_get_string(&btbl, board->vendor);
- if ((hw_prod = smbios_get_string(&stbl, sys->product)) != NULL) {
- for (i = 0; i < sizeof(smbios_uninfo)/sizeof(smbios_uninfo[0]);
- i++) {
- if ((strncmp(hw_prod, smbios_uninfo[i],
- strlen(smbios_uninfo[i]))) == 0) {
- if (havebb)
- hw_prod = smbios_get_string(&btbl,
- board->product);
- break;
- }
+ }
+ if ((p = smbios_get_string(&stbl, sys->product, prod, sizeof(prod))) !=
+ NULL)
+ hw_prod = fixstring(p);
+ if (hw_prod == NULL) {
+ if (havebb) {
+ if ((p = smbios_get_string(&btbl, board->product, prod,
+ sizeof(prod))) != NULL)
+ hw_prod = fixstring(p);
}
- } else
- hw_prod = smbios_get_string(&btbl, board->product);
+ }
if (hw_vendor != NULL && hw_prod != NULL)
printf("\n%s: %s %s", str, hw_vendor, hw_prod);
- hw_ver = smbios_get_string(&stbl, sys->version);
- hw_serial = smbios_get_string(&stbl, sys->serial);
+ if ((p = smbios_get_string(&stbl, sys->version, ver, sizeof(ver))) !=
+ NULL)
+ hw_ver = fixstring(p);
+ if ((p = smbios_get_string(&stbl, sys->serial, ser, sizeof(ser))) !=
+ NULL)
+ hw_serial = fixstring(p);
if (smbios_entry.mjr > 2 || (smbios_entry.mjr == 2 &&
smbios_entry.min >= 1)) {
/*
diff --git a/sys/arch/i386/include/smbiosvar.h b/sys/arch/i386/include/smbiosvar.h
index 5c9392c642e..6ccf7efe8bd 100644
--- a/sys/arch/i386/include/smbiosvar.h
+++ b/sys/arch/i386/include/smbiosvar.h
@@ -201,6 +201,6 @@ struct smbios_ipmi {
} __packed;
int smbios_find_table(u_int8_t, struct smbtable *);
-char * smbios_get_string(struct smbtable *, u_int8_t);
+char *smbios_get_string(struct smbtable *, u_int8_t, char *, size_t);
#endif