mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-10 18:47:22 +00:00
Add support for IBM OEM SEL messages
This commit is contained in:
parent
5532b6856e
commit
fa8c8116e1
@ -4,6 +4,7 @@ version 1.8.7
|
||||
* Increase argument size for raw commands in shell/exec
|
||||
* Fix handling of LUNs for LAN interfaces
|
||||
* Add IPMIv2 SOL loopback test
|
||||
* Add support for IBM OEM SEL messages
|
||||
|
||||
version 1.8.6
|
||||
* Fix memory corruption when sending encrypted SOL traffic
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <ipmitool/helper.h>
|
||||
|
||||
static int ipmi_oem_supermicro(struct ipmi_intf * intf);
|
||||
static int ipmi_oem_ibm(struct ipmi_intf * intf);
|
||||
|
||||
static struct ipmi_oem_handle ipmi_oem_list[] = {
|
||||
{
|
||||
@ -56,6 +57,11 @@ static struct ipmi_oem_handle ipmi_oem_list[] = {
|
||||
name: "icts",
|
||||
desc: "IPMI 2.0 ICTS compliance support",
|
||||
},
|
||||
{
|
||||
name: "ibm",
|
||||
desc: "IBM OEM support",
|
||||
setup: ipmi_oem_ibm,
|
||||
},
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
@ -67,6 +73,13 @@ ipmi_oem_supermicro(struct ipmi_intf * intf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ipmi_oem_ibm(struct ipmi_intf * intf)
|
||||
{
|
||||
ipmi_oem_ibm_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ipmi_oem_print - print list of OEM handles
|
||||
*/
|
||||
void
|
||||
|
@ -49,6 +49,148 @@ extern int verbose;
|
||||
|
||||
static int sel_extended = 0;
|
||||
|
||||
static FILE * fp;
|
||||
static int oem_ibm_nrecs = 0;
|
||||
struct ipmi_oem_ibm_msg_rec {
|
||||
int value[14];
|
||||
char *string[14];
|
||||
char *text;
|
||||
} *oem_ibm_msg;
|
||||
|
||||
#define SEL_BYTE(n) (n-3) /* So we can refer to byte positions in log entries (byte 3 is at index 0, etc) */
|
||||
|
||||
/*
|
||||
* Reads values found in message translation file. XX is a wildcard, R means reserved.
|
||||
* Returns -1 for XX, -2 for R, -3 for non-hex (string), or positive integer from a hex value.
|
||||
*/
|
||||
static int ipmi_oem_ibm_readval(char *str)
|
||||
{
|
||||
int ret;
|
||||
if (!strcmp(str, "XX")) {
|
||||
return -1;
|
||||
}
|
||||
if (!strcmp(str, "R")) {
|
||||
return -2;
|
||||
}
|
||||
if (sscanf(str, "0x%x", &ret) != 1) {
|
||||
return -3;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is where the magic happens. SEL_BYTE is a bit ugly, but it allows
|
||||
* reference to byte positions instead of array indexes which (hopefully)
|
||||
* helps make the code easier to read.
|
||||
*/
|
||||
static int ipmi_oem_ibm_match(uint8_t *evt, struct ipmi_oem_ibm_msg_rec rec)
|
||||
{
|
||||
if (evt[2] == rec.value[SEL_BYTE(3)] &&
|
||||
((rec.value[SEL_BYTE(4)] < 0) || (evt[3] == rec.value[SEL_BYTE(4)])) &&
|
||||
((rec.value[SEL_BYTE(5)] < 0) || (evt[4] == rec.value[SEL_BYTE(5)])) &&
|
||||
((rec.value[SEL_BYTE(6)] < 0) || (evt[5] == rec.value[SEL_BYTE(6)])) &&
|
||||
((rec.value[SEL_BYTE(7)] < 0) || (evt[6] == rec.value[SEL_BYTE(7)])) &&
|
||||
((rec.value[SEL_BYTE(11)] < 0) || (evt[10] == rec.value[SEL_BYTE(11)])) &&
|
||||
((rec.value[SEL_BYTE(12)] < 0) || (evt[11] == rec.value[SEL_BYTE(12)]))) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ipmi_oem_ibm_init(void)
|
||||
{
|
||||
FILE * fp;
|
||||
int i, j, k, n, byte;
|
||||
char *filename;
|
||||
char buf[15][150];
|
||||
|
||||
if ((filename = getenv("IPMI_OEM_IBM_DATAFILE")) == NULL) {
|
||||
printf ("Unable to read IPMI_OEM_IBM_DATAFILE from environment\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
printf ("could not open %s file\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* count number of records (lines) in input file */
|
||||
oem_ibm_nrecs = 0;
|
||||
while (fscanf(fp, "%*[^\n]\n", buf[0]) == 0) {
|
||||
oem_ibm_nrecs++;
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
oem_ibm_msg = (struct ipmi_oem_ibm_msg_rec *)calloc(oem_ibm_nrecs,
|
||||
sizeof(struct ipmi_oem_ibm_msg_rec));
|
||||
|
||||
for (i=0; i < oem_ibm_nrecs; i++) {
|
||||
n=fscanf(fp, "\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
|
||||
"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
|
||||
"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\"%[^\"]\",\""
|
||||
"%[^\"]\",\"%[^\"]\",\"%[^\"]\"\n",
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
|
||||
buf[6], buf[7], buf[8], buf[9], buf[10], buf[11],
|
||||
buf[12], buf[13], buf[14]);
|
||||
|
||||
if (n != 15) {
|
||||
printf ("Encountered problems reading line %d of %s\n",
|
||||
i+1, filename);
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
oem_ibm_nrecs = 0;
|
||||
/* free all the memory allocated so far */
|
||||
for (j=0; j<i ; j++) {
|
||||
for (k=3; k<17; k++) {
|
||||
if (oem_ibm_msg[j].value[SEL_BYTE(k)] == -3) {
|
||||
free(oem_ibm_msg[j].string[SEL_BYTE(k)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
free (oem_ibm_msg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (byte = 3; byte < 17; byte++) {
|
||||
if ((oem_ibm_msg[i].value[SEL_BYTE(byte)] =
|
||||
ipmi_oem_ibm_readval(buf[SEL_BYTE(byte)])) == -3) {
|
||||
oem_ibm_msg[i].string[SEL_BYTE(byte)] =
|
||||
(char *)malloc(strlen(buf[SEL_BYTE(byte)]) + 1);
|
||||
strcpy(oem_ibm_msg[i].string[SEL_BYTE(byte)],
|
||||
buf[SEL_BYTE(byte)]);
|
||||
}
|
||||
}
|
||||
oem_ibm_msg[i].text = (char *)malloc(strlen(buf[SEL_BYTE(17)]) + 1);
|
||||
strcpy(oem_ibm_msg[i].text, buf[SEL_BYTE(17)]);
|
||||
}
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
}
|
||||
|
||||
static void ipmi_oem_ibm_message(struct sel_event_record * evt, int verbose)
|
||||
{
|
||||
/*
|
||||
* Note: although we have a verbose argument, currently the output
|
||||
* isn't affected by it.
|
||||
*/
|
||||
int i, j;
|
||||
|
||||
for (i=0; i < oem_ibm_nrecs; i++) {
|
||||
if (ipmi_oem_ibm_match((uint8_t *)evt, oem_ibm_msg[i])) {
|
||||
printf (csv_output ? ",\"%s\"" : " | %s", oem_ibm_msg[i].text);
|
||||
for (j=4; j<17; j++) {
|
||||
if (oem_ibm_msg[i].value[SEL_BYTE(j)] == -3) {
|
||||
printf (csv_output ? ",%s=0x%x" : " %s = 0x%x",
|
||||
oem_ibm_msg[i].string[SEL_BYTE(j)],
|
||||
((uint8_t *)evt)[SEL_BYTE(j)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const struct valstr event_dir_vals[] = {
|
||||
{ 0, "Assertion Event" },
|
||||
{ 1, "Deassertion Event" },
|
||||
@ -324,7 +466,6 @@ get_newisys_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
|
||||
{
|
||||
@ -740,6 +881,7 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
|
||||
for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++)
|
||||
printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]);
|
||||
}
|
||||
ipmi_oem_ibm_message(evt, 0);
|
||||
printf ("\n");
|
||||
return;
|
||||
}
|
||||
@ -912,6 +1054,7 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
|
||||
for(data_count=0;data_count < SEL_OEM_NOTS_DATA_LEN;data_count++)
|
||||
printf("%02x", evt->sel_type.oem_nots_type.oem_defined[data_count]);
|
||||
printf(" [%s]\n\n",hex2ascii (evt->sel_type.oem_nots_type.oem_defined, SEL_OEM_NOTS_DATA_LEN));
|
||||
ipmi_oem_ibm_message(evt, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user