summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-09 09:19:51 +0200
committerJörg Frings-Fürst <debian@jff-webhosting.net>2016-10-09 09:19:51 +0200
commit82ac6c87ce0b0af2fb8de25d70442fec406bb742 (patch)
tree74bbca60b73160c432cd497563bf8f8de1ce80ea /lib
parent342ebce798fe98ede64939a49bbc3770d8214649 (diff)
New upstream version 1.8.18upstream/1.8.18
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/Makefile.in6
-rw-r--r--lib/dimm_spd.c22
-rw-r--r--lib/helper.c183
-rw-r--r--lib/ipmi_cfgp.c542
-rw-r--r--lib/ipmi_channel.c3
-rw-r--r--lib/ipmi_chassis.c2
-rw-r--r--lib/ipmi_delloem.c87
-rw-r--r--lib/ipmi_ekanalyzer.c29
-rw-r--r--lib/ipmi_event.c42
-rw-r--r--lib/ipmi_firewall.c10
-rw-r--r--lib/ipmi_fru.c115
-rw-r--r--lib/ipmi_hpmfwupg.c7
-rw-r--r--lib/ipmi_lanp.c100
-rw-r--r--lib/ipmi_lanp6.c1240
-rw-r--r--lib/ipmi_main.c125
-rw-r--r--lib/ipmi_mc.c109
-rw-r--r--lib/ipmi_pef.c1237
-rw-r--r--lib/ipmi_picmg.c10
-rw-r--r--lib/ipmi_sdr.c148
-rw-r--r--lib/ipmi_sel.c330
-rw-r--r--lib/ipmi_sensor.c6
-rw-r--r--lib/ipmi_session.c18
-rw-r--r--lib/ipmi_sol.c10
-rw-r--r--lib/ipmi_strings.c100
-rw-r--r--lib/ipmi_sunoem.c2
26 files changed, 3533 insertions, 951 deletions
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 359cb30..cc69a8f 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -41,6 +41,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
+ ipmi_lanp6.c ipmi_cfgp.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic
diff --git a/lib/Makefile.in b/lib/Makefile.in
index ccb468f..0e2b6b2 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -131,7 +131,8 @@ am_libipmitool_la_OBJECTS = helper.lo ipmi_sdr.lo ipmi_sel.lo \
ipmi_tsol.lo ipmi_firewall.lo ipmi_kontronoem.lo \
ipmi_hpmfwupg.lo ipmi_sdradd.lo ipmi_ekanalyzer.lo \
ipmi_gendev.lo ipmi_ime.lo ipmi_delloem.lo ipmi_dcmi.lo \
- hpm2.lo ipmi_vita.lo ../src/plugins/lan/md5.lo
+ hpm2.lo ipmi_vita.lo ipmi_lanp6.lo ipmi_cfgp.lo \
+ ../src/plugins/lan/md5.lo
libipmitool_la_OBJECTS = $(am_libipmitool_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@@ -362,6 +363,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
+ ipmi_lanp6.c ipmi_cfgp.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic
@@ -436,6 +438,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dimm_spd.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/helper.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hpm2.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_cfgp.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_channel.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_chassis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_dcmi.Plo@am__quote@
@@ -451,6 +454,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_isol.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_kontronoem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_lanp.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_lanp6.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_main.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_mc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipmi_oem.Plo@am__quote@
diff --git a/lib/dimm_spd.c b/lib/dimm_spd.c
index 8b6927c..41e30db 100644
--- a/lib/dimm_spd.c
+++ b/lib/dimm_spd.c
@@ -1340,11 +1340,10 @@ ipmi_spd_print(uint8_t *spd_data, int len)
printf(" Memory Type : %s\n",
val2str(spd_data[2], spd_memtype_vals));
-
+
if (spd_data[2] == 0x0B) /* DDR3 SDRAM */
{
int iPN;
- char *pchPN = spd_data+128;
int sdram_cap = 0;
int pri_bus_width = 0;
int sdram_width = 0;
@@ -1353,7 +1352,7 @@ ipmi_spd_print(uint8_t *spd_data, int len)
if (len < 148)
return -1; /* we need first 91 bytes to do our thing */
-
+
sdram_cap = ldexp(256,(spd_data[4]&15));
pri_bus_width = ldexp(8,(spd_data[8]&7));
@@ -1366,7 +1365,7 @@ ipmi_spd_print(uint8_t *spd_data, int len)
printf(" SDRAM Device Width : %d bits\n", sdram_width );
printf(" Number of Ranks : %d\n", ranks );
printf(" Memory size : %d MB\n", mem_size );
-
+
/* printf(" Memory Density : %s\n", val2str(spd_data[4]&15, ddr3_density_vals)); */
printf(" 1.5 V Nominal Op : %s\n", (((spd_data[6]&1) != 0) ? "No":"Yes" ) );
printf(" 1.35 V Nominal Op : %s\n", (((spd_data[6]&2) != 0) ? "No":"Yes" ) );
@@ -1417,16 +1416,15 @@ ipmi_spd_print(uint8_t *spd_data, int len)
}
- printf(" Manufacture Date : year %c%c week %c%c\n",
+ printf(" Manufacture Date : year %c%c week %c%c\n",
'0'+(spd_data[120]>>4), '0'+(spd_data[120]&15), '0'+(spd_data[121]>>4), '0'+(spd_data[121]&15) );
-
+
printf(" Serial Number : %02x%02x%02x%02x\n",
spd_data[122], spd_data[123], spd_data[124], spd_data[125]);
-
+
printf(" Part Number : ");
- for (iPN=0; iPN < 19; iPN++)
- {
- printf( "%c", *pchPN++ );
+ for (iPN = 128; iPN < 146; iPN++) {
+ printf("%c", spd_data[iPN]);
}
printf("\n");
} else if (spd_data[2] == 0x0C) /* DDR4 SDRAM */
@@ -1552,7 +1550,7 @@ ipmi_spd_print(uint8_t *spd_data, int len)
val2str(spd_data[8], spd_voltage_vals));
printf(" Error Detect/Cor : %s\n",
val2str(spd_data[11], spd_config_vals));
-
+
/* handle jedec table bank continuation values */
printf(" Manufacturer : ");
if (spd_data[64] != 0x7f)
@@ -1603,7 +1601,7 @@ ipmi_spd_print(uint8_t *spd_data, int len)
part[18] = 0;
printf(" Part Number : %s\n", part);
}
-
+
printf(" Serial Number : %02x%02x%02x%02x\n",
spd_data[95], spd_data[96], spd_data[97], spd_data[98]);
}
diff --git a/lib/helper.c b/lib/helper.c
index 022a9c9..de91438 100644
--- a/lib/helper.c
+++ b/lib/helper.c
@@ -51,6 +51,7 @@
#include <fcntl.h>
#include <errno.h>
#include <assert.h>
+#include <ctype.h>
#if HAVE_CONFIG_H
# include <config.h>
@@ -79,22 +80,139 @@ uint16_t buf2short(uint8_t * buf)
return (uint16_t)(buf[1] << 8 | buf[0]);
}
-const char * buf2str(uint8_t * buf, int len)
+/* buf2str_extended - convert sequence of bytes to hexadecimal string with
+ * optional separator
+ *
+ * @param buf - data to convert
+ * @param len - size of data
+ * @param sep - optional separator (can be NULL)
+ *
+ * @returns buf representation in hex, possibly truncated to fit
+ * allocated static memory
+ */
+const char *
+buf2str_extended(const uint8_t *buf, int len, const char *sep)
{
- static char str[2049];
+ static char str[BUF2STR_MAXIMUM_OUTPUT_SIZE];
+ char *cur;
int i;
+ int sz;
+ int left;
+ int sep_len;
- if (len <= 0 || len > 1024)
- return NULL;
+ if (buf == NULL) {
+ snprintf(str, sizeof(str), "<NULL>");
+ return (const char *)str;
+ }
+ cur = str;
+ left = sizeof(str);
+ if (sep) {
+ sep_len = strlen(sep);
+ } else {
+ sep_len = 0;
+ }
+ for (i = 0; i < len; i++) {
+ /* may return more than 2, depending on locale */
+ sz = snprintf(cur, left, "%2.2x", buf[i]);
+ if (sz >= left) {
+ /* buffer overflow, truncate */
+ break;
+ }
+ cur += sz;
+ left -= sz;
+ /* do not write separator after last byte */
+ if (sep && i != (len - 1)) {
+ if (sep_len >= left) {
+ break;
+ }
+ strncpy(cur, sep, left - sz);
+ cur += sep_len;
+ left -= sep_len;
+ }
+ }
+ *cur = '\0';
- memset(str, 0, 2049);
+ return (const char *)str;
+}
- for (i=0; i<len; i++)
- sprintf(str+i+i, "%2.2x", buf[i]);
+const char *
+buf2str(const uint8_t *buf, int len)
+{
+ return buf2str_extended(buf, len, NULL);
+}
- str[len*2] = '\0';
+/* ipmi_parse_hex - convert hexadecimal numbers to ascii string
+ * Input string must be composed of two-characer
+ * hexadecimal numbers.
+ * There is no separator between the numbers. Each number
+ * results in one byte of the converted string.
+ *
+ * Example: ipmi_parse_hex("50415353574F5244")
+ * returns 'PASSWORD'
+ *
+ * @param str: input string. It must contain only even number
+ * of '0'-'9','a'-'f' and 'A-F' characters.
+ * @param out: pointer to output data
+ * @param size: size of the output buffer
+ * @returns 0 for empty input string
+ * -1 for string with odd length
+ * -2 if out is NULL
+ * -3 if there is non-hexadecimal char in string
+ * >0 length of resulting binary data even if it is > size
+ */
+int
+ipmi_parse_hex(const char *str, uint8_t *out, int size)
+{
+ const char *p;
+ uint8_t *q;
+ uint8_t d = 0;
+ uint8_t b = 0;
+ int shift = 4;
+ int len;
+
+ len = strlen(str);
+ if (len == 0) {
+ return 0;
+ }
- return (const char *)str;
+ if (len % 2 != 0) {
+ return -1;
+ }
+
+ len /= 2; /* out bytes */
+ if (out == NULL) {
+ return -2;
+ }
+
+ for (p = str, q = out; *p; p++) {
+ if (!isxdigit(*p)) {
+ return -3;
+ }
+
+ if (*p < 'A') {
+ /* it must be 0-9 */
+ d = *p - '0';
+ } else {
+ /* it's A-F or a-f */
+ /* convert to lowercase and to 10-15 */
+ d = (*p | 0x20) - 'a' + 10;
+ }
+
+ if (q < (out + size)) {
+ /* there is space, store */
+ b += d << shift;
+ if (shift) {
+ shift = 0;
+ } else {
+ shift = 4;
+ *q = b;
+ b = 0;
+ q++;
+ }
+ }
+ }
+
+ return len;
}
void printbuf(const uint8_t * buf, int len, const char * desc)
@@ -116,6 +234,53 @@ void printbuf(const uint8_t * buf, int len, const char * desc)
fprintf(stderr, "\n");
}
+/* str2mac - parse-out MAC address from given string and store it
+ * into buffer.
+ *
+ * @arg: string to be parsed.
+ * @buf: buffer of 6 to hold parsed MAC address.
+ *
+ * returns zero on success, (-1) on error and error message is printed-out.
+ */
+int
+str2mac(const char *arg, uint8_t *buf)
+{
+ unsigned int m1 = 0;
+ unsigned int m2 = 0;
+ unsigned int m3 = 0;
+ unsigned int m4 = 0;
+ unsigned int m5 = 0;
+ unsigned int m6 = 0;
+ if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
+ &m1, &m2, &m3, &m4, &m5, &m6) != 6) {
+ lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
+ return -1;
+ }
+ if (m1 > UINT8_MAX || m2 > UINT8_MAX
+ || m3 > UINT8_MAX || m4 > UINT8_MAX
+ || m5 > UINT8_MAX || m6 > UINT8_MAX) {
+ lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
+ return -1;
+ }
+ buf[0] = (uint8_t)m1;
+ buf[1] = (uint8_t)m2;
+ buf[2] = (uint8_t)m3;
+ buf[3] = (uint8_t)m4;
+ buf[4] = (uint8_t)m5;
+ buf[5] = (uint8_t)m6;
+ return 0;
+}
+
+/* mac2str -- return MAC address as a string
+ *
+ * @buf: buffer of 6 to hold parsed MAC address.
+ */
+const char *
+mac2str(const uint8_t *buf)
+{
+ return buf2str_extended(buf, 6, ":");
+}
+
const char * val2str(uint16_t val, const struct valstr *vs)
{
static char un_str[32];
diff --git a/lib/ipmi_cfgp.c b/lib/ipmi_cfgp.c
new file mode 100644
index 0000000..b8af80d
--- /dev/null
+++ b/lib/ipmi_cfgp.c
@@ -0,0 +1,542 @@
+/*
+ * Copyright (c) 2016 Pentair Technical Products. All right reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Pentair Technical Products or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * PENTAIR TECHNICAL SOLUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <malloc.h>
+#include <string.h>
+
+#include <ipmitool/helper.h>
+#include <ipmitool/ipmi_cfgp.h>
+#include <ipmitool/log.h>
+
+/* ipmi_cfgp_init initialize configuration parameter context
+ * @param ctx context to initialize
+ * @param set array of parameter descriptors
+ * @param count amount of descriptors supplied
+ * @param handler function to do real job on parameters from the set
+ * @param priv private data for the handler
+ */
+int
+ipmi_cfgp_init(struct ipmi_cfgp_ctx *ctx, const struct ipmi_cfgp *set,
+ unsigned int count, const char *cmdname,
+ ipmi_cfgp_handler_t handler, void *priv)
+{
+ if (ctx == NULL || set == NULL || handler == NULL || !cmdname) {
+ return -1;
+ }
+
+ memset(ctx, 0, sizeof(struct ipmi_cfgp_ctx));
+
+ ctx->set = set;
+ ctx->count = count;
+ ctx->cmdname = cmdname;
+ ctx->handler = handler;
+ ctx->priv = priv;
+
+ return 0;
+}
+
+/* ipmi_cfgp_uninit destroy data list attached to context
+ * @param ctx parameter context to clear
+ * @returns 0 -- list destroyed
+ * -1 -- ctx is NULL
+ */
+int
+ipmi_cfgp_uninit(struct ipmi_cfgp_ctx *ctx)
+{
+ struct ipmi_cfgp_data *d;
+
+ if (ctx == NULL) {
+ return -1;
+ }
+
+ while (ctx->v) {
+ d = ctx->v;
+ ctx->v = d->next;
+ free(d);
+ d = NULL;
+ }
+
+ return 0;
+}
+
+/* lookup_cfgp -- find a parameter in a set*/
+static const struct ipmi_cfgp *
+lookup_cfgp(const struct ipmi_cfgp_ctx *ctx, const char *name)
+{
+ const struct ipmi_cfgp *p;
+ int i;
+
+ for (i = 0; i < ctx->count; i++) {
+ p = &ctx->set[i];
+
+ if (p->name && !strcasecmp(p->name, name)) {
+ return p;
+ }
+ }
+
+ return NULL;
+}
+
+/* ipmi_cfgp_parse_sel parse parameter selector
+ * (parameter ID, set selector, block selector) from cmdline.
+ *
+ * @param ctx configuration parameter context to use
+ * @param argc elements left in argv
+ * @param argv array of arguments
+ * @param sel where to store parsed selector
+ *
+ * @returns >=0 number of argv elements used
+ * <0 error
+ */
+int
+ipmi_cfgp_parse_sel(struct ipmi_cfgp_ctx *ctx,
+ int argc, const char **argv, struct ipmi_cfgp_sel *sel)
+{
+ const struct ipmi_cfgp *p;
+
+ if (ctx == NULL || argv == NULL || sel == NULL) {
+ return -1;
+ }
+
+ sel->param = -1;
+ sel->set = -1;
+ sel->block = -1;
+
+ if (argc == 0) {
+ /* no parameter specified, good for print, save */
+ return 0;
+ }
+
+ p = lookup_cfgp(ctx, argv[0]);
+ if (p == NULL) {
+ lprintf(LOG_ERR, "invalid parameter");
+ return -1;
+ }
+
+ sel->param = p - ctx->set;
+ sel->set = p->is_set ? -1 : 0;
+ sel->block = p->has_blocks ? -1 : 0;
+
+ if (argc == 1 || !p->is_set) {
+ /* No set and block selector applicable or specified */
+ return 1;
+ }
+
+ if (str2int(argv[1], &sel->set)
+ || sel->set < 0
+ || (sel->set == 0 && p->first_set)) {
+ lprintf(LOG_ERR, "invalid set selector");
+ return -1;
+ }
+
+ if (argc == 2 || !p->has_blocks) {
+ /* No block selector applicable or specified */
+ return 2;
+ }
+
+ if (str2int(argv[2], &sel->block)
+ || sel->block < 0
+ || (sel->block == 0 && p->first_block)) {
+ lprintf(LOG_ERR, "invalid block selector");
+ return -1;
+ }
+
+ return 3;
+}
+
+/* cfgp_add_data adds block of data to list in the configuration
+ * parameter context
+ *
+ * @param ctx context to add data to
+ * @param data parameter data
+ */
+static void
+cfgp_add_data(struct ipmi_cfgp_ctx *ctx, struct ipmi_cfgp_data *data)
+{
+ struct ipmi_cfgp_data **pprev = &ctx->v;
+
+ data->next = NULL;
+
+ while (*pprev) {
+ pprev = &(*pprev)->next;
+ }
+
+ *pprev = data;
+}
+
+/* cfgp_usage prints format for configuration parameter
+ *
+ * @param p configuration parameter descriptor
+ * @param write 0 if no value is expected, !=0 otherwise
+ */
+static void
+cfgp_usage(const struct ipmi_cfgp *p, int write)
+{
+ if (p->name == NULL) {
+ return;
+ }
+
+ if (write && p->format == NULL) {
+ return;
+ }
+
+ printf(" %s%s%s %s\n",
+ p->name, p->is_set ? " <set_sel>" : "",
+ p->has_blocks ? " <block_sel>" : "",
+ write ? p->format : "");
+}
+
+/* ipmi_cfgp_usage prints format for configuration parameter set
+ *
+ * @param set configuration parameter descriptor array
+ * @param count number of elements in set
+ * @param write 0 if no value is expected, !=0 otherwise
+ */
+void
+ipmi_cfgp_usage(const struct ipmi_cfgp *set, int count, int write)
+{
+ const struct ipmi_cfgp *p;
+ int i;
+
+ if (set == NULL) {
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ p = &set[i];
+
+ if (write && p->access == CFGP_RDONLY) {
+ continue;
+ }
+
+ if (!write && p->access == CFGP_WRONLY) {
+ continue;
+ }
+
+ cfgp_usage(p, write);
+ }
+}
+
+/* ipmi_cfgp_parse_data parse parameter data from command line into context
+ * @param ctx context to add data
+ * @param sel parameter selector
+ * @param argc number of elements in argv
+ * @param argv array of unparsed arguments
+ *
+ * @returns 0 on success
+ * <0 on error
+ */
+int
+ipmi_cfgp_parse_data(struct ipmi_cfgp_ctx *ctx,
+ const struct ipmi_cfgp_sel *sel, int argc, const char **argv)
+{
+ const struct ipmi_cfgp *p;
+ struct ipmi_cfgp_data *data;
+ struct ipmi_cfgp_action action;
+
+ if (ctx == NULL || sel == NULL || argv == NULL) {
+ return -1;
+ }
+
+ if (sel->param == -1 || sel->param >= ctx->count) {
+ lprintf(LOG_ERR, "invalid parameter, must be one of:");
+ ipmi_cfgp_usage(ctx->set, ctx->count, 1);
+ return -1;
+ }
+
+ if (sel->set == -1) {
+ lprintf(LOG_ERR, "set selector is not specified");
+ return -1;
+ }
+
+ if (sel->block == -1) {
+ lprintf(LOG_ERR, "block selector is not specified");
+ return -1;
+ }
+
+ p = &ctx->set[sel->param];
+
+ if (p->size == 0) {
+ return -1;
+ }
+
+ data = malloc(sizeof(struct ipmi_cfgp_data) + p->size);
+ if (data == NULL) {
+ return -1;
+ }
+
+ memset(data, 0, sizeof(struct ipmi_cfgp_data) + p->size);
+
+ action.type = CFGP_PARSE;
+ action.set = sel->set;
+ action.block = sel->block;
+ action.argc = argc;
+ action.argv = argv;
+ action.file = NULL;
+
+ if (ctx->handler(ctx->priv, p, &action, data->data) != 0) {
+ ipmi_cfgp_usage(p, 1, 1);
+ free(data);
+ data = NULL;
+ return -1;
+ }
+
+ data->sel = *sel;
+
+ cfgp_add_data(ctx, data);
+ return 0;
+}
+
+/* cfgp_get_param -- get parameter data from MC into data list within context
+ *
+ * @param ctx context
+ * @param p parameter descriptor
+ * @param set parameter set selector, can be -1 to scan all set selectors
+ * @param block parameter block selector, can be -1 to get all blocks
+ * @param quiet set to non-zero to continue on errors
+ * (required for -1 to work)
+ * @returns 0 on success, non-zero otherwise
+ */
+static int
+cfgp_get_param(struct ipmi_cfgp_ctx *ctx, const struct ipmi_cfgp *p,
+ int set, int block, int quiet)
+{
+ struct ipmi_cfgp_data *data;
+ struct ipmi_cfgp_action action;
+ int cset;
+ int cblock;
+ int ret;
+
+ if (p->size == 0) {
+ return -1;
+ }
+
+ action.type = CFGP_GET;
+ action.argc = 0;
+ action.argv = NULL;
+ action.file = NULL;
+
+ if (set == -1 && !p->is_set) {
+ set = 0;
+ }
+
+ if (block == -1 && !p->has_blocks) {
+ block = 0;
+ }
+
+ if (set == -1) {
+ cset = p->first_set;
+ } else {
+ cset = set;
+ }
+
+ action.quiet = quiet;
+
+ do {
+ if (block == -1) {
+ cblock = p->first_block;
+ } else {
+ cblock = block;
+ }
+
+ do {
+ data = malloc(sizeof(struct ipmi_cfgp_data) + p->size);
+ if (data == NULL) {
+ return -1;
+ }
+
+ memset(data, 0, sizeof(struct ipmi_cfgp_data) + p->size);
+
+ action.set = cset;
+ action.block = cblock;
+
+ ret = ctx->handler(ctx->priv, p, &action, data->data);
+ if (ret != 0) {
+ free(data);
+ data = NULL;
+
+ if (!action.quiet) {
+ return ret;
+ }
+ break;
+ }
+
+ data->sel.param = p - ctx->set;
+ data->sel.set = cset;
+ data->sel.block = cblock;
+
+ cfgp_add_data(ctx, data);
+
+ cblock++;
+ action.quiet = 1;
+ } while (block == -1);
+
+ if (ret != 0 && cblock == p->first_block) {
+ break;
+ }
+
+ cset++;
+ } while (set == -1);
+
+ return 0;
+}
+
+/* ipmi_cfgp_get -- get parameters data from MC into data list within context
+ *
+ * @param ctx context
+ * @param sel parameter selector
+ * @returns 0 on success, non-zero otherwise
+ */
+int
+ipmi_cfgp_get(struct ipmi_cfgp_ctx *ctx, const struct ipmi_cfgp_sel *sel)
+{
+ int i;
+ int ret;
+
+ if (ctx == NULL || sel == NULL) {
+ return -1;
+ }
+
+ if (sel->param != -1) {
+ if (sel->param >= ctx->count) {
+ return -1;
+ }
+
+ ret = cfgp_get_param(ctx, &ctx->set[sel->param],
+ sel->set, sel->block, 0);
+ if (ret) {
+ return -1;
+ }
+ return 0;
+ }
+
+ for (i = 0; i < ctx->count; i++) {
+ if (ctx->set[i].access == CFGP_WRONLY) {
+ continue;
+ }
+
+ if (cfgp_get_param(ctx, &ctx->set[i], sel->set, sel->block, 1)) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+cfgp_do_action(struct ipmi_cfgp_ctx *ctx, int action_type,
+ const struct ipmi_cfgp_sel *sel, FILE *file, int filter)
+{
+ const struct ipmi_cfgp *p;
+ struct ipmi_cfgp_data *data;
+ struct ipmi_cfgp_action action;
+ int ret;
+
+ if (ctx == NULL || sel == NULL) {
+ return -1;
+ }
+
+ action.type = action_type;
+ action.argc = 0;
+ action.argv = NULL;
+ action.file = file;
+
+ for (data = ctx->v; data != NULL; data = data->next) {
+ if (sel->param != -1 && sel->param != data->sel.param) {
+ continue;
+ }
+ if (sel->set != -1 && sel->set != data->sel.set) {
+ continue;
+ }
+ if (sel->block != -1 && sel->block != data->sel.block) {
+ continue;
+ }
+ if (ctx->set[data->sel.param].access == filter) {
+ continue;
+ }
+
+ p = &ctx->set[data->sel.param];
+
+ action.set = data->sel.set;
+ action.block = data->sel.block;
+
+ if (action_type == CFGP_SAVE) {
+ fprintf(file, "%s %s ", ctx->cmdname, p->name);
+ if (p->is_set) {
+ fprintf(file, "%d ", data->sel.set);
+ }
+ if (p->has_blocks) {
+ fprintf(file, "%d ", data->sel.block);
+ }
+ }
+
+ ret = ctx->handler(ctx->priv, p, &action, data->data);
+
+ if (action_type == CFGP_SAVE) {
+ fputc('\n', file);
+ }
+
+ if (ret != 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_cfgp_set(struct ipmi_cfgp_ctx *ctx, const struct ipmi_cfgp_sel *sel)
+{
+ return cfgp_do_action(ctx, CFGP_SET, sel, NULL, CFGP_RDONLY);
+}
+
+int
+ipmi_cfgp_save(struct ipmi_cfgp_ctx *ctx,
+ const struct ipmi_cfgp_sel *sel, FILE *file)
+{
+ if (file == NULL) {
+ return -1;
+ }
+
+ return cfgp_do_action(ctx, CFGP_SAVE, sel, file, CFGP_RDONLY);
+}
+
+int
+ipmi_cfgp_print(struct ipmi_cfgp_ctx *ctx,
+ const struct ipmi_cfgp_sel *sel, FILE *file)
+{
+ if (file == NULL) {
+ return -1;
+ }
+
+ return cfgp_do_action(ctx, CFGP_PRINT, sel, file, CFGP_RESERVED);
+}
diff --git a/lib/ipmi_channel.c b/lib/ipmi_channel.c
index 5171644..fab2e54 100644
--- a/lib/ipmi_channel.c
+++ b/lib/ipmi_channel.c
@@ -734,7 +734,8 @@ ipmi_get_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id)
(user_access.ipmi_messaging) ? "en" : "dis");
printf("Privilege Level : %s\n",
val2str(user_access.privilege_limit, ipmi_privlvl_vals));
-
+ printf("Enable Status : %s\n",
+ val2str(user_access.enable_status, ipmi_user_enable_status_vals));
curr_uid ++;
} while (!user_id && curr_uid <= max_uid);
diff --git a/lib/ipmi_chassis.c b/lib/ipmi_chassis.c
index fb7c27d..7b5c2a8 100644
--- a/lib/ipmi_chassis.c
+++ b/lib/ipmi_chassis.c
@@ -1381,7 +1381,7 @@ ipmi_chassis_main(struct ipmi_intf * intf, int argc, char ** argv)
}
}
else {
- lprintf(LOG_ERR, "Invalid Chassis command: %s", argv[0]);
+ lprintf(LOG_ERR, "Invalid chassis command: %s", argv[0]);
return -1;
}
diff --git a/lib/ipmi_delloem.c b/lib/ipmi_delloem.c
index 9bb0885..bc78c1d 100644
--- a/lib/ipmi_delloem.c
+++ b/lib/ipmi_delloem.c
@@ -1652,11 +1652,7 @@ ipmi_macinfo_drac_idrac_virtual_mac(struct ipmi_intf* intf,uint8_t NicNum)
printf("\niDRAC6 MAC Address ");
}
- for (j = 0; j < 5; j++) {
- printf("%02x:", VirtualMacAddress[j]);
- }
- printf("%02x", VirtualMacAddress[j]);
- printf("\n");
+ printf("%s\n", mac2str(VirtualMacAddress));
return 0;
}
/*
@@ -1724,11 +1720,7 @@ ipmi_macinfo_drac_idrac_mac(struct ipmi_intf* intf,uint8_t NicNum)
printf("\niDRAC6 MAC Address ");
}
- for (j = 0; j < 5; j++) {
- printf("%02x:", iDRAC6MacAddressByte[j]);
- }
- printf("%02x", iDRAC6MacAddressByte[j]);
- printf("\n");
+ printf("%s\n", mac2str(iDRAC6MacAddressByte));
return 0;
}
/*
@@ -1786,13 +1778,8 @@ ipmi_macinfo_10g(struct ipmi_intf* intf, uint8_t NicNum)
for (i = 0; i < Total_No_NICs; i++) {
if ((0xff == NicNum) || (i == NicNum)) {
printf("\n%d",i);
- printf("\t\t");
- for (j = 0 ; j < 5; j++) {
- printf("%02x:",
- EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]);
- }
- printf("%02x",
- EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte[j]);
+ printf("\t\t%s",
+ mac2str(EmbeddedNICMacAddress_10G.MacAddress[i].MacAddressByte));
}
}
printf("\n");
@@ -1889,13 +1876,7 @@ ipmi_macinfo_11g(struct ipmi_intf* intf, uint8_t NicNum)
if ((0xff==NicNum)
|| (NicNum == EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber)) {
printf("\n%d",EmbeddedNICMacAddress.LOMMacAddress[i].NICNumber);
- printf("\t\t");
- for (j = 0; j < 5; j++) {
- printf("%02x:",
- EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]);
- }
- printf("%02x",
- EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte[j]);
+ printf("\t\t%s", mac2str(EmbeddedNICMacAddress.LOMMacAddress[i].MacAddressByte));
if (LOM_ETHERNET_ENABLED
== EmbeddedNICMacAddress.LOMMacAddress[i].EthernetStatus) {
@@ -3061,9 +3042,9 @@ ipmi_get_power_headroom_command(struct ipmi_intf * intf,uint8_t unit)
if (unit == btuphr) {
peakpowerheadroombtuphr = watt_to_btuphr_conversion(powerheadroom.peakheadroom);
instantpowerhearoom = watt_to_btuphr_conversion(powerheadroom.instheadroom);
- printf("System Instantaneous Headroom : %lld BTU/hr\n",
+ printf("System Instantaneous Headroom : %" PRId64 " BTU/hr\n",
instantpowerhearoom);
- printf("System Peak Headroom : %lld BTU/hr\n",
+ printf("System Peak Headroom : %" PRId64 " BTU/hr\n",
peakpowerheadroombtuphr);
} else {
printf("System Instantaneous Headroom : %d W\n",
@@ -3452,63 +3433,63 @@ ipmi_print_power_consmpt_history(struct ipmi_intf * intf, int unit)
if (unit == btuphr) {
printf("Average Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastminutepower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lasthourpower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastdaypower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(avgpower.lastweakpower);
- printf("%4lld BTU/hr\n", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv);
printf("Max Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastminutepower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lasthourpower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastdaypower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stPeakpower.lastweakpower);
- printf("%4lld BTU/hr\n", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr\n", tempbtuphrconv);
printf("Min Power Consumption ");
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastminutepower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lasthourpower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastdaypower);
- printf("%4lld BTU/hr ", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr ", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(stMinpower.lastweakpower);
- printf("%4lld BTU/hr\n\n", tempbtuphrconv);
+ printf("%4" PRId64 " BTU/hr\n\n", tempbtuphrconv);
} else {
printf("Average Power Consumption ");
tempbtuphrconv = (avgpower.lastminutepower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (avgpower.lasthourpower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (avgpower.lastdaypower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv=(avgpower.lastweakpower);
- printf("%4lld W \n", tempbtuphrconv);
+ printf("%4" PRId64 " W \n", tempbtuphrconv);
printf("Max Power Consumption ");
tempbtuphrconv = (stPeakpower.lastminutepower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stPeakpower.lasthourpower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stPeakpower.lastdaypower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stPeakpower.lastweakpower);
- printf("%4lld W \n", tempbtuphrconv);
+ printf("%4" PRId64 " W \n", tempbtuphrconv);
printf("Min Power Consumption ");
tempbtuphrconv = (stMinpower.lastminutepower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stMinpower.lasthourpower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stMinpower.lastdaypower);
- printf("%4lld W ", tempbtuphrconv);
+ printf("%4" PRId64 " W ", tempbtuphrconv);
tempbtuphrconv = (stMinpower.lastweakpower);
- printf("%4lld W \n\n", tempbtuphrconv);
+ printf("%4" PRId64 " W \n\n", tempbtuphrconv);
}
lastminutepeakpower = stPeakpower.lastminutepowertime;
@@ -3612,11 +3593,11 @@ ipmi_print_power_cap(struct ipmi_intf * intf,uint8_t unit)
if (rc == 0) {
if (unit == btuphr) {
tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MaximumPowerConsmp);
- printf("Maximum power: %lld BTU/hr\n", tempbtuphrconv);
+ printf("Maximum power: %" PRId64 " BTU/hr\n", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.MinimumPowerConsmp);
- printf("Minimum power: %lld BTU/hr\n", tempbtuphrconv);
+ printf("Minimum power: %" PRId64 " BTU/hr\n", tempbtuphrconv);
tempbtuphrconv = watt_to_btuphr_conversion(ipmipowercap.PowerCap);
- printf("Power cap : %lld BTU/hr\n", tempbtuphrconv);
+ printf("Power cap : %" PRId64 " BTU/hr\n", tempbtuphrconv);
} else {
printf("Maximum power: %d Watt\n", ipmipowercap.MaximumPowerConsmp);
printf("Minimum power: %d Watt\n", ipmipowercap.MinimumPowerConsmp);
diff --git a/lib/ipmi_ekanalyzer.c b/lib/ipmi_ekanalyzer.c
index d6ce4c7..7a6c63d 100644
--- a/lib/ipmi_ekanalyzer.c
+++ b/lib/ipmi_ekanalyzer.c
@@ -602,10 +602,13 @@ ipmi_ekanalyzer_main(struct ipmi_intf *intf, int argc, char **argv)
*/
filename_size = strlen(argv[index]) - SIZE_OF_FILE_TYPE + 1;
if (filename_size > 0) {
- /* TODO - check malloc() retval */
filename[i] = malloc( filename_size );
if (filename[i] != NULL) {
strcpy(filename[i], &argv[index][SIZE_OF_FILE_TYPE]);
+ } else {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ rc = ERROR_STATUS;
+ break;
}
}
rc = OK_STATUS;
@@ -2205,6 +2208,9 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record,
int index_oem = 0;
amc_record->oem_guid = malloc(amc_record->guid_count * \
sizeof(struct fru_picmgext_guid));
+ if (amc_record->oem_guid == NULL) {
+ return ERROR_STATUS;
+ }
for (index_oem = 0; index_oem < amc_record->guid_count;
index_oem++) {
memcpy(&amc_record->oem_guid[index_oem].guid,
@@ -2232,6 +2238,9 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record,
int ch_index = 0;
amc_record->ch_desc = malloc((amc_record->ch_count) * \
sizeof(struct fru_picmgext_amc_channel_desc_record));
+ if (amc_record->ch_desc == NULL) {
+ return ERROR_STATUS;
+ }
for (ch_index = 0; ch_index < amc_record->ch_count;
ch_index++) {
unsigned int data;
@@ -2255,6 +2264,9 @@ ipmi_ek_create_amc_p2p_record(struct ipmi_ek_multi_header *record,
int i=0;
amc_record->link_desc = malloc(amc_record->link_desc_count * \
sizeof(struct fru_picmgext_amc_link_desc_record));
+ if (amc_record->link_desc == NULL) {
+ return ERROR_STATUS;
+ }
for (i = 0; i< amc_record->link_desc_count; i++) {
unsigned int data[2];
struct fru_picmgext_amc_link_desc_record *src, *dst;
@@ -2767,7 +2779,6 @@ ipmi_ek_display_board_info_area(FILE *input_file, char *board_type,
lprintf(LOG_ERR, "ipmitool: malloc failure");
return (size_t)(-1);
}
-
ret = fread(additional_data, size_board, 1, input_file);
if ((ret != 1) || ferror(input_file)) {
lprintf(LOG_ERR, "Invalid Additional Data!");
@@ -3363,7 +3374,7 @@ ipmi_ek_display_board_p2p_record(struct ipmi_ek_multi_header *record)
printf("\n");
offset += sizeof(struct fru_picmgext_guid);
}
- for (offset;
+ for (offset = offset;
offset < record->header.len;
offset += sizeof(struct fru_picmgext_link_desc)) {
/* to solve little endian/big endian problem */
@@ -3522,7 +3533,7 @@ ipmi_ek_display_radial_ipmb0_record(struct ipmi_ek_multi_header *record)
if (record->data[offset] < 1) {
return;
}
- for (offset; offset < record->header.len;) {
+ for (offset = offset; offset < record->header.len;) {
unsigned char entry_count = 0;
printf(" IPMB-0 Hub Descriptor\n");
printf("\tHardware Address: 0x%02x\n",
@@ -4046,14 +4057,18 @@ ipmi_ekanalyzer_fru_file2structure(char *filename,
fseek(input_file, multi_offset, SEEK_SET);
while (!feof(input_file)) {
- /* TODO - check malloc() */
*list_record = malloc(sizeof(struct ipmi_ek_multi_header));
+ if (*list_record == NULL) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ return ERROR_STATUS;
+ }
ret = fread(&(*list_record)->header, START_DATA_OFFSET, 1,
input_file);
if ((ret != 1) || ferror(input_file)) {
- /* TODO - no free?! */
- lprintf(LOG_ERR, "Invalid Header!");
+ free(*list_record);
+ *list_record = NULL;
fclose(input_file);
+ lprintf(LOG_ERR, "Invalid Header!");
return ERROR_STATUS;
}
if ((*list_record)->header.len == 0) {
diff --git a/lib/ipmi_event.c b/lib/ipmi_event.c
index 16fc80d..bc32ae8 100644
--- a/lib/ipmi_event.c
+++ b/lib/ipmi_event.c
@@ -207,18 +207,20 @@ ipmi_send_platform_event_num(struct ipmi_intf * intf, int num)
}
static int
-ipmi_event_find_offset(uint8_t code,
- struct ipmi_event_sensor_types * evt,
- char * desc)
+ipmi_event_find_offset(struct ipmi_intf *intf, uint8_t sensor_type, uint8_t event_type, char *desc)
{
- if (desc == NULL || code == 0)
+ const struct ipmi_event_sensor_types *evt;
+
+ if (desc == NULL || sensor_type == 0 || event_type == 0) {
return 0x00;
+ }
- while (evt->type) {
- if (evt->code == code && evt->desc != NULL &&
- strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0)
+ for (evt = ipmi_get_first_event_sensor_type(intf, sensor_type, event_type);
+ evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) {
+ if (evt->desc != NULL &&
+ strncasecmp(desc, evt->desc, __maxlen(desc, evt->desc)) == 0) {
return evt->offset;
- evt++;
+ }
}
lprintf(LOG_WARN, "Unable to find matching event offset for '%s'", desc);
@@ -226,11 +228,11 @@ ipmi_event_find_offset(uint8_t code,
}
static void
-print_sensor_states(uint8_t sensor_type, uint8_t event_type)
+print_sensor_states(struct ipmi_intf *intf, uint8_t sensor_type, uint8_t event_type)
{
- ipmi_sdr_print_discrete_state_mini(
+ ipmi_sdr_print_discrete_state_mini(intf,
"Sensor States: \n ", "\n ", sensor_type,
- event_type, 0xff, 0xff);
+ event_type, 0xff, 0xff);
printf("\n");
}
@@ -400,7 +402,7 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
- print_sensor_states(emsg.sensor_type, emsg.event_type);
+ print_sensor_states(intf, emsg.sensor_type, emsg.event_type);
printf("Sensor State Shortcuts:\n");
for (x = 0; x < sizeof(digi_on)/sizeof(*digi_on); x++) {
printf(" %-9s %-9s\n", digi_on[x], digi_off[x]);
@@ -422,8 +424,8 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e
}
}
if (off == 0) {
- off = ipmi_event_find_offset(
- emsg.event_type, generic_event_types, state);
+ off = ipmi_event_find_offset(intf,
+ emsg.sensor_type, emsg.event_type, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
@@ -440,11 +442,11 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
- print_sensor_states(emsg.sensor_type, emsg.event_type);
+ print_sensor_states(intf, emsg.sensor_type, emsg.event_type);
return 0;
}
- off = ipmi_event_find_offset(
- emsg.event_type, generic_event_types, state);
+ off = ipmi_event_find_offset(intf,
+ emsg.sensor_type, emsg.event_type, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
@@ -460,11 +462,11 @@ ipmi_event_fromsensor(struct ipmi_intf * intf, char * id, char * state, char * e
* print list of available states for this sensor
*/
if (state == NULL || strncasecmp(state, "list", 4) == 0) {
- print_sensor_states(emsg.sensor_type, emsg.event_type);
+ print_sensor_states(intf, emsg.sensor_type, emsg.event_type);
return 0;
}
- off = ipmi_event_find_offset(
- emsg.sensor_type, sensor_specific_types, state);
+ off = ipmi_event_find_offset(intf,
+ emsg.sensor_type, emsg.event_type, state);
if (off < 0)
return -1;
emsg.event_data[0] = off;
diff --git a/lib/ipmi_firewall.c b/lib/ipmi_firewall.c
index c3f51ad..26bfd30 100644
--- a/lib/ipmi_firewall.c
+++ b/lib/ipmi_firewall.c
@@ -899,7 +899,7 @@ static int
ipmi_firewall_info(struct ipmi_intf * intf, int argc, char ** argv)
{
int ret = 0;
- struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
+ struct ipmi_function_params p = {0xe, -1, -1, -1, -1, 0};
struct bmc_fn_support * bmc_fn_support;
unsigned int l, n, c;
@@ -1012,7 +1012,7 @@ ipmi_firewall_info(struct ipmi_intf * intf, int argc, char ** argv)
static int
ipmi_firewall_enable_disable(struct ipmi_intf * intf, int enable, int argc, char ** argv)
{
- struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
+ struct ipmi_function_params p = {0xe, -1, -1, -1, -1, 0};
struct bmc_fn_support * bmc_fn_support;
int ret;
unsigned int l, n, c;
@@ -1103,7 +1103,7 @@ ipmi_firewall_enable_disable(struct ipmi_intf * intf, int enable, int argc, char
static int
ipmi_firewall_reset(struct ipmi_intf * intf, int argc, char ** argv)
{
- struct ipmi_function_params p = {0xe, -1, -1, -1, -1};
+ struct ipmi_function_params p = {0xe, -1, -1, -1, -1, 0};
struct bmc_fn_support * bmc_fn_support;
int ret;
unsigned int l, n, c;
@@ -1135,8 +1135,8 @@ ipmi_firewall_reset(struct ipmi_intf * intf, int argc, char ** argv)
for (l=0; l<MAX_LUN; l++) {
p.lun = l;
- for (n=0; n<MAX_NETFN; n+=2) {
- p.netfn = n;
+ for (n=0; n<MAX_NETFN_PAIR; n++) {
+ p.netfn = n*2;
for (c=0; c<MAX_COMMAND; c++) {
p.command = c;
printf("reset lun %d, netfn %d, command %d, subfn\n", l, n, c);
diff --git a/lib/ipmi_fru.c b/lib/ipmi_fru.c
index 5c94b08..cf00eff 100644
--- a/lib/ipmi_fru.c
+++ b/lib/ipmi_fru.c
@@ -50,6 +50,13 @@
#define FRU_MULTIREC_CHUNK_SIZE (255 + sizeof(struct fru_multirec_header))
+static const char *section_id[4] = {
+ "Internal Use Section",
+ "Chassis Section",
+ "Board Section",
+ "Product Section"
+};
+
/* From lib/dimm_spd.c: */
int
ipmi_spd_print_fru(struct ipmi_intf * intf, uint8_t id);
@@ -677,9 +684,9 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
break;
}
if (rsp->ccode > 0) {
- /* if we get C8h or CAh completion code then we requested too
+ /* if we get C7h or C8h or CAh return code then we requested too
* many bytes at once so try again with smaller size */
- if ((rsp->ccode == 0xc8 || rsp->ccode == 0xca)
+ if ((rsp->ccode == 0xc7 || rsp->ccode == 0xc8 || rsp->ccode == 0xca)
&& fru->max_read_size > 8) {
if (fru->max_read_size > 32) {
/* subtract read length more aggressively */
@@ -2281,8 +2288,7 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
printf(" Link Type Extension: 0x%02x - ",
d->ext);
if (d->type == FRU_PICMGEXT_LINK_TYPE_BASE) {
- switch (d->ext)
- {
+ switch (d->ext) {
case 0:
printf("10/100/1000BASE-T Link (four-pair)\n");
break;
@@ -2290,76 +2296,93 @@ static void ipmi_fru_picmg_ext_print(uint8_t * fru_data, int off, int length)
printf("ShMC Cross-connect (two-pair)\n");
break;
default:
- printf("Unknwon\n");
+ printf("Unknown\n");
break;
}
} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET) {
- switch (d->ext)
- {
+ switch (d->ext) {
case 0:
- printf("Fixed 1000Base-BX\n");
+ printf("1000Base-BX\n");
break;
case 1:
- printf("Fixed 10GBASE-BX4 [XAUI]\n");
+ printf("10GBase-BX4 [XAUI]\n");
break;
case 2:
printf("FC-PI\n");
break;
+ case 3:
+ printf("1000Base-KX\n");
+ break;
+ case 4:
+ printf("10GBase-KX4\n");
+ break;
+ default:
+ printf("Unknown\n");
+ break;
+ }
+ } else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET_10GBD) {
+ switch (d->ext) {
+ case 0:
+ printf("10GBase-KR\n");
+ break;
+ case 1:
+ printf("40GBase-KR4\n");
+ break;
default:
- printf("Unknwon\n");
+ printf("Unknown\n");
break;
}
} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND) {
- printf("Unknwon\n");
+ printf("Unknown\n");
} else if (d->type == FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR) {
- printf("Unknwon\n");
+ printf("Unknown\n");
} else if (d->type == FRU_PICMGEXT_LINK_TYPE_PCIE) {
- printf("Unknwon\n");
+ printf("Unknown\n");
} else {
- printf("Unknwon\n");
+ printf("Unknown\n");
}
printf(" Link Type: 0x%02x - ",
d->type);
- if (d->type == 0 || d->type == 0xff) {
- printf("Reserved\n");
- }
- else if (d->type >= 0x06 && d->type <= 0xef) {
- printf("Reserved\n");
- }
- else if (d->type >= 0xf0 && d->type <= 0xfe) {
- printf("OEM GUID Definition\n");
- }
- else {
- switch (d->type)
- {
- case FRU_PICMGEXT_LINK_TYPE_BASE:
- printf("PICMG 3.0 Base Interface 10/100/1000\n");
- break;
- case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
- printf("PICMG 3.1 Ethernet Fabric Interface\n");
- break;
- case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
- printf("PICMG 3.2 Infiniband Fabric Interface\n");
- break;
- case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
- printf("PICMG 3.3 Star Fabric Interface\n");
- break;
- case FRU_PICMGEXT_LINK_TYPE_PCIE:
- printf("PICMG 3.4 PCI Express Fabric Interface\n");
- break;
- default:
+ switch (d->type) {
+ case FRU_PICMGEXT_LINK_TYPE_BASE:
+ printf("PICMG 3.0 Base Interface 10/100/1000\n");
+ break;
+ case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET:
+ printf("PICMG 3.1 Ethernet Fabric Interface\n");
+ printf(" Base signaling Link Class\n");
+ break;
+ case FRU_PICMGEXT_LINK_TYPE_FABRIC_INFINIBAND:
+ printf("PICMG 3.2 Infiniband Fabric Interface\n");
+ break;
+ case FRU_PICMGEXT_LINK_TYPE_FABRIC_STAR:
+ printf("PICMG 3.3 Star Fabric Interface\n");
+ break;
+ case FRU_PICMGEXT_LINK_TYPE_PCIE:
+ printf("PICMG 3.4 PCI Express Fabric Interface\n");
+ break;
+ case FRU_PICMGEXT_LINK_TYPE_FABRIC_ETHERNET_10GBD:
+ printf("PICMG 3.1 Ethernet Fabric Interface\n");
+ printf(" 10.3125Gbd signaling Link Class\n");
+ break;
+ default:
+ if (d->type == 0 || d->type == 0xff) {
+ printf("Reserved\n");
+ } else if (d->type >= 0x06 && d->type <= 0xef) {
+ printf("Reserved\n");
+ } else if (d->type >= 0xf0 && d->type <= 0xfe) {
+ printf("OEM GUID Definition\n");
+ } else {
printf("Invalid\n");
- break;
- }
+ }
+ break;
}
printf(" Link Designator: \n");
printf(" Port Flag: 0x%02x\n",
d->desig_port);
printf(" Interface: 0x%02x - ",
d->desig_if);
- switch (d->desig_if)
- {
+ switch (d->desig_if) {
case FRU_PICMGEXT_DESIGN_IF_BASE:
printf("Base Interface\n");
break;
diff --git a/lib/ipmi_hpmfwupg.c b/lib/ipmi_hpmfwupg.c
index 9cbd4ff..bbcffc0 100644
--- a/lib/ipmi_hpmfwupg.c
+++ b/lib/ipmi_hpmfwupg.c
@@ -1399,7 +1399,12 @@ HpmfwupgGetBufferFromFile(char *imageFilename,
return HPMFWUPG_ERROR;
}
/* Get the raw data in file */
- fseek(pImageFile, 0, SEEK_END);
+ ret = fseek(pImageFile, 0, SEEK_END);
+ if (ret != 0) {
+ lprintf(LOG_ERR, "Failed to seek in the image file '%s'",
+ imageFilename);
+ return HPMFWUPG_ERROR;
+ }
pFwupgCtx->imageSize = ftell(pImageFile);
pFwupgCtx->pImageData = malloc(sizeof(unsigned char)*pFwupgCtx->imageSize);
if (pFwupgCtx->pImageData == NULL) {
diff --git a/lib/ipmi_lanp.c b/lib/ipmi_lanp.c
index ecd313a..65d881b 100644
--- a/lib/ipmi_lanp.c
+++ b/lib/ipmi_lanp.c
@@ -104,7 +104,7 @@ is_lan_channel(struct ipmi_intf * intf, uint8_t chan)
* @intf: ipmi interface handle
* @start: channel number to start searching from
*/
-static uint8_t
+uint8_t
find_lan_channel(struct ipmi_intf * intf, uint8_t start)
{
uint8_t chan = 0;
@@ -704,8 +704,7 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
if (p == NULL)
return -1;
if (p->data != NULL)
- printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
- p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
+ printf("%-24s: %s\n", p->desc, mac2str(p->data));
p = get_lan_param(intf, chan, IPMI_LANP_SNMP_STRING);
if (p == NULL)
@@ -744,8 +743,7 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
if (p == NULL)
return -1;
if (p->data != NULL)
- printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
- p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
+ printf("%-24s: %s\n", p->desc, mac2str(p->data));
p = get_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP);
if (p == NULL)
@@ -758,8 +756,7 @@ ipmi_lan_print(struct ipmi_intf * intf, uint8_t chan)
if (p == NULL)
return -1;
if (p->data != NULL)
- printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", p->desc,
- p->data[0], p->data[1], p->data[2], p->data[3], p->data[4], p->data[5]);
+ printf("%-24s: %s\n", p->desc, mac2str(p->data));
p = get_lan_param(intf, chan, IPMI_LANP_VLAN_ID);
if (p != NULL && p->data != NULL) {
@@ -1103,42 +1100,6 @@ ipmi_set_user_access(struct ipmi_intf *intf, uint8_t channel, uint8_t user_id)
}
}
-/* get_cmdline_macaddr - parse-out MAC address from given string and store it
- * into buffer.
- *
- * @arg: string to be parsed.
- * @buf: buffer of 6 to hold parsed MAC address.
- *
- * returns zero on success, (-1) on error and error message is printed-out.
- */
-static int
-get_cmdline_macaddr(char *arg, uint8_t *buf)
-{
- uint32_t m1 = 0;
- uint32_t m2 = 0;
- uint32_t m3 = 0;
- uint32_t m4 = 0;
- uint32_t m5 = 0;
- uint32_t m6 = 0;
- if (sscanf(arg, "%02x:%02x:%02x:%02x:%02x:%02x",
- &m1, &m2, &m3, &m4, &m5, &m6) != 6) {
- lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
- return -1;
- }
- if (m1 > UINT8_MAX || m2 > UINT8_MAX
- || m3 > UINT8_MAX || m4 > UINT8_MAX
- || m5 > UINT8_MAX || m6 > UINT8_MAX) {
- lprintf(LOG_ERR, "Invalid MAC address: %s", arg);
- return -1;
- }
- buf[0] = (uint8_t)m1;
- buf[1] = (uint8_t)m2;
- buf[2] = (uint8_t)m3;
- buf[3] = (uint8_t)m4;
- buf[4] = (uint8_t)m5;
- buf[5] = (uint8_t)m6;
- return 0;
-}
static int
@@ -1243,12 +1204,27 @@ get_cmdline_ipaddr(char * arg, uint8_t * buf)
static int
ipmi_lan_set_vlan_id(struct ipmi_intf *intf, uint8_t chan, char *string)
{
+ struct lan_param *p;
uint8_t data[2];
int rc;
if (string == NULL) {
- data[0] = 0;
- data[1] = 0;
+ lprintf(LOG_DEBUG, "Get current VLAN ID from BMC.");
+ p = get_lan_param(intf, chan, IPMI_LANP_VLAN_ID);
+ if (p != NULL && p->data != NULL && p->data_len > 1) {
+ int id = ((p->data[1] & 0x0f) << 8) + p->data[0];
+ if (id < 1 || id > 4094) {
+ lprintf(LOG_ERR,
+ "Retrieved VLAN ID %i is out of range <1..4094>.",
+ id);
+ return (-1);
+ }
+ data[0] = p->data[0];
+ data[1] = p->data[1] & 0x0F;
+ } else {
+ data[0] = 0;
+ data[1] = 0;
+ }
}
else {
int id = 0;
@@ -1540,11 +1516,11 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
print_lan_set_usage();
return -1;
}
- rc = get_cmdline_macaddr(argv[2], data);
+ rc = str2mac(argv[2], data);
if (rc == 0) {
- printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
- ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc,
- data[0], data[1], data[2], data[3], data[4], data[5]);
+ printf("Setting LAN %s to %s\n",
+ ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc,
+ mac2str(data));
rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6);
}
}
@@ -1566,10 +1542,10 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_IP, data, 4);
}
else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
- (get_cmdline_macaddr(argv[3], data) == 0)) {
- printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
- ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc,
- data[0], data[1], data[2], data[3], data[4], data[5]);
+ (str2mac(argv[3], data) == 0)) {
+ printf("Setting LAN %s to %s\n",
+ ipmi_lan_params[IPMI_LANP_DEF_GATEWAY_MAC].desc,
+ mac2str(data));
rc = set_lan_param(intf, chan, IPMI_LANP_DEF_GATEWAY_MAC, data, 6);
}
else {
@@ -1595,10 +1571,10 @@ ipmi_lan_set(struct ipmi_intf * intf, int argc, char ** argv)
rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_IP, data, 4);
}
else if ((strncmp(argv[2], "macaddr", 7) == 0) &&
- (get_cmdline_macaddr(argv[3], data) == 0)) {
- printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n",
- ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc,
- data[0], data[1], data[2], data[3], data[4], data[5]);
+ (str2mac(argv[3], data) == 0)) {
+ printf("Setting LAN %s to %s\n",
+ ipmi_lan_params[IPMI_LANP_BAK_GATEWAY_MAC].desc,
+ mac2str(data));
rc = set_lan_param(intf, chan, IPMI_LANP_BAK_GATEWAY_MAC, data, 6);
}
else {
@@ -1776,9 +1752,8 @@ ipmi_lan_alert_print(struct ipmi_intf * intf, uint8_t channel, uint8_t alert)
printf("%-24s: %d.%d.%d.%d\n", "Alert IP Address",
paddr[3], paddr[4], paddr[5], paddr[6]);
- printf("%-24s: %02x:%02x:%02x:%02x:%02x:%02x\n", "Alert MAC Address",
- paddr[7], paddr[8], paddr[9],
- paddr[10], paddr[11], paddr[12]);
+ printf("%-24s: %s\n", "Alert MAC Address",
+ mac2str(&paddr[7]));
printf("\n");
return 0;
@@ -1843,7 +1818,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
}
/* alert destination mac address */
else if (strncasecmp(argv[0], "macaddr", 7) == 0 &&
- (get_cmdline_macaddr(argv[1], temp) == 0)) {
+ (str2mac(argv[1], temp) == 0)) {
/* get current parameter */
p = get_lan_param_select(intf, chan, IPMI_LANP_DEST_ADDR, alert);
if (p == NULL) {
@@ -1853,8 +1828,7 @@ ipmi_lan_alert_set(struct ipmi_intf * intf, uint8_t chan, uint8_t alert,
/* set new macaddr */
memcpy(data+7, temp, 6);
printf("Setting LAN Alert %d MAC Address to "
- "%02x:%02x:%02x:%02x:%02x:%02x\n", alert,
- data[7], data[8], data[9], data[10], data[11], data[12]);
+ "%s\n", alert, mac2str(&data[7]));
rc = set_lan_param_nowait(intf, chan, IPMI_LANP_DEST_ADDR, data, p->data_len);
}
/* alert destination gateway selector */
diff --git a/lib/ipmi_lanp6.c b/lib/ipmi_lanp6.c
new file mode 100644
index 0000000..bbffb89
--- /dev/null
+++ b/lib/ipmi_lanp6.c
@@ -0,0 +1,1240 @@
+/*
+ * Copyright (c) 2016 Pentair Technical Products. All right reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * Redistribution of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * Redistribution in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * Neither the name of Pentair Technical Products or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * PENTAIR TECHNICAL SOLUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <ipmitool/helper.h>
+#include <ipmitool/ipmi_cc.h>
+#include <ipmitool/ipmi_cfgp.h>
+#include <ipmitool/ipmi_lanp.h>
+#include <ipmitool/ipmi_lanp6.h>
+#include <ipmitool/log.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+/*
+ * LAN6 command values.
+ */
+enum {
+ LANP_CMD_SAVE,
+ LANP_CMD_SET,
+ LANP_CMD_PRINT,
+ LANP_CMD_LOCK,
+ LANP_CMD_COMMIT,
+ LANP_CMD_DISCARD,
+ LANP_CMD_HELP,
+ LANP_CMD_ANY = 0xFF
+};
+
+/*
+ * Generic LAN configuration parameters.
+ */
+const struct ipmi_lanp generic_lanp6[] = {
+ { 0, "Set In Progress", 1 },
+ { 50, "IPv6/IPv4 Support", 1 },
+ { 51, "IPv6/IPv4 Addressing Enables", 1 },
+ { 52, "IPv6 Header Traffic Class", 1 },
+ { 53, "IPv6 Header Static Hop Limit", 1 },
+ { 54, "IPv6 Header Flow Label", 3 },
+ { 55, "IPv6 Status", 3 },
+ { 56, "IPv6 Static Address", 20 },
+ { 57, "IPv6 DHCPv6 Static DUID Storage Length", 1 },
+ { 58, "IPv6 DHCPv6 Static DUID", 18 },
+ { 59, "IPv6 Dynamic Address", 20 },
+ { 60, "IPv6 DHCPv6 Dynamic DUID Storage Length", 1 },
+ { 61, "IPv6 DHCPv6 Dynamic DUID", 18 },
+ { 62, "IPv6 DHCPv6 Timing Configuration Support", 1 },
+ { 63, "IPv6 DHCPv6 Timing Configuration", 18 },
+ { 64, "IPv6 Router Address Configuration Control", 1 },
+ { 65, "IPv6 Static Router 1 IP Address", 16 },
+ { 66, "IPv6 Static Router 1 MAC Address", 6 },
+ { 67, "IPv6 Static Router 1 Prefix Length", 1 },
+ { 68, "IPv6 Static Router 1 Prefix Value", 16 },
+ { 69, "IPv6 Static Router 2 IP Address", 16 },
+ { 70, "IPv6 Static Router 2 MAC Address", 6 },
+ { 71, "IPv6 Static Router 2 Prefix Length", 1 },
+ { 72, "IPv6 Static Router 2 Prefix Value", 16 },
+ { 73, "IPv6 Number of Dynamic Router Info Sets", 1 },
+ { 74, "IPv6 Dynamic Router Info IP Address", 17 },
+ { 75, "IPv6 Dynamic Router Info MAC Address", 7 },
+ { 76, "IPv6 Dynamic Router Info Prefix Length", 2 },
+ { 77, "IPv6 Dynamic Router Info Prefix Value", 17 },
+ { 78, "IPv6 Dynamic Router Received Hop Limit", 1 },
+ { 79, "IPv6 ND/SLAAC Timing Configuration Support", 1 },
+ { 80, "IPv6 ND/SLAAC Timing Configuration", 18 },
+ { 0, NULL, 0 }
+};
+
+/*
+ * Set/Get LAN Configuration Parameters
+ * command-specific completion codes.
+ */
+const struct valstr lanp_cc_vals[] = {
+ { 0x80, "Parameter not supported" },
+ { 0x81, "Set already in progress" },
+ { 0x82, "Parameter is read-only" },
+ { 0x83, "Write-only parameter" },
+ { 0x00, NULL }
+};
+
+/*
+ * IPv6/IPv4 Addressing Enables.
+ */
+const struct valstr ip6_enable_vals[] = {
+ { 0, "ipv4" },
+ { 1, "ipv6" },
+ { 2, "both" },
+ { 0xFF, NULL }
+};
+
+/*
+ * Enable/Disable a static address.
+ */
+const struct valstr ip6_addr_enable_vals[] = {
+ { 0x00, "disable" },
+ { 0x80, "enable" },
+ { 0xFF, NULL }
+};
+
+/*
+ * IPv6 address source values.
+ */
+const struct valstr ip6_addr_sources[] = {
+ { 0, "static" },
+ { 1, "SLAAC" },
+ { 2, "DHCPv6" },
+ { 0, NULL }
+};
+
+/*
+ * IPv6 address status values.
+ */
+const struct valstr ip6_addr_statuses[] = {
+ { 0, "active" },
+ { 1, "disabled" },
+ { 2, "pending" },
+ { 3, "failed" },
+ { 4, "deprecated" },
+ { 5, "invalid" },
+ { 0xFF, NULL }
+};
+
+/*
+ * DHCPv6 DUID type values.
+ */
+const struct valstr ip6_duid_types[] = {
+ { 0, "unknown" },
+ { 1, "DUID-LLT" },
+ { 2, "DUID-EN" },
+ { 3, "DUID-LL" },
+ { 0xFF, NULL }
+};
+
+/*
+ * Timing Configuration support values.
+ */
+const struct valstr ip6_cfg_sup_vals[] = {
+ { 0, "not supported" },
+ { 1, "global" },
+ { 2, "per interface" },
+ { 0xFF, NULL }
+};
+
+/*
+ * Router Address Configuration Control values.
+ */
+const struct valstr ip6_rtr_configs[] = {
+ { 1, "static" },
+ { 2, "dynamic" },
+ { 3, "both" },
+ { 0xFF, NULL }
+};
+
+
+const struct valstr ip6_command_vals[] = {
+ { LANP_CMD_SET, "set" },
+ { LANP_CMD_SAVE, "save" },
+ { LANP_CMD_PRINT, "print" },
+ { LANP_CMD_LOCK, "lock" },
+ { LANP_CMD_COMMIT, "commit" },
+ { LANP_CMD_DISCARD, "discard" },
+ { LANP_CMD_HELP, "help" },
+ { LANP_CMD_ANY, NULL }
+};
+
+static const struct ipmi_cfgp lan_cfgp[] = {
+ { .name = "support", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_SUPPORT
+ },
+ { .name = "enables", .format = "{ipv4|ipv6|both}", .size = 1,
+ .access = CFGP_RDWR,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_ENABLES
+ },
+ { .name = "traffic_class", .format = "<value>", .size = 1,
+ .access = CFGP_RDWR,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_TRAFFIC_CLASS
+ },
+ { .name = "static_hops", .format = "<value>", .size = 1,
+ .access = CFGP_RDWR,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATIC_HOPS
+ },
+ { .name = "flow_label", .format = "<value>", .size = 3,
+ .access = CFGP_RDWR,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_FLOW_LABEL
+ },
+ { .name = "status", .format = NULL, .size = 3,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATUS
+ },
+ { .name = "static_addr",
+ .format = "{enable|disable} <addr> <pfx_len>", .size = 20,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATIC_ADDR
+ },
+ { .name = "static_duid_stg", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATIC_DUID_STG
+ },
+ { .name = "static_duid", .format = "<data>", .size = 18,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 0, .has_blocks = 1, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATIC_DUID
+ },
+ { .name = "dynamic_addr", .format = NULL, .size = 20,
+ .access = CFGP_RDONLY,
+ .is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DYNAMIC_ADDR
+ },
+ { .name = "dynamic_duid_stg", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DYNAMIC_DUID_STG
+ },
+ { .name = "dynamic_duid", .format = "<data>", .size = 18,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 0, .has_blocks = 1, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DYNAMIC_DUID
+ },
+ { .name = "dhcp6_cfg_sup", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DHCP6_CFG_SUP
+ },
+ { .name = "dhcp6_cfg", .format = "<data> <data>", .size = 36,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DHCP6_CFG
+ },
+ { .name = "rtr_cfg", .format = "{static|dynamic|both}", .size = 1,
+ .access = CFGP_RDWR,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_ROUTER_CFG
+ },
+ { .name = "static_rtr",
+ .format = "<addr> <macaddr> <prefix> <prefix_len>", .size = 43,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 1, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_STATIC_RTR1_ADDR
+ },
+ { .name = "num_dynamic_rtrs", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_NUM_DYNAMIC_RTRS
+ },
+ { .name = "dynamic_rtr", .format = NULL, .size = 43,
+ .access = CFGP_RDONLY,
+ .is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DYNAMIC_RTR_ADDR
+ },
+ { .name = "dynamic_hops", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_DYNAMIC_HOPS
+ },
+ { .name = "ndslaac_cfg_sup", .format = NULL, .size = 1,
+ .access = CFGP_RDONLY,
+ .is_set = 0, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_NDSLAAC_CFG_SUP
+ },
+ { .name = "ndslaac_cfg", .format = "<data>", .size = 18,
+ .access = CFGP_RDWR,
+ .is_set = 1, .first_set = 0, .has_blocks = 0, .first_block = 0,
+ .specific = IPMI_LANP_IP6_NDSLAAC_CFG
+ }
+};
+
+/*
+ * Lookup LAN parameter descriptor by parameter selector.
+ */
+const struct ipmi_lanp *
+lookup_lanp(int param)
+{
+ const struct ipmi_lanp *p = generic_lanp6;
+
+ while (p->name) {
+ if (p->selector == param) {
+ return p;
+ }
+
+ p++;
+ }
+
+ return NULL;
+}
+
+/*
+ * Print request error.
+ */
+static int
+ipmi_lanp_err(const struct ipmi_rs *rsp, const struct ipmi_lanp *p,
+ const char *action, int quiet)
+{
+ const char *reason;
+ char cc_msg[10];
+ int log_level = LOG_ERR;
+ int err;
+
+ if (rsp == NULL) {
+ reason = "No response";
+ err = -1;
+ } else {
+ err = rsp->ccode;
+ if (quiet == 1
+ && (rsp->ccode == 0x80
+ || rsp->ccode == IPMI_CC_PARAM_OUT_OF_RANGE
+ || rsp->ccode == IPMI_CC_INV_DATA_FIELD_IN_REQ)) {
+ /* be quiet */
+ return err;
+ }
+
+ if (rsp->ccode >= 0xC0) {
+ /* browse for generic completion codes */
+ reason = val2str(rsp->ccode, completion_code_vals);
+ } else {
+ /* browse for command-specific completion codes first */
+ reason = val2str(rsp->ccode, lanp_cc_vals);
+ }
+
+ if (reason == NULL) {
+ /* print completion code value */
+ snprintf(cc_msg, sizeof(cc_msg), "CC=%02x", rsp->ccode);
+ reason = cc_msg;
+ }
+
+ if (rsp->ccode == IPMI_CC_OK) {
+ log_level = LOG_DEBUG;
+ }
+ }
+
+ lprintf(log_level, "Failed to %s %s: %s", action, p->name, reason);
+ return err;
+}
+
+/*
+ * Get dynamic OEM LAN configuration parameter from BMC.
+ * Dynamic in this context is when the base for OEM LAN parameters
+ * is not known apriori.
+ */
+int
+ipmi_get_dynamic_oem_lanp(void *priv, const struct ipmi_lanp *param,
+ int oem_base, int set_selector, int block_selector,
+ void *data, int quiet)
+{
+ struct ipmi_lanp_priv *lp = priv;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t req_data[4];
+ int length;
+
+ if (!priv || !param || !data) {
+ return -1;
+ }
+ req_data[0] = lp->channel;
+ req_data[1] = param->selector + oem_base;
+ req_data[2] = set_selector;
+ req_data[3] = block_selector;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_TRANSPORT;
+ req.msg.cmd = 2;
+ req.msg.data = req_data;
+ req.msg.data_len = 4;
+
+ lprintf(LOG_INFO, "Getting parameter '%s' set %d block %d",
+ param->name, set_selector, block_selector);
+
+ rsp = lp->intf->sendrecv(lp->intf, &req);
+ if (rsp == NULL || rsp->ccode) {
+ return ipmi_lanp_err(rsp, param, "get", quiet);
+ }
+
+ memset(data, 0, param->size);
+
+ if (rsp->data_len - 1 < param->size) {
+ length = rsp->data_len - 1;
+ } else {
+ length = param->size;
+ }
+
+ if (length) {
+ memcpy(data, rsp->data + 1, length);
+ }
+
+ return 0;
+}
+
+/*
+ * Get generic LAN configuration parameter.
+ */
+int
+ipmi_get_lanp(void *priv, int param_selector, int set_selector,
+ int block_selector, void *data, int quiet)
+{
+ return ipmi_get_dynamic_oem_lanp(priv, lookup_lanp(param_selector), 0,
+ set_selector, block_selector, data, quiet);
+}
+
+/*
+ * Set dynamic OEM LAN configuration parameter to BMC.
+ * Dynamic in this context is when the base for OEM LAN parameters
+ * is not known apriori.
+ */
+int
+ipmi_set_dynamic_oem_lanp(void *priv, const struct ipmi_lanp *param,
+ int base, const void *data)
+{
+ struct ipmi_lanp_priv *lp = priv;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t req_data[32];
+
+ if (!priv || !param || !data) {
+ return -1;
+ }
+ /* fill the first two bytes */
+ req_data[0] = lp->channel;
+ req_data[1] = param->selector + base;
+
+ /* fill the rest data */
+ memcpy(&req_data[2], data, param->size);
+
+ /* fill request */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_TRANSPORT;
+ req.msg.cmd = 1;
+ req.msg.data = req_data;
+ req.msg.data_len = param->size + 2;
+
+ lprintf(LOG_INFO, "Setting parameter '%s'", param->name);
+
+ rsp = lp->intf->sendrecv(lp->intf, &req);
+ if (rsp == NULL || rsp->ccode) {
+ return ipmi_lanp_err(rsp, param, "set", 0);
+ }
+
+ return 0;
+}
+
+/*
+ * Set generic LAN configuration parameter.
+ */
+int
+ipmi_set_lanp(void *priv, int param_selector, const void *data)
+{
+ return ipmi_set_dynamic_oem_lanp(priv, lookup_lanp(param_selector),
+ 0, data);
+}
+
+static int
+lanp_parse_cfgp(const struct ipmi_cfgp *p, int set, int block,
+ int argc, const char *argv[], unsigned char *data)
+{
+ unsigned int v;
+
+ if (argc == 0) {
+ return -1;
+ }
+
+ switch(p->specific) {
+ case IPMI_LANP_IP6_ENABLES:
+ data[0] = str2val(argv[0], ip6_enable_vals);
+ if (data[0] == 0xFF) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ case IPMI_LANP_IP6_FLOW_LABEL:
+ if (str2uint(argv[0], &v)) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+
+ data[0] = (v >> 16) & 0x0F;
+ data[1] = (v >> 8) & 0xFF;
+ data[2] = v & 0xFF;
+ break;
+
+ case IPMI_LANP_IP6_STATUS:
+ if (argc < 3) {
+ return -1;
+ }
+
+ if (str2uchar(argv[0], &data[0])
+ || str2uchar(argv[1], &data[1])
+ || str2uchar(argv[2], &data[2])) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ case IPMI_LANP_IP6_STATIC_ADDR:
+ case IPMI_LANP_IP6_DYNAMIC_ADDR:
+ if (argc < 3) {
+ return -1;
+ }
+
+ data[0] = set;
+ if (p->specific == IPMI_LANP_IP6_STATIC_ADDR) {
+ data[1] = str2val(argv[0], ip6_addr_enable_vals);
+ } else {
+ data[1] = str2val(argv[0], ip6_addr_sources);
+ }
+ if (data[1] == 0xFF) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+
+ if (inet_pton(AF_INET6, argv[1], &data[2]) != 1) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+
+ if (str2uchar(argv[2], &data[18])) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+
+ if (argc >= 4) {
+ data[19] = str2val(argv[3], ip6_addr_statuses);
+ }
+ break;
+
+ case IPMI_LANP_IP6_STATIC_DUID:
+ case IPMI_LANP_IP6_DYNAMIC_DUID:
+ case IPMI_LANP_IP6_NDSLAAC_CFG:
+ data[0] = set;
+ data[1] = block;
+ if (ipmi_parse_hex(argv[0], &data[2], 16) < 0) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ case IPMI_LANP_IP6_DHCP6_CFG:
+ data[0] = set;
+ data[1] = 0;
+ data[18] = set;
+ data[19] = 1;
+
+ if (ipmi_parse_hex(argv[0], &data[2], 16) < 0
+ || (argc > 1 &&
+ ipmi_parse_hex(argv[1], &data[20], 6) < 0)) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ case IPMI_LANP_IP6_ROUTER_CFG:
+ data[0] = str2val(argv[0], ip6_rtr_configs);
+ if (data[0] == 0xFF) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
+ if (set > 2) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+
+ case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
+ if (argc < 4) {
+ return -1;
+ }
+
+ /*
+ * Data is stored in the following way:
+ * 0: <set> <addr1>...<addr16>
+ * 17: <set> <mac1>...<mac6>
+ * 24: <set> <pfxlen>
+ * 26: <set> <pfx1>...<pfx16>
+ */
+ data[0] = data[17] = data[24] = data[26] = set;
+
+ if (inet_pton(AF_INET6, argv[0], &data[1]) != 1
+ || str2mac(argv[1], &data[18])
+ || inet_pton(AF_INET6, argv[2], &data[27]) != 1
+ || str2uchar(argv[3], &data[25])) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ break;
+
+ default:
+ if (str2uchar(argv[0], &data[0])) {
+ lprintf(LOG_ERR, "invalid value");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+lanp_set_cfgp(void *priv, const struct ipmi_cfgp *p, const unsigned char *data)
+{
+ int ret;
+ int param = p->specific;
+ int off = 0;
+
+ switch(param) {
+ case IPMI_LANP_IP6_DHCP6_CFG:
+ ret = ipmi_set_lanp(priv, param, &data[0]);
+ if (ret == 0) {
+ ret = ipmi_set_lanp(priv, param, &data[18]);
+ }
+ break;
+
+ case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
+ if (data[0] == 2) {
+ param = IPMI_LANP_IP6_STATIC_RTR2_ADDR;
+ }
+ off = 1;
+
+ case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
+ ret = ipmi_set_lanp(priv, param, &data[0 + off]);
+ if (ret == 0) {
+ ret = ipmi_set_lanp(priv, param + 1, &data[17 + off]);
+ }
+ if (ret == 0) {
+ ret = ipmi_set_lanp(priv, param + 2, &data[24 + off]);
+ }
+ if (ret == 0) {
+ ret = ipmi_set_lanp(priv, param + 3, &data[26 + off]);
+ }
+ break;
+
+
+ default:
+ ret = ipmi_set_lanp(priv, param, data);
+ }
+
+ return ret;
+}
+
+static int
+lanp_get_cfgp(void *priv, const struct ipmi_cfgp *p,
+ int set, int block, unsigned char *data, int quiet)
+{
+ int ret;
+ int param = p->specific;
+ int off = 0;
+
+ switch(param) {
+ case IPMI_LANP_IP6_DHCP6_CFG:
+ ret = ipmi_get_lanp(priv, param, set, 0, &data[0], quiet);
+ if (ret == 0) {
+ ret = ipmi_get_lanp(priv, param, set,
+ 1, &data[18], quiet);
+ }
+ break;
+
+ case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
+ if (set > 2) {
+ return -1;
+ }
+
+ if (set == 2) {
+ param = IPMI_LANP_IP6_STATIC_RTR2_ADDR;
+ }
+ set = 0;
+ off = 1;
+ data[0] = data[17] = data[24] = data[26] = set;
+
+ case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
+ ret = ipmi_get_lanp(priv, param, set, block,
+ &data[0 + off], quiet);
+ if (ret == 0) {
+ ret = ipmi_get_lanp(priv, param + 1, set, block,
+ &data[17 + off], 0);
+ }
+ if (ret == 0) {
+ ret = ipmi_get_lanp(priv, param + 2, set, block,
+ &data[24 + off], 0);
+ }
+ if (ret == 0) {
+ ret = ipmi_get_lanp(priv, param + 3, set, block,
+ &data[26 + off], 0);
+ }
+ break;
+
+ default:
+ ret = ipmi_get_lanp(priv, param, set, block, data, quiet);
+ }
+
+ return ret;
+}
+
+static int
+lanp_save_cfgp(const struct ipmi_cfgp *p, const unsigned char *data, FILE *file)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char pfx[INET6_ADDRSTRLEN];
+ const char *src;
+
+ switch(p->specific) {
+ case IPMI_LANP_IP6_ENABLES:
+ fputs(val2str(data[0], ip6_enable_vals), file);
+ break;
+
+ case IPMI_LANP_IP6_FLOW_LABEL:
+ fprintf(file, "0x%xd", (data[0] << 16 ) | (data[1] << 8) | data[2]);
+ break;
+
+ case IPMI_LANP_IP6_STATUS:
+ fprintf(file, "%d %d %d", data[0], data[1], data[2]);
+ break;
+
+ case IPMI_LANP_IP6_STATIC_ADDR:
+ case IPMI_LANP_IP6_DYNAMIC_ADDR:
+ if (p->specific == IPMI_LANP_IP6_STATIC_ADDR) {
+ src = val2str(data[1], ip6_addr_enable_vals);
+ } else {
+ src = val2str(data[1], ip6_addr_sources);
+ }
+
+ fprintf(file, "%s %s %d %s", src,
+ inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
+ data[18], val2str(data[19], ip6_addr_statuses));
+ break;
+
+ case IPMI_LANP_IP6_STATIC_DUID:
+ case IPMI_LANP_IP6_DYNAMIC_DUID:
+ case IPMI_LANP_IP6_NDSLAAC_CFG:
+ fprintf(file, "%s", buf2str(&data[2], 16));
+ break;
+
+ case IPMI_LANP_IP6_DHCP6_CFG:
+ fprintf(file, "%s", buf2str(&data[2], 16));
+ fprintf(file, " %s", buf2str(&data[20], 6));
+ break;
+
+ case IPMI_LANP_IP6_ROUTER_CFG:
+ fputs(val2str(data[0], ip6_rtr_configs), file);
+ break;
+
+ case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
+ case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
+ fprintf(file, "%s %s %s %d",
+ inet_ntop(AF_INET6, &data[1], addr, sizeof(addr)),
+ mac2str(&data[18]),
+ inet_ntop(AF_INET6, &data[27], pfx, sizeof(pfx)), data[25]);
+ break;
+
+ default:
+ fprintf(file, "%d", data[0]);
+ }
+
+ return 0;
+}
+
+
+static int
+lanp_print_cfgp(const struct ipmi_cfgp *p,
+ int set, int block, const unsigned char *data, FILE *file)
+{
+ char addr[INET6_ADDRSTRLEN];
+ char pfx[INET6_ADDRSTRLEN];
+ const char *pname;
+ const struct ipmi_lanp *lanp = lookup_lanp(p->specific);
+
+ if (!lanp || !p || !file || !data || !lanp->name) {
+ return -1;
+ }
+ pname = lanp->name;
+
+ switch(p->specific) {
+ case IPMI_LANP_IP6_SUPPORT:
+ fprintf(file, "%s:\n"
+ " IPv6 only: %s\n"
+ " IPv4 and IPv6: %s\n"
+ " IPv6 Destination Addresses for LAN alerting: %s\n",
+ pname,
+ data[0] & 1 ? "yes" : "no",
+ data[0] & 2 ? "yes" : "no",
+ data[0] & 4 ? "yes" : "no");
+ break;
+
+ case IPMI_LANP_IP6_ENABLES:
+ fprintf(file, "%s: %s\n",
+ pname, val2str(data[0], ip6_enable_vals));
+ break;
+
+ case IPMI_LANP_IP6_FLOW_LABEL:
+ fprintf(file, "%s: %d\n",
+ pname, (data[0] << 16 ) | (data[1] << 8) | data[2]);
+ break;
+
+ case IPMI_LANP_IP6_STATUS:
+ fprintf(file, "%s:\n"
+ " Static address max: %d\n"
+ " Dynamic address max: %d\n"
+ " DHCPv6 support: %s\n"
+ " SLAAC support: %s\n",
+ pname,
+ data[0], data[1],
+ (data[2] & 1) ? "yes" : "no",
+ (data[2] & 2) ? "yes" : "no");
+ break;
+
+ case IPMI_LANP_IP6_STATIC_ADDR:
+ fprintf(file, "%s %d:\n"
+ " Enabled: %s\n"
+ " Address: %s/%d\n"
+ " Status: %s\n",
+ pname, set,
+ (data[1] & 0x80) ? "yes" : "no",
+ inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
+ data[18], val2str(data[19] & 0xF, ip6_addr_statuses));
+ break;
+
+ case IPMI_LANP_IP6_DYNAMIC_ADDR:
+ fprintf(file, "%s %d:\n"
+ " Source/Type: %s\n"
+ " Address: %s/%d\n"
+ " Status: %s\n",
+ pname, set,
+ val2str(data[1] & 0xF, ip6_addr_sources),
+ inet_ntop(AF_INET6, &data[2], addr, sizeof(addr)),
+ data[18], val2str(data[19] & 0xF, ip6_addr_statuses));
+ break;
+
+ case IPMI_LANP_IP6_STATIC_DUID:
+ case IPMI_LANP_IP6_DYNAMIC_DUID:
+ if (block == 0) {
+ fprintf(file, "%s %d:\n"
+ " Length: %d\n"
+ " Type: %s\n",
+ pname, set, data[2],
+ val2str((data[3] << 8) + data[4], ip6_duid_types));
+ }
+ fprintf(file, " %s\n", buf2str(&data[2], 16));
+ break;
+
+ case IPMI_LANP_IP6_DHCP6_CFG_SUP:
+ case IPMI_LANP_IP6_NDSLAAC_CFG_SUP:
+ fprintf(file, "%s: %s\n",
+ pname, val2str(data[0], ip6_cfg_sup_vals));
+ break;
+
+ case IPMI_LANP_IP6_DHCP6_CFG:
+ fprintf(file, "%s %d:\n", pname, set);
+
+ fprintf(file,
+ " SOL_MAX_DELAY: %d\n"
+ " SOL_TIMEOUT: %d\n"
+ " SOL_MAX_RT: %d\n"
+ " REQ_TIMEOUT: %d\n"
+ " REQ_MAX_RT: %d\n"
+ " REQ_MAX_RC: %d\n"
+ " CNF_MAX_DELAY: %d\n"
+ " CNF_TIMEOUT: %d\n"
+ " CNF_MAX_RT: %d\n"
+ " CNF_MAX_RD: %d\n"
+ " REN_TIMEOUT: %d\n"
+ " REN_MAX_RT: %d\n"
+ " REB_TIMEOUT: %d\n"
+ " REB_MAX_RT: %d\n"
+ " INF_MAX_DELAY: %d\n"
+ " INF_TIMEOUT: %d\n"
+ " INF_MAX_RT: %d\n"
+ " REL_TIMEOUT: %d\n"
+ " REL_MAX_RC: %d\n"
+ " DEC_TIMEOUT: %d\n"
+ " DEC_MAX_RC: %d\n"
+ " HOP_COUNT_LIMIT: %d\n",
+ data[2], data[3], data[4], data[5],
+ data[6], data[7], data[8], data[9],
+ data[10], data[11], data[12], data[13],
+ data[14], data[15], data[16], data[17],
+ data[20], data[21], data[22], data[23],
+ data[24], data[25]);
+ break;
+
+ case IPMI_LANP_IP6_ROUTER_CFG:
+ fprintf(file, "%s:\n"
+ " Enable static router address: %s\n"
+ " Enable dynamic router address: %s\n",
+ pname,
+ (data[0] & 1) ? "yes" : "no",
+ (data[0] & 2) ? "yes" : "no");
+ break;
+
+ case IPMI_LANP_IP6_STATIC_RTR1_ADDR:
+ case IPMI_LANP_IP6_DYNAMIC_RTR_ADDR:
+ if (p->specific == IPMI_LANP_IP6_STATIC_RTR1_ADDR) {
+ pname = "IPv6 Static Router";
+ } else {
+ pname = "IPv6 Dynamic Router";
+ }
+
+ fprintf(file, "%s %d:\n"
+ " Address: %s\n"
+ " MAC: %s\n"
+ " Prefix: %s/%d\n",
+ pname, set,
+ inet_ntop(AF_INET6, &data[1], addr, sizeof(addr)),
+ mac2str(&data[18]),
+ inet_ntop(AF_INET6, &data[27], pfx, sizeof(pfx)), data[25]);
+ break;
+
+ case IPMI_LANP_IP6_NDSLAAC_CFG:
+ fprintf(file, "%s %d:\n"
+ " MAX_RTR_SOLICITATION_DELAY: %d\n"
+ " RTR_SOLICITATION_INTERVAL: %d\n"
+ " MAX_RTR_SOLICITATIONS: %d\n"
+ " DupAddrDetectTransmits: %d\n"
+ " MAX_MULTICAST_SOLICIT: %d\n"
+ " MAX_UNICAST_SOLICIT: %d\n"
+ " MAX_ANYCAST_DELAY_TIME: %d\n"
+ " MAX_NEIGHBOR_ADVERTISEMENT: %d\n"
+ " REACHABLE_TIME: %d\n"
+ " RETRANS_TIMER: %d\n"
+ " DELAY_FIRST_PROBE_TIME: %d\n"
+ " MAX_RANDOM_FACTOR: %d\n"
+ " MIN_RANDOM_FACTOR: %d\n",
+ pname, set,
+ data[2], data[3], data[4], data[5],
+ data[6], data[7], data[8], data[9],
+ data[10], data[11], data[12], data[13],
+ data[14]);
+ break;
+
+ default:
+ fprintf(file, "%s: %d\n", pname, data[0]);
+ }
+
+ return 0;
+}
+
+static int
+lanp_ip6_cfgp(void *priv, const struct ipmi_cfgp *p,
+ const struct ipmi_cfgp_action *action, unsigned char *data)
+{
+ switch (action->type) {
+ case CFGP_PARSE:
+ return lanp_parse_cfgp(p, action->set, action->block,
+ action->argc, action->argv, data);
+
+ case CFGP_GET:
+ return lanp_get_cfgp(priv, p, action->set, action->block,
+ data, action->quiet);
+
+ case CFGP_SET:
+ return lanp_set_cfgp(priv, p, data);
+
+ case CFGP_SAVE:
+ return lanp_save_cfgp(p, data, action->file);
+
+ case CFGP_PRINT:
+ return lanp_print_cfgp(p, action->set, action->block,
+ data, action->file);
+
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static void lanp_print_usage(int cmd)
+{
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_HELP) {
+ printf(" help [command]\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_SAVE) {
+ printf(" save <channel> [<parameter> [<set_sel> [<block_sel>]]]\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_SET) {
+ printf(" set <channel> [nolock] <parameter> [<set_sel> [<block_sel>]] <values...>\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_PRINT) {
+ printf(" print <channel> [<parameter> [<set_sel> [<block_sel>]]]\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_LOCK) {
+ printf(" lock <channel>\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_COMMIT) {
+ printf(" commit <channel>\n");
+ }
+ if (cmd == LANP_CMD_ANY || cmd == LANP_CMD_DISCARD) {
+ printf(" discard <channel>\n");
+ }
+ if (cmd == LANP_CMD_SAVE
+ || cmd == LANP_CMD_PRINT
+ || cmd == LANP_CMD_SET) {
+ printf("\n available parameters:\n");
+ /* 'save' shall use 'write' filter, since it outputs a block
+ * of 'set's */
+ ipmi_cfgp_usage(lan_cfgp,
+ sizeof(lan_cfgp)/sizeof(lan_cfgp[0]),
+ cmd != LANP_CMD_PRINT);
+ }
+}
+
+static int
+lanp_lock(struct ipmi_lanp_priv *lp)
+{
+ unsigned char byte = 1;
+
+ return ipmi_set_lanp(lp, 0, &byte);
+}
+
+static int
+lanp_discard(struct ipmi_lanp_priv *lp)
+{
+ unsigned char byte = 0;
+
+ return ipmi_set_lanp(lp, 0, &byte);
+}
+
+static int
+lanp_commit(struct ipmi_lanp_priv *lp)
+{
+ unsigned char byte = 2;
+ int ret;
+
+ ret = ipmi_set_lanp(lp, 0, &byte);
+ if (ret == 0) {
+ ret = lanp_discard(lp);
+ }
+
+ return ret;
+}
+
+int
+ipmi_lan6_main(struct ipmi_intf *intf, int argc, char **argv)
+{
+ struct ipmi_cfgp_ctx ctx;
+ struct ipmi_cfgp_sel sel;
+ struct ipmi_lanp_priv lp;
+ int cmd;
+ int chan;
+ int nolock = 0;
+ int ret;
+
+ if (argc == 0) {
+ lanp_print_usage(LANP_CMD_ANY);
+ return 0;
+ }
+
+ cmd = str2val(argv[0], ip6_command_vals);
+ if (cmd == LANP_CMD_ANY) {
+ lanp_print_usage(cmd);
+ return -1;
+ }
+
+ if (cmd == LANP_CMD_HELP) {
+ if (argc == 1) {
+ cmd = LANP_CMD_ANY;
+ } else {
+ cmd = str2val(argv[1], ip6_command_vals);
+ }
+
+ lanp_print_usage(cmd);
+ return 0;
+ }
+
+ /*
+ * the rest commands expect channel number
+ * with the exception of 'get' and 'print'
+ */
+ if (argc == 1) {
+ if (cmd == LANP_CMD_SAVE || cmd == LANP_CMD_PRINT) {
+ chan = find_lan_channel(intf, 1);
+ if (chan == 0) {
+ lprintf(LOG_ERR, "No LAN channel found");
+ return -1;
+ }
+ } else {
+ lanp_print_usage(cmd);
+ return -1;
+ }
+
+ argc -= 1;
+ argv += 1;
+ } else {
+ if (str2int(argv[1], &chan) != 0) {
+ lprintf(LOG_ERR, "Invalid channel: %s", argv[1]);
+ return -1;
+ }
+
+ argc -= 2;
+ argv += 2;
+
+ if (cmd == LANP_CMD_SET) {
+ if (argc && !strcasecmp(argv[0], "nolock")) {
+ nolock = 1;
+
+ argc -= 1;
+ argv += 1;
+ }
+ }
+
+ }
+
+ lp.intf = intf;
+ lp.channel = chan;
+
+ /*
+ * lock/commit/discard commands do not require parsing
+ * of parameter selection
+ */
+
+ switch (cmd) {
+ case LANP_CMD_LOCK:
+ lprintf(LOG_NOTICE, "Lock parameter(s)...");
+ return lanp_lock(&lp);
+
+ case LANP_CMD_COMMIT:
+ lprintf(LOG_NOTICE, "Commit parameter(s)...");
+ return lanp_commit(&lp);
+
+ case LANP_CMD_DISCARD:
+ lprintf(LOG_NOTICE, "Discard parameter(s)...");
+ return lanp_discard(&lp);
+ }
+
+ /*
+ * initialize configuration context and parse parameter selection
+ */
+
+ ipmi_cfgp_init(&ctx, lan_cfgp,
+ sizeof(lan_cfgp)/sizeof(lan_cfgp[0]), "lan6 set nolock",
+ lanp_ip6_cfgp, &lp);
+
+ ret = ipmi_cfgp_parse_sel(&ctx, argc, (const char **)argv, &sel);
+ if (ret == -1) {
+ lanp_print_usage(cmd);
+ ipmi_cfgp_uninit(&ctx);
+ return -1;
+ }
+
+ argc -= ret;
+ argv += ret;
+
+ /*
+ * handle the rest commands
+ */
+
+ switch (cmd) {
+ case LANP_CMD_SAVE:
+ case LANP_CMD_PRINT:
+ lprintf(LOG_NOTICE, "Getting parameter(s)...");
+
+ ret = ipmi_cfgp_get(&ctx, &sel);
+ if (ret != 0) {
+ break;
+ }
+
+ if (cmd == LANP_CMD_SAVE) {
+ static char cmd[20];
+ FILE *out = stdout;
+ snprintf(cmd, sizeof(cmd) - 1, "lan6 set %d nolock",
+ lp.channel);
+ cmd[sizeof(cmd) - 1] = '\0';
+ ctx.cmdname = cmd;
+ fprintf(out, "lan6 lock %d\n", lp.channel);
+ ret = ipmi_cfgp_save(&ctx, &sel, out);
+ fprintf(out, "lan6 commit %d\nlan6 discard %d\nexit\n",
+ lp.channel, lp.channel);
+ } else {
+ ret = ipmi_cfgp_print(&ctx, &sel, stdout);
+ }
+ break;
+
+ case LANP_CMD_SET:
+ ret = ipmi_cfgp_parse_data(&ctx, &sel, argc,
+ (const char **)argv);
+ if (ret != 0) {
+ break;
+ }
+
+ lprintf(LOG_NOTICE, "Setting parameter(s)...");
+
+ if (!nolock) {
+ ret = lanp_lock(&lp);
+ if (ret != 0) {
+ break;
+ }
+ }
+
+ ret = ipmi_cfgp_set(&ctx, &sel);
+ if (!nolock) {
+ if (ret == 0) {
+ ret = lanp_commit(&lp);
+ } else {
+ lanp_discard(&lp);
+ }
+ }
+ break;
+ }
+
+ /*
+ * free allocated memory
+ */
+ ipmi_cfgp_uninit(&ctx);
+
+ return ret;
+}
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index e6f96f6..811c80b 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -291,69 +291,6 @@ void ipmi_catch_sigint()
exit(-1);
}
-/* ipmi_parse_hex - convert hexadecimal numbers to ascii string
- * Input string must be composed of two-characer hexadecimal numbers.
- * There is no separator between the numbers. Each number results in one character
- * of the converted string.
- *
- * Example: ipmi_parse_hex("50415353574F5244") returns 'PASSWORD'
- *
- * @param str: input string. It must contain only even number of '0'-'9','a'-'f' and 'A-F' characters.
- * @returns converted ascii string
- * @returns NULL on error
- */
-static unsigned char *
-ipmi_parse_hex(const char *str)
-{
- const char * p;
- unsigned char * out, *q;
- unsigned char b = 0;
- int shift = 4;
-
- if (strlen(str) == 0)
- return NULL;
-
- if (strlen(str) % 2 != 0) {
- lprintf(LOG_ERR, "Number of hex_kg characters is not even");
- return NULL;
- }
-
- if (strlen(str) > (IPMI_KG_BUFFER_SIZE-1)*2) {
- lprintf(LOG_ERR, "Kg key is too long");
- return NULL;
- }
-
- out = calloc(IPMI_KG_BUFFER_SIZE, sizeof(unsigned char));
- if (out == NULL) {
- lprintf(LOG_ERR, "malloc failure");
- return NULL;
- }
-
- for (p = str, q = out; *p; p++) {
- if (!isxdigit(*p)) {
- lprintf(LOG_ERR, "Kg_hex is not hexadecimal number");
- free(out);
- out = NULL;
- return NULL;
- }
-
- if (*p < 'A') /* it must be 0-9 */
- b = *p - '0';
- else /* it's A-F or a-f */
- b = (*p | 0x20) - 'a' + 10; /* convert to lowercase and to 10-15 */
-
- *q = *q + (b << shift);
- if (shift)
- shift = 0;
- else {
- shift = 4;
- q++;
- }
- }
-
- return out;
-}
-
static uint8_t
ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
{
@@ -406,7 +343,7 @@ ipmi_main(int argc, char ** argv,
char * progname = NULL;
char * oemtype = NULL;
char * sdrcache = NULL;
- unsigned char * kgkey = NULL;
+ uint8_t kgkey[IPMI_KG_BUFFER_SIZE];
char * seloem = NULL;
int port = 0;
int devnum = 0;
@@ -421,6 +358,7 @@ ipmi_main(int argc, char ** argv,
progname = strrchr(argv[0], '/');
progname = ((progname == NULL) ? argv[0] : progname+1);
signal(SIGINT, ipmi_catch_sigint);
+ memset(kgkey, 0, sizeof(kgkey));
while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
{
@@ -547,38 +485,30 @@ ipmi_main(int argc, char ** argv,
}
break;
case 'k':
- if (kgkey) {
- free(kgkey);
- kgkey = NULL;
- }
- kgkey = strdup(optarg);
- if (kgkey == NULL) {
- lprintf(LOG_ERR, "%s: malloc failure", progname);
- goto out_free;
- }
+ memset(kgkey, 0, sizeof(kgkey));
+ strncpy((char *)kgkey, optarg, sizeof(kgkey) - 1);
break;
case 'K':
if ((tmp_env = getenv("IPMI_KGKEY"))) {
- if (kgkey) {
- free(kgkey);
- kgkey = NULL;
- }
- kgkey = strdup(tmp_env);
- if (kgkey == NULL) {
- lprintf(LOG_ERR, "%s: malloc failure", progname);
- goto out_free;
- }
+ memset(kgkey, 0, sizeof(kgkey));
+ strncpy((char *)kgkey, tmp_env,
+ sizeof(kgkey) - 1);
} else {
lprintf(LOG_WARN, "Unable to read kgkey from environment");
}
break;
case 'y':
- if (kgkey) {
- free(kgkey);
- kgkey = NULL;
- }
- kgkey = ipmi_parse_hex(optarg);
- if (kgkey == NULL) {
+ memset(kgkey, 0, sizeof(kgkey));
+
+ rc = ipmi_parse_hex(optarg, kgkey, sizeof(kgkey) - 1);
+ if (rc == -1) {
+ lprintf(LOG_ERR, "Number of Kg key characters is not even");
+ goto out_free;
+ } else if (rc == -3) {
+ lprintf(LOG_ERR, "Kg key is not hexadecimal number");
+ goto out_free;
+ } else if (rc > (IPMI_KG_BUFFER_SIZE-1)) {
+ lprintf(LOG_ERR, "Kg key is too long");
goto out_free;
}
break;
@@ -589,16 +519,10 @@ ipmi_main(int argc, char ** argv,
tmp_pass = getpass("Key: ");
#endif
if (tmp_pass != NULL) {
- if (kgkey) {
- free(kgkey);
- kgkey = NULL;
- }
- kgkey = strdup(tmp_pass);
+ memset(kgkey, 0, sizeof(kgkey));
+ strncpy((char *)kgkey, tmp_pass,
+ sizeof(kgkey) - 1);
tmp_pass = NULL;
- if (kgkey == NULL) {
- lprintf(LOG_ERR, "%s: malloc failure", progname);
- goto out_free;
- }
}
break;
case 'U':
@@ -928,8 +852,7 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_username(ipmi_main_intf, username);
if (password != NULL)
ipmi_intf_session_set_password(ipmi_main_intf, password);
- if (kgkey != NULL)
- ipmi_intf_session_set_kgkey(ipmi_main_intf, kgkey);
+ ipmi_intf_session_set_kgkey(ipmi_main_intf, kgkey);
if (port > 0)
ipmi_intf_session_set_port(ipmi_main_intf, port);
if (authtype >= 0)
@@ -1123,10 +1046,6 @@ ipmi_main(int argc, char ** argv,
free(seloem);
seloem = NULL;
}
- if (kgkey != NULL) {
- free(kgkey);
- kgkey = NULL;
- }
if (sdrcache != NULL) {
free(sdrcache);
sdrcache = NULL;
diff --git a/lib/ipmi_mc.c b/lib/ipmi_mc.c
index 5b4a080..4580bfb 100644
--- a/lib/ipmi_mc.c
+++ b/lib/ipmi_mc.c
@@ -462,78 +462,79 @@ ipmi_mc_get_deviceid(struct ipmi_intf * intf)
return 0;
}
-/* Structure follow the IPMI V.2 Rev 1.0
- * See Table 20-10 */
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(1)
-#endif
-
-struct ipmi_guid {
- uint32_t time_low; /* timestamp low field */
- uint16_t time_mid; /* timestamp middle field */
- uint16_t time_hi_and_version; /* timestamp high field and version number */
- uint8_t clock_seq_hi_variant;/* clock sequence high field and variant */
- uint8_t clock_seq_low; /* clock sequence low field */
- uint8_t node[6]; /* node */
-} ATTRIBUTE_PACKING;
-#ifdef HAVE_PRAGMA_PACK
-#pragma pack(0)
-#endif
-
-/* ipmi_mc_get_guid - print this MC GUID
+/* _ipmi_mc_get_guid - Gets BMCs GUID according to (22.14)
*
* @intf: ipmi interface
+ * @guid: pointer where to store BMC GUID
*
- * returns 0 on success
- * returns -1 on error
+ * returns - negative number means error, positive is a ccode.
*/
-static int
-ipmi_mc_get_guid(struct ipmi_intf * intf)
+int
+_ipmi_mc_get_guid(struct ipmi_intf *intf, struct ipmi_guid_t *guid)
{
- struct ipmi_rs * rsp;
+ struct ipmi_rs *rsp;
struct ipmi_rq req;
- struct ipmi_guid guid;
+ if (guid == NULL) {
+ return (-3);
+ }
+ memset(guid, 0, sizeof(struct ipmi_guid_t));
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_GUID;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
- lprintf(LOG_ERR, "Get GUID command failed");
- return -1;
- }
- if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Get GUID command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
-
- if (rsp->data_len == sizeof(struct ipmi_guid)) {
- char tbuf[40];
- time_t s;
- memset(tbuf, 0, 40);
- memset(&guid, 0, sizeof(struct ipmi_guid));
- memcpy(&guid, rsp->data, rsp->data_len);
-
- /* Kipp - changed order of last field (node) to follow specification */
- printf("System GUID : %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
- guid.time_low, guid.time_mid, guid.time_hi_and_version,
- guid.clock_seq_hi_variant << 8 | guid.clock_seq_low,
- guid.node[0], guid.node[1], guid.node[2],
- guid.node[3], guid.node[4], guid.node[5]);
-
- s = (time_t)guid.time_low; /* Kipp - removed the BSWAP_32, it was not needed here */
- strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
- printf("Timestamp : %s\n", tbuf);
- }
- else {
- lprintf(LOG_ERR, "Invalid GUID length %d", rsp->data_len);
+ return (-1);
+ } else if (rsp->ccode > 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 16
+ || rsp->data_len != sizeof(struct ipmi_guid_t)) {
+ return (-2);
}
+ memcpy(guid, &rsp->data[0], sizeof(struct ipmi_guid_t));
+ return 0;
+}
+/* ipmi_mc_print_guid - print-out given BMC GUID
+ *
+ * @guid - struct with GUID.
+ *
+ * returns 0
+ */
+static int
+ipmi_mc_print_guid(struct ipmi_guid_t guid)
+{
+ char tbuf[40];
+ time_t s;
+ memset(tbuf, 0, 40);
+ /* Kipp - changed order of last field (node) to follow specification */
+ printf("System GUID : %08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x\n",
+ guid.time_low, guid.time_mid, guid.time_hi_and_version,
+ guid.clock_seq_hi_variant << 8 | guid.clock_seq_low,
+ guid.node[0], guid.node[1], guid.node[2],
+ guid.node[3], guid.node[4], guid.node[5]);
+
+ s = (time_t)guid.time_low; /* Kipp - removed the BSWAP_32, it was not needed here */
+ strftime(tbuf, sizeof(tbuf), "%m/%d/%Y %H:%M:%S", localtime(&s));
+ printf("Timestamp : %s\n", tbuf);
return 0;
}
+/* ipmi_mc_get_guid - Gets and prints-out System GUID */
+int
+ipmi_mc_get_guid(struct ipmi_intf *intf)
+{
+ struct ipmi_guid_t guid;
+ int rc;
+ rc = _ipmi_mc_get_guid(intf, &guid);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ }
+ rc = ipmi_mc_print_guid(guid);
+ return rc;
+}
+
/* ipmi_mc_get_selftest - returns and print selftest results
*
* @intf: ipmi interface
diff --git a/lib/ipmi_pef.c b/lib/ipmi_pef.c
index 22f29e4..bbf25f2 100644
--- a/lib/ipmi_pef.c
+++ b/lib/ipmi_pef.c
@@ -36,10 +36,13 @@
#include <ipmitool/bswap.h>
#include <ipmitool/helper.h>
-#include <ipmitool/log.h>
#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_channel.h>
#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_mc.h>
#include <ipmitool/ipmi_pef.h>
+#include <ipmitool/ipmi_sel.h>
+#include <ipmitool/log.h>
extern int verbose;
/*
@@ -75,6 +78,8 @@ static const char * pef_flag_fmts[][3] = {
};
static const char * listitem[] = {" | %s", ",%s", "%s"};
+static int ipmi_pef2_list_filters(struct ipmi_intf *);
+
const char *
ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t value)
{ /*
@@ -184,6 +189,31 @@ ipmi_pef_print_1xd(const char * text, uint32_t val)
ipmi_pef_print_field(pef_fld_fmts[F_1XD], text, val);
}
+/* ipmi_pef_print_guid - print-out GUID. */
+static int
+ipmi_pef_print_guid(uint8_t *guid)
+{
+ if (guid == NULL) {
+ return (-1);
+ }
+
+ if (verbose) {
+ printf("%-*s : %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
+ KYWD_LENGTH, "System GUID",
+ guid[0], guid[1], guid[2], guid[3], guid[4],
+ guid[5], guid[6], guid[7], guid[8], guid[9],
+ guid[10],guid[11], guid[12], guid[13], guid[14],
+ guid[15]);
+ } else {
+ printf(" | %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ guid[0], guid[1], guid[2], guid[3], guid[4],
+ guid[5], guid[6], guid[7], guid[8], guid[9],
+ guid[10], guid[11], guid[12], guid[13], guid[14],
+ guid[15]);
+ }
+ return 0;
+}
+
static struct ipmi_rs *
ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
{ /*
@@ -204,58 +234,423 @@ ipmi_pef_msg_exchange(struct ipmi_intf * intf, struct ipmi_rq * req, char * txt)
return(rsp);
}
-static uint8_t
-ipmi_pef_get_policy_table(struct ipmi_intf * intf,
- struct pef_cfgparm_policy_table_entry ** table)
-{ /*
- // get the PEF policy table: allocate space, fillin, and return its size
- // NB: the caller must free the returned area (when returned size > 0)
- */
- struct ipmi_rs * rsp;
+/* _ipmi_get_pef_capabilities - Requests and returns result of (30.1) Get PEF
+ * Capabilities.
+ *
+ * @pcap - pointer where to store results.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+int
+_ipmi_get_pef_capabilities(struct ipmi_intf *intf,
+ struct pef_capabilities *pcap)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ if (pcap == NULL) {
+ return (-3);
+ }
+
+ memset(pcap, 0, sizeof(struct pef_capabilities));
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 3) {
+ return (-2);
+ }
+ pcap->version = rsp->data[0];
+ pcap->actions = rsp->data[1];
+ pcap->event_filter_count = rsp->data[2];
+ return 0;
+}
+
+/* _ipmi_get_pef_filter_entry - Fetches one Entry from Event Filter Table
+ * identified by Filter ID.
+ *
+ * @filter_id - Filter ID of Entry in Event Filter Table.
+ * @filter_entry - Pointer where to copy Filter Entry data.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_get_pef_filter_entry(struct ipmi_intf *intf, uint8_t filter_id,
+ struct pef_cfgparm_filter_table_entry *filter_entry)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t data[3];
+ uint8_t data_len = 3 * sizeof(uint8_t);
+ int dest_size;
+ if (filter_entry == NULL) {
+ return (-3);
+ }
+
+ dest_size = (int)sizeof(struct pef_cfgparm_filter_table_entry);
+ memset(filter_entry, 0, dest_size);
+ memset(&data, 0, data_len);
+ data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY;
+ data[1] = filter_id;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&data;
+ req.msg.data_len = data_len;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 22 || (rsp->data_len - 1) != dest_size) {
+ return (-2);
+ }
+ memcpy(filter_entry, &rsp->data[1], dest_size);
+ return 0;
+}
+
+/* _ipmi_get_pef_filter_entry_cfg - Fetches configuration of one Entry from
+ * Event Filter Table identified by Filter ID.
+ *
+ * @filter_id - Filter ID of Entry in Event Filter Table.
+ * @filter_entry_cfg - Pointer where to copy Filter Entry configuration.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+int
+_ipmi_get_pef_filter_entry_cfg(struct ipmi_intf *intf, uint8_t filter_id,
+ struct pef_cfgparm_filter_table_data_1 *filter_cfg)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t data[3];
+ uint8_t data_len = 3 * sizeof(uint8_t);
+ int dest_size;
+ if (filter_cfg == NULL) {
+ return (-3);
+ }
+
+ dest_size = (int)sizeof(struct pef_cfgparm_filter_table_data_1);
+ memset(filter_cfg, 0, dest_size);
+ memset(&data, 0, data_len);
+ data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1;
+ data[1] = filter_id;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&data;
+ req.msg.data_len = data_len;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 3 || (rsp->data_len - 1) != dest_size) {
+ return (-2);
+ }
+ memcpy(filter_cfg, &rsp->data[1], dest_size);
+ return 0;
+}
+
+/* _ipmi_get_pef_policy_entry - Fetches one Entry from Alert Policy Table
+ * identified by Policy ID.
+ *
+ * @policy_id - Policy ID of Entry in Alert Policy Table.
+ * @policy_entry - Pointer where to copy Policy Entry data.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_get_pef_policy_entry(struct ipmi_intf *intf, uint8_t policy_id,
+ struct pef_cfgparm_policy_table_entry *policy_entry)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t data[3];
+ uint8_t data_len = 3 * sizeof(uint8_t);
+ int dest_size;
+ if (policy_entry == NULL) {
+ return (-3);
+ }
+
+ dest_size = (int)sizeof(struct pef_cfgparm_policy_table_entry);
+ memset(policy_entry, 0, dest_size);
+ memset(&data, 0, data_len);
+ data[0] = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
+ data[1] = policy_id & PEF_POLICY_TABLE_ID_MASK;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&data;
+ req.msg.data_len = data_len;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 5 || (rsp->data_len - 1) != dest_size) {
+ return (-2);
+ }
+ memcpy(policy_entry, &rsp->data[1], dest_size);
+ return 0;
+}
+
+/* _ipmi_get_pef_filter_table_size - Fetch the Number of Event Filter Entries.
+ * If the number is 0, it means feature is not supported.
+ *
+ * @table_size - ptr to where to store number of entries.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_get_pef_filter_table_size(struct ipmi_intf *intf, uint8_t *table_size)
+{
+ struct ipmi_rs *rsp;
struct ipmi_rq req;
struct pef_cfgparm_selector psel;
- struct pef_cfgparm_policy_table_entry * ptbl, * ptmp;
- uint32_t i;
- uint8_t tbl_size;
+ if (table_size == NULL) {
+ return (-3);
+ }
+
+ *table_size = 0;
+ memset(&psel, 0, sizeof(psel));
+ psel.id = PEF_CFGPARM_ID_PEF_FILTER_TABLE_SIZE;
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&psel;
+ req.msg.data_len = sizeof(psel);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 2) {
+ return (-2);
+ }
+ *table_size = rsp->data[1] & 0x7F;
+ return 0;
+}
+
+/* _ipmi_get_pef_policy_table_size - Fetch the Number of Alert Policy Entries. If the
+ * number is 0, it means feature is not supported.
+ *
+ * @table_size - ptr to where to store number of entries.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_get_pef_policy_table_size(struct ipmi_intf *intf, uint8_t *table_size)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct pef_cfgparm_selector psel;
+
+ if (table_size == NULL) {
+ return (-3);
+ }
+
+ *table_size = 0;
memset(&psel, 0, sizeof(psel));
psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_SIZE;
memset(&req, 0, sizeof(req));
+
req.msg.netfn = IPMI_NETFN_SE;
req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
req.msg.data = (uint8_t *)&psel;
req.msg.data_len = sizeof(psel);
- rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table size");
- if (!rsp)
- return(0);
- tbl_size = (rsp->data[1] & PEF_POLICY_TABLE_SIZE_MASK);
- i = (tbl_size * sizeof(struct pef_cfgparm_policy_table_entry));
- if (!i
- || (ptbl = (struct pef_cfgparm_policy_table_entry *)malloc(i)) == NULL)
- return(0);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 2) {
+ return (-2);
+ }
+ *table_size = rsp->data[1] & 0x7F;
+ return 0;
+}
+
+/* _ipmi_get_pef_system_guid - Fetches System GUID from PEF. This configuration
+ * parameter is optional. If data1 is 0x0, then this GUID is ignored by BMC.
+ *
+ * @system_guid - pointer where to store received data.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+int
+_ipmi_get_pef_system_guid(struct ipmi_intf *intf,
+ struct pef_cfgparm_system_guid *system_guid)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct pef_cfgparm_selector psel;
+ if (system_guid == NULL) {
+ return (-3);
+ }
+ memset(system_guid, 0, sizeof(struct pef_cfgparm_system_guid));
memset(&psel, 0, sizeof(psel));
- psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
- for (ptmp=ptbl, i=1; i<=tbl_size; i++) {
- psel.set = (i & PEF_POLICY_TABLE_ID_MASK);
- rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table entry");
- if (!rsp
- || i != (rsp->data[1] & PEF_POLICY_TABLE_ID_MASK)) {
- lprintf(LOG_ERR, " **Error retrieving %s",
- "Alert policy table entry");
- free(ptbl);
- ptbl = NULL;
- tbl_size = 0;
- break;
- }
- memcpy(ptmp, &rsp->data[1], sizeof(*ptmp));
- ptmp++;
+ psel.id = PEF_CFGPARM_ID_SYSTEM_GUID;
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&psel;
+ req.msg.data_len = sizeof(psel);
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ } else if (rsp->data_len != 18
+ || (rsp->data_len - 2) != sizeof(system_guid->guid)) {
+ return (-2);
+ }
+ system_guid->data1 = rsp->data[1] & 0x1;
+ memcpy(system_guid->guid, &rsp->data[2], sizeof(system_guid->guid));
+ return 0;
+}
+
+/* _ipmi_set_pef_filter_entry_cfg - Sets/updates configuration of Entry in Event
+ * Filter Table identified by Filter ID.
+ *
+ * @filter_id - ID of Entry in Event Filter Table to be updated
+ * @filter_cfg - Pointer to configuration data.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_set_pef_filter_entry_cfg(struct ipmi_intf *intf, uint8_t filter_id,
+ struct pef_cfgparm_filter_table_data_1 *filter_cfg)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ uint8_t data[3];
+ uint8_t data_len = 3 * sizeof(uint8_t);
+ if (filter_cfg == NULL) {
+ return (-3);
}
- *table = ptbl;
- return(tbl_size);
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&data;
+ req.msg.data_len = data_len;
+
+ memset(&data, 0, data_len);
+ data[0] = PEF_CFGPARM_ID_PEF_FILTER_TABLE_DATA_1;
+ data[1] = filter_id;
+ data[2] = filter_cfg->cfg;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ }
+ return 0;
+}
+
+/* _ipmi_set_pef_policy_entry - Sets/updates Entry in Alert Policy Table identified by
+ * Policy ID.
+ *
+ * @policy_id - Policy ID of Entry in Alert Policy Table to be updated
+ * @policy_entry - Pointer to data.
+ *
+ * returns - negative number means error, positive is a ccode.
+ */
+static int
+_ipmi_set_pef_policy_entry(struct ipmi_intf *intf, uint8_t policy_id,
+ struct pef_cfgparm_policy_table_entry *policy_entry)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ struct pef_cfgparm_set_policy_table_entry payload;
+ if (policy_entry == NULL) {
+ return (-3);
+ }
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SE;
+ req.msg.cmd = IPMI_CMD_SET_PEF_CONFIG_PARMS;
+ req.msg.data = (uint8_t *)&payload;
+ req.msg.data_len = sizeof(payload);
+
+ memset(&payload, 0, sizeof(payload));
+ payload.param_selector = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
+ payload.policy_id = policy_id & PEF_POLICY_TABLE_ID_MASK;
+ memcpy(&payload.entry, &policy_entry->entry,
+ sizeof(policy_entry->entry));
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ return (-1);
+ } else if (rsp->ccode != 0) {
+ return rsp->ccode;
+ }
+ return 0;
+}
+
+static void
+ipmi_pef_print_oem_lan_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest)
+{
+ char address[128];
+ int len;
+ int rc;
+ int rlen;
+ int set;
+ uint8_t data[32];
+
+ if (ipmi_get_oem(intf) != IPMI_OEM_DELL) {
+ return;
+ }
+ /* Get # of IPV6 trap destinations */
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_COUNT, 0x00, 0x00, 4, data);
+ if (rc != 0 || dest > data[0]) {
+ return;
+ }
+ ipmi_pef_print_str("Alert destination type", "xxx");
+ ipmi_pef_print_str("PET Community", "xxx");
+ ipmi_pef_print_dec("ACK timeout/retry (secs)", 0);
+ ipmi_pef_print_dec("Retries", 0);
+
+ /* Get IPv6 destination string (may be in multiple sets) */
+ memset(address, 0, sizeof(address));
+ memset(data, 0, sizeof(data));
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, 0x00, dest, 19, data);
+ if (rc != 0) {
+ return;
+ }
+ /* Total length of IPv6 string */
+ len = data[4];
+ if ((rlen = len) > (IPMI_SYSINFO_SET0_SIZE-3)) {
+ /* First set has 11 bytes */
+ rlen = IPMI_SYSINFO_SET0_SIZE - 3;
+ }
+ memcpy(address, data + 8, rlen);
+ for (set = 1; len > 11; set++) {
+ rc = ipmi_mc_getsysinfo(intf, IPMI_SYSINFO_DELL_IPV6_DESTADDR, set, dest, 19, data);
+ if ((rlen = len - 11) >= (IPMI_SYSINFO_SETN_SIZE - 2)) {
+ /* Remaining sets have 14 bytes */
+ rlen = IPMI_SYSINFO_SETN_SIZE - 2;
+ }
+ memcpy(address + (set * 11), data + 3, rlen);
+ len -= rlen+3;
+ }
+ ipmi_pef_print_str("IPv6 Address", address);
}
+/* TODO - rewrite */
static void
ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
{ /*
@@ -325,16 +720,13 @@ ipmi_pef_print_lan_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
pinfo->ip[0], pinfo->ip[1], pinfo->ip[2], pinfo->ip[3]);
ipmi_pef_print_str("IP address", buf);
- sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
- pinfo->mac[0], pinfo->mac[1], pinfo->mac[2],
- pinfo->mac[3], pinfo->mac[4], pinfo->mac[5]);
- ipmi_pef_print_str("MAC address", buf);
+ ipmi_pef_print_str("MAC address", mac2str(pinfo->mac));
}
}
static void
-ipmi_pef_print_serial_dest_dial(struct ipmi_intf * intf, char * label,
- struct pef_serial_cfgparm_selector * ssel)
+ipmi_pef_print_serial_dest_dial(struct ipmi_intf *intf, char *label,
+ struct pef_serial_cfgparm_selector *ssel)
{ /*
// print a dial string
*/
@@ -381,8 +773,8 @@ ipmi_pef_print_serial_dest_dial(struct ipmi_intf * intf, char * label,
}
static void
-ipmi_pef_print_serial_dest_tap(struct ipmi_intf * intf,
- struct pef_serial_cfgparm_selector * ssel)
+ipmi_pef_print_serial_dest_tap(struct ipmi_intf *intf,
+ struct pef_serial_cfgparm_selector *ssel)
{ /*
// print TAP destination info
*/
@@ -431,28 +823,21 @@ ipmi_pef_print_serial_dest_tap(struct ipmi_intf * intf,
/* TODO : additional TAP settings? */
}
+/*
static void
-ipmi_pef_print_serial_dest_ppp(struct ipmi_intf * intf,
- struct pef_serial_cfgparm_selector * ssel)
-{ /*
- // print PPP destination info
- */
-
- /* TODO */
+ipmi_pef_print_serial_dest_ppp(struct ipmi_intf *intf,
+ struct pef_serial_cfgparm_selector *ssel)
+{
}
static void
-ipmi_pef_print_serial_dest_callback(struct ipmi_intf * intf,
- struct pef_serial_cfgparm_selector * ssel)
-{ /*
- // print callback destination info
- */
-
- /* TODO */
+ipmi_pef_print_serial_dest_callback(struct ipmi_intf *intf,
+ struct pef_serial_cfgparm_selector *ssel)
}
+*/
static void
-ipmi_pef_print_serial_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
+ipmi_pef_print_serial_dest(struct ipmi_intf *intf, uint8_t ch, uint8_t dest)
{ /*
// print Serial/PPP alert destination info
*/
@@ -479,6 +864,10 @@ ipmi_pef_print_serial_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
tbl_size = (rsp->data[1] & PEF_SERIAL_DEST_TABLE_SIZE_MASK);
if (!dest || tbl_size == 0) /* Page alerting not supported */
return;
+ if (dest > tbl_size) {
+ ipmi_pef_print_oem_lan_dest(intf, ch, dest - tbl_size);
+ return;
+ }
ssel.id = PEF_SERIAL_CFGPARM_ID_DESTINFO;
ssel.set = dest;
@@ -503,11 +892,11 @@ ipmi_pef_print_serial_dest(struct ipmi_intf * intf, uint8_t ch, uint8_t dest)
ipmi_pef_print_serial_dest_tap(intf, &ssel);
break;
case PEF_SERIAL_DEST_TYPE_PPP:
- ipmi_pef_print_serial_dest_ppp(intf, &ssel);
+ /* ipmi_pef_print_serial_dest_ppp(intf, &ssel); */
break;
case PEF_SERIAL_DEST_TYPE_BASIC_CALLBACK:
case PEF_SERIAL_DEST_TYPE_PPP_CALLBACK:
- ipmi_pef_print_serial_dest_callback(intf, &ssel);
+ /* ipmi_pef_print_serial_dest_callback(intf, &ssel); */
break;
}
}
@@ -529,7 +918,7 @@ ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * bu
static char * classes[] = {"Discrete", "Threshold", "OEM"};
uint16_t offmask;
char * p;
- int i;
+ unsigned int i;
uint8_t t;
ipmi_pef_print_str("Event severity",
@@ -574,170 +963,234 @@ ipmi_pef_print_event_info(struct pef_cfgparm_filter_table_entry * pef, char * bu
ipmi_pef_print_str("Event trigger(s)", buf);
}
+/* ipmi_pef_print_filter_entry - Print-out Entry of Event Filter Table. */
static void
-ipmi_pef_print_entry(struct ipmi_rs * rsp, uint8_t id,
- struct pef_cfgparm_filter_table_entry * pef)
-{ /*
- // print a PEF table entry
- */
- uint8_t wrk, set;
+ipmi_pef_print_filter_entry(struct pef_cfgparm_filter_table_entry *filter_entry)
+{
char buf[128];
+ uint8_t filter_enabled;
+ uint8_t set;
- ipmi_pef_print_dec("PEF table entry", id);
+ ipmi_pef_print_dec("PEF Filter Table entry", filter_entry->data1);
- wrk = !!(pef->entry.config & PEF_CONFIG_ENABLED);
- sprintf(buf, "%sactive", (wrk ? "" : "in"));
- if (pef->entry.config & PEF_CONFIG_PRECONFIGURED)
- strcat(buf, ", pre-configured");
+ filter_enabled = filter_entry->entry.config & PEF_CONFIG_ENABLED;
+ sprintf(buf, "%sabled", (filter_enabled ? "en" : "dis"));
+ switch (filter_entry->entry.config & 0x60) {
+ case 0x40:
+ strcat(buf, ", pre-configured");
+ break;
+ case 0x00:
+ strcat(buf, ", configurable");
+ break;
+ default:
+ /* Covers 0x60 and 0x20 which are reserved */
+ strcat(buf, ", reserved");
+ break;
+ }
ipmi_pef_print_str("Status", buf);
- if (wrk != 0) {
- ipmi_pef_print_1xd("Version", rsp->data[0]);
- ipmi_pef_print_str("Sensor type",
- ipmi_pef_bit_desc(&pef_b2s_sensortypes, pef->entry.sensor_type));
+ if (!filter_enabled) {
+ return;
+ }
- if (pef->entry.sensor_number == PEF_SENSOR_NUMBER_MATCH_ANY)
- ipmi_pef_print_str("Sensor number", "Any");
- else
- ipmi_pef_print_dec("Sensor number", pef->entry.sensor_number);
+ ipmi_pef_print_str("Sensor type",
+ ipmi_pef_bit_desc(&pef_b2s_sensortypes,
+ filter_entry->entry.sensor_type));
- ipmi_pef_print_event_info(pef, buf);
- ipmi_pef_print_str("Action",
- ipmi_pef_bit_desc(&pef_b2s_actions, pef->entry.action));
+ if (filter_entry->entry.sensor_number == PEF_SENSOR_NUMBER_MATCH_ANY) {
+ ipmi_pef_print_str("Sensor number", "Any");
+ } else {
+ ipmi_pef_print_dec("Sensor number",
+ filter_entry->entry.sensor_number);
+ }
- if (pef->entry.action & PEF_ACTION_ALERT) {
- set = (pef->entry.policy_number & PEF_POLICY_NUMBER_MASK);
- ipmi_pef_print_int("Policy set", set);
- }
+ ipmi_pef_print_event_info(filter_entry, buf);
+ ipmi_pef_print_str("Action",
+ ipmi_pef_bit_desc(&pef_b2s_actions,
+ filter_entry->entry.action));
+
+ if (filter_entry->entry.action & PEF_ACTION_ALERT) {
+ set = (filter_entry->entry.policy_number & PEF_POLICY_NUMBER_MASK);
+ ipmi_pef_print_int("Policy set", set);
}
}
-static void
-ipmi_pef_list_entries(struct ipmi_intf * intf)
-{ /*
- // list all PEF table entries
- */
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct pef_cfgparm_selector psel;
- struct pef_cfgparm_filter_table_entry * pcfg;
- uint32_t i;
- uint8_t max_filters;
+/* ipmi_pef2_filter_enable - Enable/Disable specific PEF Event Filter.
+ *
+ * @enable - enable(1) or disable(0) PEF Event Filter.
+ * @filter_id - Filter ID of Entry in Event Filter Table.
+ *
+ * returns - 0 on success, any other value means error.
+ */
+static int
+ipmi_pef2_filter_enable(struct ipmi_intf *intf, uint8_t enable, uint8_t filter_id)
+{
+ struct pef_cfgparm_filter_table_data_1 filter_cfg;
+ int rc;
+ uint8_t filter_table_size;
+
+ rc = _ipmi_get_pef_filter_table_size(intf, &filter_table_size);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ } else if (filter_table_size == 0) {
+ lprintf(LOG_ERR, "PEF Filter isn't supported.");
+ return (-1);
+ } else if (filter_id > filter_table_size) {
+ lprintf(LOG_ERR,
+ "PEF Filter ID out of range. Valid range is (1..%d).",
+ filter_table_size);
+ return (-1);
+ }
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_SE;
- req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
- rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
- if (!rsp
- || (max_filters = ((struct pef_capabilities *)rsp->data)->tblsize) == 0)
- return; /* sssh, not supported */
+ memset(&filter_cfg, 0, sizeof(filter_cfg));
+ rc = _ipmi_set_pef_filter_entry_cfg(intf, filter_id, &filter_cfg);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ }
- memset(&psel, 0, sizeof(psel));
- psel.id = PEF_CFGPARM_ID_PEF_FILTER_TABLE_ENTRY;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_SE;
- req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
- req.msg.data = (uint8_t *)&psel;
- req.msg.data_len = sizeof(psel);
- for (i=1; i<=max_filters; i++) {
- if (i > 1)
- printf("\n");
- psel.set = (i & PEF_FILTER_TABLE_ID_MASK);
- rsp = ipmi_pef_msg_exchange(intf, &req, "PEF table entry");
- if (!rsp
- || (psel.set != (rsp->data[1] & PEF_FILTER_TABLE_ID_MASK))) {
- lprintf(LOG_ERR, " **Error retrieving %s",
- "PEF table entry");
- continue;
- }
- pcfg = (struct pef_cfgparm_filter_table_entry *)&rsp->data[1];
- first_field = 1;
- ipmi_pef_print_entry(rsp, psel.set, pcfg);
+ if (enable != 0) {
+ /* Enable */
+ filter_cfg.cfg |= PEF_FILTER_ENABLED;
+ } else {
+ /* Disable */
+ filter_cfg.cfg &= PEF_FILTER_DISABLED;
}
+ rc = _ipmi_set_pef_filter_entry_cfg(intf, filter_id, &filter_cfg);
+ if (eval_ccode(rc) != 0) {
+ lprintf(LOG_ERR, "Failed to %s PEF Filter ID %d.",
+ enable ? "enable" : "disable",
+ filter_id);
+ return (-1);
+ }
+ printf("PEF Filter ID %" PRIu8 " is %s now.\n", filter_id,
+ enable ? "enabled" : "disabled");
+ return rc;
}
-static void
-ipmi_pef_list_policies(struct ipmi_intf * intf)
-{ /*
- // list PEF alert policies
- */
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct pef_cfgparm_policy_table_entry * ptbl = NULL;
- struct pef_cfgparm_policy_table_entry * ptmp = NULL;
- uint32_t i;
- uint8_t wrk, ch, medium, tbl_size;
-
- tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
- if (!tbl_size) {
- if (ptbl != NULL) {
- free(ptbl);
- ptbl = NULL;
+void
+ipmi_pef2_filter_help(void)
+{
+ lprintf(LOG_NOTICE,
+"usage: pef filter help");
+ lprintf(LOG_NOTICE,
+" pef filter list");
+ lprintf(LOG_NOTICE,
+" pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE,
+" pef filter delete <id = 1..n>");
+}
+
+/* ipmi_pef2_filter - Handle processing of "filter" CLI args. */
+int
+ipmi_pef2_filter(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_filter_help();
+ rc = (-1);
+ } else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_filter_help();
+ rc = 0;
+ } else if (!strncmp(argv[0], "list\0", 5)) {
+ rc = ipmi_pef2_list_filters(intf);
+ } else if (!strncmp(argv[0], "enable\0", 7)
+ ||(!strncmp(argv[0], "disable\0", 8))) {
+ uint8_t enable;
+ uint8_t filter_id;
+ if (argc != 2) {
+ lprintf(LOG_ERR, "Not enough arguments given.");
+ ipmi_pef2_filter_help();
+ return (-1);
}
- return;
+ if (str2uchar(argv[1], &filter_id) != 0) {
+ lprintf(LOG_ERR, "Invalid PEF Event Filter ID given: %s", argv[1]);
+ return (-1);
+ } else if (filter_id < 1) {
+ lprintf(LOG_ERR, "PEF Event Filter ID out of range. "
+ "Valid range is <1..255>.");
+ return (-1);
+ }
+ if (!strncmp(argv[0], "enable\0", 7)) {
+ enable = 1;
+ } else {
+ enable = 0;
+ }
+ rc = ipmi_pef2_filter_enable(intf, enable, filter_id);
+ } else if (!strncmp(argv[0], "create\0", 7)) {
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else if (!strncmp(argv[0], "delete\0", 7)) {
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else {
+ lprintf(LOG_ERR, "Invalid PEF Filter command: %s", argv[0]);
+ ipmi_pef2_filter_help();
+ rc = 1;
}
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = IPMI_CMD_GET_CHANNEL_INFO;
- req.msg.data = &ch;
- req.msg.data_len = sizeof(ch);
- for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
- if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
- if (i > 1)
- printf("\n");
- first_field = 1;
- ipmi_pef_print_dec("Alert policy table entry",
- (ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
- ipmi_pef_print_dec("Policy set",
- (ptmp->entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
- ipmi_pef_print_str("Policy entry rule",
- ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
-
- if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
- ipmi_pef_print_str("Event-specific", "true");
-// continue;
- }
- wrk = ptmp->entry.chan_dest;
-
- /* channel/description */
- ch = (wrk & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT;
- rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
- if (!rsp || rsp->data[0] != ch) {
- lprintf(LOG_ERR, " **Error retrieving %s",
- "Channel info");
- continue;
- }
- medium = rsp->data[1];
- ipmi_pef_print_dec("Channel number", ch);
- ipmi_pef_print_str("Channel medium",
- ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
-
- /* destination/description */
- wrk &= PEF_POLICY_DESTINATION_MASK;
- switch (medium) {
- case PEF_CH_MEDIUM_TYPE_LAN:
- ipmi_pef_print_lan_dest(intf, ch, wrk);
- break;
- case PEF_CH_MEDIUM_TYPE_SERIAL:
- ipmi_pef_print_serial_dest(intf, ch, wrk);
- break;
- default:
- ipmi_pef_print_dest(intf, ch, wrk);
- break;
- }
+ return rc;
+}
+
+/* ipmi_pef2_get_info - Reports PEF capabilities + System GUID */
+static int
+ipmi_pef2_get_info(struct ipmi_intf *intf)
+{
+ struct pef_capabilities pcap;
+ struct pef_cfgparm_system_guid psys_guid;
+ struct ipmi_guid_t guid;
+ int rc;
+ uint8_t *guid_ptr = NULL;
+ uint8_t policy_table_size;
+
+ rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size);
+ if (eval_ccode(rc) != 0) {
+ lprintf(LOG_WARN, "Failed to get size of PEF Policy Table.");
+ policy_table_size = 0;
+ }
+ rc = _ipmi_get_pef_capabilities(intf, &pcap);
+ if (eval_ccode(rc) != 0) {
+ lprintf(LOG_ERR, "Failed to get PEF Capabilities.");
+ return (-1);
+ }
+
+ ipmi_pef_print_1xd("Version", pcap.version);
+ ipmi_pef_print_dec("PEF Event Filter count",
+ pcap.event_filter_count);
+ ipmi_pef_print_dec("PEF Alert Policy Table size",
+ policy_table_size);
+
+ rc = _ipmi_get_pef_system_guid(intf, &psys_guid);
+ if (rc != 0x80 && eval_ccode(rc) != 0) {
+ lprintf(LOG_ERR, "Failed to get PEF System GUID. %i", rc);
+ return (-1);
+ } else if (psys_guid.data1 == 0x1) {
+ /* IPMI_CMD_GET_SYSTEM_GUID */
+ guid_ptr = &psys_guid.guid[0];
+ } else {
+ rc = _ipmi_mc_get_guid(intf, &guid);
+ if (rc == 0) {
+ guid_ptr = (uint8_t *)&guid;
}
}
- free(ptbl);
- ptbl = NULL;
+ /* Got GUID? */
+ if (guid_ptr) {
+ ipmi_pef_print_guid(guid_ptr);
+ }
+ ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, pcap.actions);
+ return 0;
}
-static void
-ipmi_pef_get_status(struct ipmi_intf * intf)
-{ /*
- // report the PEF status
- */
- struct ipmi_rs * rsp;
+/* ipmi_pef2_get_status - TODO rewrite - report the PEF status */
+static int
+ipmi_pef2_get_status(struct ipmi_intf *intf)
+{
+ struct ipmi_rs *rsp;
struct ipmi_rq req;
struct pef_cfgparm_selector psel;
char tbuf[40];
@@ -751,7 +1204,7 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"Last S/W processed ID");
- return;
+ return (-1);
}
memcpy(&timei, rsp->data, sizeof(timei));
#if WORDS_BIGENDIAN
@@ -777,7 +1230,7 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"PEF control");
- return;
+ return (-1);
}
ipmi_pef_print_flags(&pef_b2s_control, P_ABLE, rsp->data[1]);
@@ -786,102 +1239,312 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
if (!rsp) {
lprintf(LOG_ERR, " **Error retrieving %s",
"PEF action");
- return;
+ return (-1);
}
ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
+ return 0;
}
-static void
-ipmi_pef_get_info(struct ipmi_intf * intf)
-{ /*
- // report PEF capabilities + System GUID
- */
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
- struct pef_capabilities * pcap;
- struct pef_cfgparm_selector psel;
- struct pef_cfgparm_policy_table_entry * ptbl = NULL;
- uint8_t * uid;
- uint8_t actions, tbl_size;
+/* ipmi_pef2_list_filters - List all entries in PEF Event Filter Table. */
+static int
+ipmi_pef2_list_filters(struct ipmi_intf *intf)
+{
+ struct pef_capabilities pcap;
+ struct pef_cfgparm_filter_table_entry filter_entry;
+ int rc;
+ uint8_t i;
+
+ rc = _ipmi_get_pef_capabilities(intf, &pcap);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ } else if (pcap.event_filter_count == 0) {
+ lprintf(LOG_ERR, "PEF Event Filtering isn't supported.");
+ return (-1);
+ }
- tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
- if (ptbl != NULL) {
- free(ptbl);
- ptbl = NULL;
+ for (i = 1; i <= pcap.event_filter_count; i++) {
+ first_field = 1;
+ rc = _ipmi_get_pef_filter_entry(intf, i, &filter_entry);
+ if (eval_ccode(rc) != 0) {
+ lprintf(LOG_ERR, "Failed to get PEF Event Filter Entry %i.",
+ i);
+ continue;
+ }
+ ipmi_pef_print_filter_entry(&filter_entry);
+ printf("\n");
}
+ return 0;
+}
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_SE;
- req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
- rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
- if (!rsp)
- return;
- pcap = (struct pef_capabilities *)rsp->data;
+/* ipmi_pef2_list_policies - List Entries in PEF Alert Policy Table. */
+static int
+ipmi_pef2_list_policies(struct ipmi_intf *intf)
+{
+ struct channel_info_t channel_info;
+ struct pef_cfgparm_policy_table_entry entry;
+ int rc;
+ uint8_t dest;
+ uint8_t i;
+ uint8_t policy_table_size;
+
+ rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ } else if (policy_table_size == 0) {
+ lprintf(LOG_ERR, "PEF Alert Policy isn't supported.");
+ return (-1);
+ }
- ipmi_pef_print_1xd("Version", pcap->version);
- ipmi_pef_print_dec("PEF table size", pcap->tblsize);
- ipmi_pef_print_dec("Alert policy table size", tbl_size);
- actions = pcap->actions;
+ for (i = 1; i <= policy_table_size; i++) {
+ first_field = 1;
+ rc = _ipmi_get_pef_policy_entry(intf, i, &entry);
+ if (eval_ccode(rc) != 0) {
+ continue;
+ }
- memset(&psel, 0, sizeof(psel));
- psel.id = PEF_CFGPARM_ID_SYSTEM_GUID;
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_SE;
- req.msg.cmd = IPMI_CMD_GET_PEF_CONFIG_PARMS;
- req.msg.data = (uint8_t *)&psel;
- req.msg.data_len = sizeof(psel);
- rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
- uid = NULL;
- if (rsp && (rsp->data[1] & PEF_SYSTEM_GUID_USED_IN_PET))
- uid = &rsp->data[2];
- else {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.cmd = IPMI_CMD_GET_SYSTEM_GUID;
- rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
- if (rsp)
- uid = &rsp->data[0];
- }
- if (uid) { /* got GUID? */
- if (verbose)
- printf(pef_fld_fmts[F_UID][0], KYWD_LENGTH, "System GUID",
- uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
- uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
- else
- printf(pef_fld_fmts[F_UID][1],
- uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
- uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
+ ipmi_pef_print_dec("Alert policy table entry",
+ (entry.data1 & PEF_POLICY_TABLE_ID_MASK));
+ ipmi_pef_print_dec("Policy set",
+ (entry.entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
+ ipmi_pef_print_str("State",
+ entry.entry.policy & PEF_POLICY_ENABLED ? "enabled" : "disabled");
+ ipmi_pef_print_str("Policy entry rule",
+ ipmi_pef_bit_desc(&pef_b2s_policies,
+ (entry.entry.policy & PEF_POLICY_FLAGS_MASK)));
+
+ if (entry.entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
+ ipmi_pef_print_str("Event-specific", "true");
+ }
+ channel_info.channel = ((entry.entry.chan_dest &
+ PEF_POLICY_CHANNEL_MASK) >>
+ PEF_POLICY_CHANNEL_SHIFT);
+ rc = _ipmi_get_channel_info(intf, &channel_info);
+ if (eval_ccode(rc) != 0) {
+ continue;
+ }
+ ipmi_pef_print_dec("Channel number", channel_info.channel);
+ ipmi_pef_print_str("Channel medium",
+ ipmi_pef_bit_desc(&pef_b2s_ch_medium,
+ channel_info.medium));
+ dest = entry.entry.chan_dest & PEF_POLICY_DESTINATION_MASK;
+ switch (channel_info.medium) {
+ case PEF_CH_MEDIUM_TYPE_LAN:
+ ipmi_pef_print_lan_dest(intf, channel_info.channel,
+ dest);
+ break;
+ case PEF_CH_MEDIUM_TYPE_SERIAL:
+ ipmi_pef_print_serial_dest(intf, channel_info.channel,
+ dest);
+ break;
+ default:
+ ipmi_pef_print_dest(intf, channel_info.channel, dest);
+ break;
+ }
+ printf("\n");
}
- ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
+ return 0;
}
-int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
-{ /*
- // PEF subcommand handling
- */
- int help = 0;
- int rc = 0;
-
- if (!argc || !strncmp(argv[0], "info", 4))
- ipmi_pef_get_info(intf);
- else if (!strncmp(argv[0], "help", 4))
- help = 1;
- else if (!strncmp(argv[0], "status", 6))
- ipmi_pef_get_status(intf);
- else if (!strncmp(argv[0], "policy", 6))
- ipmi_pef_list_policies(intf);
- else if (!strncmp(argv[0], "list", 4))
- ipmi_pef_list_entries(intf);
- else {
- help = 1;
- rc = -1;
- lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
+void
+ipmi_pef2_policy_help(void)
+{
+ lprintf(LOG_NOTICE,
+"usage: pef policy help");
+ lprintf(LOG_NOTICE,
+" pef policy list");
+ lprintf(LOG_NOTICE,
+" pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE,
+" pef policy delete <id = 1..n>");
+}
+
+/* ipmi_pef2_policy_enable - Enable/Disable specific PEF policy
+ *
+ * @enable - enable(1) or disable(0) PEF Alert Policy
+ * @policy_id - Policy ID of Entry in Alert Policy Table.
+ *
+ * returns - 0 on success, any other value means error.
+ */
+static int
+ipmi_pef2_policy_enable(struct ipmi_intf *intf, int enable, uint8_t policy_id)
+{
+ struct pef_cfgparm_policy_table_entry policy_entry;
+ int rc;
+ uint8_t policy_table_size;
+
+ rc = _ipmi_get_pef_policy_table_size(intf, &policy_table_size);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ } else if (policy_table_size == 0) {
+ lprintf(LOG_ERR, "PEF Policy isn't supported.");
+ return (-1);
+ } else if (policy_id > policy_table_size) {
+ lprintf(LOG_ERR,
+ "PEF Policy ID out of range. Valid range is (1..%d).",
+ policy_table_size);
+ return (-1);
}
- if (help)
- lprintf(LOG_NOTICE, "PEF commands: info status policy list");
- else if (!verbose)
- printf("\n");
+ memset(&policy_entry, 0, sizeof(policy_entry));
+ rc = _ipmi_get_pef_policy_entry(intf, policy_id, &policy_entry);
+ if (eval_ccode(rc) != 0) {
+ return (-1);
+ }
+
+ if (enable != 0) {
+ /* Enable */
+ policy_entry.entry.policy |= PEF_POLICY_ENABLED;
+ } else {
+ /* Disable */
+ policy_entry.entry.policy &= PEF_POLICY_DISABLED;
+ }
+ rc = _ipmi_set_pef_policy_entry(intf, policy_id, &policy_entry);
+ if (eval_ccode(rc) != 0) {
+ lprintf(LOG_ERR, "Failed to %s PEF Policy ID %d.",
+ enable ? "enable" : "disable",
+ policy_id);
+ return (-1);
+ }
+ printf("PEF Policy ID %" PRIu8 " is %s now.\n", policy_id,
+ enable ? "enabled" : "disabled");
+ return rc;
+}
+
+/* ipmi_pef2_policy - Handle processing of "policy" CLI args. */
+int
+ipmi_pef2_policy(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_policy_help();
+ rc = (-1);
+ } else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_policy_help();
+ rc = 0;
+ } else if (!strncmp(argv[0], "list\0", 5)) {
+ rc = ipmi_pef2_list_policies(intf);
+ } else if (!strncmp(argv[0], "enable\0", 7)
+ || !strncmp(argv[0], "disable\0", 8)) {
+ uint8_t enable;
+ uint8_t policy_id;
+ if (argc != 2) {
+ lprintf(LOG_ERR, "Not enough arguments given.");
+ ipmi_pef2_policy_help();
+ return (-1);
+ }
+ if (str2uchar(argv[1], &policy_id) != 0) {
+ lprintf(LOG_ERR, "Invalid PEF Policy ID given: %s", argv[1]);
+ return (-1);
+ } else if (policy_id < 1 || policy_id > 127) {
+ lprintf(LOG_ERR, "PEF Policy ID out of range. Valid range is <1..127>.");
+ return (-1);
+ }
+ if (!strncmp(argv[0], "enable\0", 7)) {
+ enable = 1;
+ } else {
+ enable = 0;
+ }
+ rc = ipmi_pef2_policy_enable(intf, enable, policy_id);
+ } else if (!strncmp(argv[0], "create\0", 7)) {
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else if (!strncmp(argv[0], "delete\0", 7)) {
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else {
+ lprintf(LOG_ERR, "Invalid PEF Policy command: %s", argv[0]);
+ ipmi_pef2_policy_help();
+ rc = 1;
+ }
+ return rc;
+}
+
+/* ipmi_pef2_help - print-out help text. */
+void
+ipmi_pef2_help(void)
+{
+ lprintf(LOG_NOTICE,
+"usage: pef help");
+ lprintf(LOG_NOTICE,
+" pef capabilities");
+ lprintf(LOG_NOTICE,
+" pef event <params>");
+ lprintf(LOG_NOTICE,
+" pef filter list");
+ lprintf(LOG_NOTICE,
+" pef filter enable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef filter disable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef filter create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE,
+" pef filter delete <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef info");
+ lprintf(LOG_NOTICE,
+" pef policy list");
+ lprintf(LOG_NOTICE,
+" pef policy enable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef policy disable <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef policy create <id = 1..n> <params>");
+ lprintf(LOG_NOTICE,
+" pef policy delete <id = 1..n>");
+ lprintf(LOG_NOTICE,
+" pef pet ack <params>");
+ lprintf(LOG_NOTICE,
+" pef status");
+ lprintf(LOG_NOTICE,
+" pef timer get");
+ lprintf(LOG_NOTICE,
+" pef timer set <0x00-0xFF>");
+}
+int ipmi_pef_main(struct ipmi_intf *intf, int argc, char **argv)
+{
+ int rc = 0;
+
+ if (argc < 1) {
+ lprintf(LOG_ERR, "Not enough parameters given.");
+ ipmi_pef2_help();
+ rc = (-1);
+ } else if (!strncmp(argv[0], "help\0", 5)) {
+ ipmi_pef2_help();
+ rc = 0;
+ } else if (!strncmp(argv[0], "capabilities\0", 13)) {
+ /* rc = ipmi_pef2_get_capabilities(intf); */
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else if (!strncmp(argv[0], "event\0", 6)) {
+ /* rc = ipmi_pef2_event(intf, (argc - 1), ++argv); */
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else if (!strncmp(argv[0], "filter\0", 7)) {
+ rc = ipmi_pef2_filter(intf, (argc - 1), ++argv);
+ } else if (!strncmp(argv[0], "info\0", 5)) {
+ rc = ipmi_pef2_get_info(intf);
+ } else if (!strncmp(argv[0], "pet\0", 4)) {
+ /* rc = ipmi_pef2_pet(intf, (argc - 1), ++argv); */
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else if (!strncmp(argv[0], "policy\0", 7)) {
+ rc = ipmi_pef2_policy(intf, (argc - 1), ++argv);
+ } else if (!strncmp(argv[0], "status\0", 7)) {
+ rc = ipmi_pef2_get_status(intf);
+ } else if (!strncmp(argv[0], "timer\0", 6)) {
+ /* rc = ipmi_pef2_timer(intf, (argc - 1), ++argv); */
+ lprintf(LOG_ERR, "Not implemented.");
+ rc = 1;
+ } else {
+ lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
+ rc = (-1);
+ }
return rc;
}
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index 70f845d..c7d9c8e 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -2301,7 +2301,7 @@ uint8_t
ipmi_picmg_ipmb_address(struct ipmi_intf *intf) {
struct ipmi_rq req;
struct ipmi_rs *rsp;
- char msg_data;
+ uint8_t msg_data;
if (!intf->picmg_avail) {
return 0;
@@ -2336,12 +2336,13 @@ picmg_discover(struct ipmi_intf *intf) {
* PICMG Extension Version 2.0 (PICMG 3.0 Revision 1.0 ATCA) to
* PICMG Extension Version 2.3 (PICMG 3.0 Revision 3.0 ATCA)
* PICMG Extension Version 4.1 (PICMG 3.0 Revision 3.0 AMC)
+ * PICMG Extension Version 5.0 (MTCA.0 R1.0)
*/
/* First, check if PICMG extension is available and supported */
struct ipmi_rq req;
struct ipmi_rs *rsp;
- char msg_data;
+ uint8_t msg_data;
uint8_t picmg_avail = 0;
memset(&req, 0, sizeof(req));
@@ -2366,8 +2367,9 @@ picmg_discover(struct ipmi_intf *intf) {
} else if (rsp->data[0] != 0) {
lprintf(LOG_INFO,"Invalid Get PICMG Properties group extension %#x",
rsp->data[0]);
- } else if ((rsp->data[1] & 0x0F) != PICMG_ATCA_MAJOR_VERSION
- && (rsp->data[1] & 0x0F) != PICMG_AMC_MAJOR_VERSION) {
+ } else if ((rsp->data[1] & 0x0F) != PICMG_EXTENSION_ATCA_MAJOR_VERSION
+ && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_AMC0_MAJOR_VERSION
+ && (rsp->data[1] & 0x0F) != PICMG_EXTENSION_UTCA_MAJOR_VERSION) {
lprintf(LOG_INFO,"Unknown PICMG Extension Version %d.%d",
(rsp->data[1] & 0x0F), (rsp->data[1] >> 4));
} else {
diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
index e3122dc..2a9cbe3 100644
--- a/lib/ipmi_sdr.c
+++ b/lib/ipmi_sdr.c
@@ -689,32 +689,6 @@ ipmi_sdr_get_sensor_event_enable(struct ipmi_intf *intf, uint8_t sensor,
return rsp;
}
-/* ipmi_sdr_get_sensor_type_desc - Get sensor type descriptor
- *
- * @type: ipmi sensor type
- *
- * returns
- * string from sensor_type_desc
- * or "reserved"
- * or "OEM reserved"
- */
-const char *
-ipmi_sdr_get_sensor_type_desc(const uint8_t type)
-{
- static char desc[32];
- memset(desc, 0, 32);
- if (type <= SENSOR_TYPE_MAX)
- return sensor_type_desc[type];
- if (type < 0xc0)
- snprintf(desc, 32, "reserved #%02x", type);
- else
- {
- snprintf(desc, 32, oemval2str(sdriana,type,ipmi_oem_sdr_type_vals),
- type);
- }
- return desc;
-}
-
/* ipmi_sdr_get_thresh_status - threshold status indicator
*
* @rsp: response from Get Sensor Reading comand
@@ -1014,21 +988,21 @@ ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
switch (numeric_fmt) {
case DISCRETE_SENSOR:
if (rsp->data_len == 2) {
- ipmi_sdr_print_discrete_state("Assertion Events",
+ ipmi_sdr_print_discrete_state(intf, "Assertion Events",
sensor_type, event_type,
rsp->data[1], 0);
} else if (rsp->data_len > 2) {
- ipmi_sdr_print_discrete_state("Assertion Events",
+ ipmi_sdr_print_discrete_state(intf, "Assertion Events",
sensor_type, event_type,
rsp->data[1],
rsp->data[2]);
}
if (rsp->data_len == 4) {
- ipmi_sdr_print_discrete_state("Deassertion Events",
+ ipmi_sdr_print_discrete_state(intf, "Deassertion Events",
sensor_type, event_type,
rsp->data[3], 0);
} else if (rsp->data_len > 4) {
- ipmi_sdr_print_discrete_state("Deassertion Events",
+ ipmi_sdr_print_discrete_state(intf, "Deassertion Events",
sensor_type, event_type,
rsp->data[3],
rsp->data[4]);
@@ -1081,22 +1055,23 @@ ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
}
static int
-ipmi_sdr_print_sensor_mask(struct sdr_record_mask *mask,
- uint8_t sensor_type,
- uint8_t event_type, int numeric_fmt)
+ipmi_sdr_print_sensor_mask(struct ipmi_intf *intf,
+ struct sdr_record_mask *mask,
+ uint8_t sensor_type,
+ uint8_t event_type, int numeric_fmt)
{
/* iceblink - don't print some event status fields - CVS rev1.53 */
return 0;
switch (numeric_fmt) {
case DISCRETE_SENSOR:
- ipmi_sdr_print_discrete_state("Assert Event Mask", sensor_type,
+ ipmi_sdr_print_discrete_state(intf, "Assert Event Mask", sensor_type,
event_type,
mask->type.discrete.
assert_event & 0xff,
(mask->type.discrete.
assert_event & 0xff00) >> 8);
- ipmi_sdr_print_discrete_state("Deassert Event Mask",
+ ipmi_sdr_print_discrete_state(intf, "Deassert Event Mask",
sensor_type, event_type,
mask->type.discrete.
deassert_event & 0xff,
@@ -1224,21 +1199,21 @@ ipmi_sdr_print_sensor_event_enable(struct ipmi_intf *intf,
case DISCRETE_SENSOR:
/* discrete */
if (rsp->data_len == 2) {
- ipmi_sdr_print_discrete_state("Assertions Enabled",
+ ipmi_sdr_print_discrete_state(intf, "Assertions Enabled",
sensor_type, event_type,
rsp->data[1], 0);
} else if (rsp->data_len > 2) {
- ipmi_sdr_print_discrete_state("Assertions Enabled",
+ ipmi_sdr_print_discrete_state(intf, "Assertions Enabled",
sensor_type, event_type,
rsp->data[1],
rsp->data[2]);
}
if (rsp->data_len == 4) {
- ipmi_sdr_print_discrete_state("Deassertions Enabled",
+ ipmi_sdr_print_discrete_state(intf, "Deassertions Enabled",
sensor_type, event_type,
rsp->data[3], 0);
} else if (rsp->data_len > 4) {
- ipmi_sdr_print_discrete_state("Deassertions Enabled",
+ ipmi_sdr_print_discrete_state(intf, "Deassertions Enabled",
sensor_type, event_type,
rsp->data[3],
rsp->data[4]);
@@ -1381,8 +1356,9 @@ print_sensor_min_max(struct sdr_record_full_sensor *full)
* returns void
*/
static void
-print_csv_discrete(struct sdr_record_common_sensor *sensor,
- const struct sensor_reading *sr)
+print_csv_discrete(struct ipmi_intf *intf,
+ struct sdr_record_common_sensor *sensor,
+ const struct sensor_reading *sr)
{
if (!sr->s_reading_valid || sr->s_reading_unavailable) {
printf("%02Xh,ns,%d.%d,No Reading",
@@ -1400,7 +1376,7 @@ print_csv_discrete(struct sdr_record_common_sensor *sensor,
printf("ok,%d.%d,",
sensor->entity.id,
sensor->entity.instance);
- ipmi_sdr_print_discrete_state_mini(NULL, ", ",
+ ipmi_sdr_print_discrete_state_mini(intf, NULL, ", ",
sensor->sensor.type,
sensor->event_type,
sr->s_data2,
@@ -1430,7 +1406,7 @@ ipmi_sdr_read_sensor_value(struct ipmi_intf *intf,
memset(&sr, 0, sizeof(sr));
switch (sdr_record_type) {
- int idlen;
+ unsigned int idlen;
case (SDR_RECORD_TYPE_FULL_SENSOR):
sr.full = (struct sdr_record_full_sensor *)sensor;
idlen = sr.full->id_code & 0x1f;
@@ -1542,7 +1518,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
uint8_t sdr_record_type)
{
char sval[16];
- int i = 0;
+ unsigned int i = 0;
uint8_t target, lun, channel;
struct sensor_reading *sr;
@@ -1567,7 +1543,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
printf("%s,", sr->s_id);
if (!IS_THRESHOLD_SENSOR(sensor)) {
/* Discrete/Non-Threshold */
- print_csv_discrete(sensor, sr);
+ print_csv_discrete(intf, sensor, sr);
printf("\n");
}
else {
@@ -1581,7 +1557,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
printf("%s,%s", sr->s_a_units,
ipmi_sdr_get_thresh_status(sr, "ns"));
} else { /* Discrete/Threshold */
- print_csv_discrete(sensor, sr);
+ print_csv_discrete(intf, sensor, sr);
}
} else {
printf(",,ns");
@@ -1589,10 +1565,9 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
if (verbose) {
printf(",%d.%d,%s,%s,",
- sensor->entity.id, sensor->entity.instance,
- val2str(sensor->entity.id, entity_id_vals),
- ipmi_sdr_get_sensor_type_desc(sensor->sensor.
- type));
+ sensor->entity.id, sensor->entity.instance,
+ val2str(sensor->entity.id, entity_id_vals),
+ ipmi_get_sensor_type(intf, sensor->sensor.type));
if (sr->full) {
SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read,
@@ -1712,7 +1687,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
printf("%s %s", sr->s_a_str, sr->s_a_units);
header = ", ";
}
- ipmi_sdr_print_discrete_state_mini(header, ", ",
+ ipmi_sdr_print_discrete_state_mini(intf, header, ", ",
sensor->sensor.type,
sensor->event_type,
sr->s_data2,
@@ -1740,7 +1715,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
if (!IS_THRESHOLD_SENSOR(sensor)) {
/* Discrete */
printf(" Sensor Type (Discrete): %s (0x%02x)\n",
- ipmi_sdr_get_sensor_type_desc(sensor->sensor.type),
+ ipmi_get_sensor_type(intf, sensor->sensor.type),
sensor->sensor.type);
lprintf(LOG_DEBUG, " Event Type Code : 0x%02x",
sensor->event_type);
@@ -1776,12 +1751,12 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
break;
}
- ipmi_sdr_print_discrete_state("States Asserted",
+ ipmi_sdr_print_discrete_state(intf, "States Asserted",
sensor->sensor.type,
sensor->event_type,
sr->s_data2,
sr->s_data3);
- ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type,
+ ipmi_sdr_print_sensor_mask(intf, &sensor->mask, sensor->sensor.type,
sensor->event_type, DISCRETE_SENSOR);
ipmi_sdr_print_sensor_event_status(intf,
sensor->keys.sensor_num,
@@ -1804,7 +1779,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
return 0; /* done */
}
printf(" Sensor Type (Threshold) : %s (0x%02x)\n",
- ipmi_sdr_get_sensor_type_desc(sensor->sensor.type),
+ ipmi_get_sensor_type(intf, sensor->sensor.type),
sensor->sensor.type);
printf(" Sensor Reading : ");
@@ -1945,7 +1920,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
printf("\n");
}
- ipmi_sdr_print_sensor_mask(&sensor->mask,
+ ipmi_sdr_print_sensor_mask(intf, &sensor->mask,
sensor->sensor.type,
sensor->event_type, ANALOG_SENSOR);
ipmi_sdr_print_sensor_event_status(intf,
@@ -1988,46 +1963,43 @@ get_offset(uint8_t x)
* no meaningful return value
*/
void
-ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator,
+ipmi_sdr_print_discrete_state_mini(struct ipmi_intf *intf,
+ const char *header, const char *separator,
uint8_t sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2)
{
- uint8_t typ;
- struct ipmi_event_sensor_types *evt;
+ const struct ipmi_event_sensor_types *evt;
int pre = 0, c = 0;
if (state1 == 0 && (state2 & 0x7f) == 0)
return;
- if (event_type == 0x6f) {
- evt = sensor_specific_types;
- typ = sensor_type;
- } else {
- evt = generic_event_types;
- typ = event_type;
- }
-
if (header)
printf("%s", header);
- for (; evt->type != NULL; evt++) {
- if ((evt->code != typ) ||
- (evt->data != 0xFF))
+ for (evt = ipmi_get_first_event_sensor_type(intf, sensor_type, event_type);
+ evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) {
+ if (evt->data != 0xFF) {
continue;
+ }
if (evt->offset > 7) {
if ((1 << (evt->offset - 8)) & (state2 & 0x7f)) {
- if (pre++ != 0)
+ if (pre++ != 0) {
printf("%s", separator);
- if (evt->desc)
+ }
+ if (evt->desc) {
printf("%s", evt->desc);
+ }
}
} else {
if ((1 << evt->offset) & state1) {
- if (pre++ != 0)
+ if (pre++ != 0) {
printf("%s", separator);
- if (evt->desc)
+ }
+ if (evt->desc) {
printf("%s", evt->desc);
+ }
}
}
c++;
@@ -2045,32 +2017,24 @@ ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator,
* no meaningful return value
*/
void
-ipmi_sdr_print_discrete_state(const char *desc,
+ipmi_sdr_print_discrete_state(struct ipmi_intf *intf, const char *desc,
uint8_t sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2)
{
- uint8_t typ;
- struct ipmi_event_sensor_types *evt;
+ const struct ipmi_event_sensor_types *evt;
int pre = 0, c = 0;
if (state1 == 0 && (state2 & 0x7f) == 0)
return;
- if (event_type == 0x6f) {
- evt = sensor_specific_types;
- typ = sensor_type;
- } else {
- evt = generic_event_types;
- typ = event_type;
- }
-
- for (; evt->type != NULL; evt++) {
- if ((evt->code != typ) ||
- (evt->data != 0xFF))
+ for (evt = ipmi_get_first_event_sensor_type(intf, sensor_type, event_type);
+ evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) {
+ if (evt->data != 0xFF) {
continue;
+ }
if (pre == 0) {
- printf(" %-21s : %s\n", desc, evt->type);
+ printf(" %-21s : %s\n", desc, ipmi_get_sensor_type(intf, sensor_type));
pre = 1;
}
@@ -2129,7 +2093,7 @@ ipmi_sdr_print_sensor_eventonly(struct ipmi_intf *intf,
sensor->entity.id, sensor->entity.instance,
val2str(sensor->entity.id, entity_id_vals));
printf("Sensor Type : %s (0x%02x)\n",
- ipmi_sdr_get_sensor_type_desc(sensor->sensor_type),
+ ipmi_get_sensor_type(intf, sensor->sensor_type),
sensor->sensor_type);
lprintf(LOG_DEBUG, "Event Type Code : 0x%02x",
sensor->event_type);
@@ -2509,8 +2473,8 @@ ipmi_sdr_print_sensor_oem(struct ipmi_intf *intf, struct sdr_record_oem *oem)
* returns -1 on error
*/
int
-ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id,
- uint8_t type,uint8_t * raw)
+ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf, uint16_t id,
+ uint8_t type, uint8_t *raw)
{
union {
struct sdr_record_full_sensor *full;
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c
index b6629a2..8b0395e 100644
--- a/lib/ipmi_sel.c
+++ b/lib/ipmi_sel.c
@@ -49,6 +49,7 @@
#include <ipmitool/ipmi_sdr.h>
#include <ipmitool/ipmi_fru.h>
#include <ipmitool/ipmi_sensor.h>
+#include <ipmitool/ipmi_strings.h>
extern int verbose;
static int sel_extended = 0;
@@ -446,13 +447,14 @@ ipmi_sel_add_entries_fromfile(struct ipmi_intf * intf, const char * filename)
return rc;
}
-static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
- { 0x70 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 1", "Code Assert" },
- { 0x71 , 0x00 , 0xff, IPMI_EVENT_CLASS_DISCRETE , "OEM Firmware Info 2", "Code Assert" },
+static struct ipmi_event_sensor_types oem_kontron_event_reading_types[] __attribute__((unused)) = {
+ { 0x70 , 0x00 , 0xff, "Code Assert" },
+ { 0x71 , 0x00 , 0xff, "Code Assert" },
+ { 0, 0, 0xFF, NULL }
};
char *
-get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
+get_kontron_evt_desc(struct ipmi_intf *intf, struct sel_event_record * rec)
{
char * description = NULL;
/*
@@ -462,8 +464,8 @@ get_kontron_evt_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
/* Only standard records are defined so far */
if( rec->record_type < 0xC0 ){
- struct ipmi_event_sensor_types *st=NULL;
- for ( st=oem_kontron_event_reading_types ; st->type != NULL; st++){
+ const struct ipmi_event_sensor_types *st=NULL;
+ for ( st=oem_kontron_event_types ; st->desc != NULL; st++){
if (st->code == rec->sel_type.standard_type.event_type ){
size_t len =strlen(st->desc);
description = (char*)malloc( len + 1 );
@@ -546,7 +548,7 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
struct ipmi_rs *rsp;
struct ipmi_rq req;
char *desc = NULL;
- int chipset_type = 1;
+ int chipset_type = 4;
int data1;
int data2;
int data3;
@@ -612,12 +614,48 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
break;
}
}
+ for (i = 0; supermicro_older[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_older[i]) {
+ chipset_type = 0;
+ break;
+ }
+ }
+ for (i = 0; supermicro_romely[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_romely[i]) {
+ chipset_type = 1;
+ break;
+ }
+ }
for (i = 0; supermicro_x9[i] != 0xFFFF; i++) {
if (oem_id == supermicro_x9[i]) {
chipset_type = 2;
break;
}
}
+ for (i = 0; supermicro_brickland[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_brickland[i]) {
+ chipset_type = 3;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10QRH[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10QRH[i]) {
+ chipset_type = 4;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10QBL[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10QBL[i]) {
+ chipset_type = 4;
+ break;
+ }
+ }
+ for (i = 0; supermicro_x10OBi[i] != 0xFFFF; i++) {
+ if (oem_id == supermicro_x10OBi[i]) {
+ chipset_type = 5;
+ break;
+ }
+ }
if (chipset_type == 0) {
snprintf(desc, SIZE_OF_DESC, "@DIMM%2X(CPU%x)",
data2,
@@ -630,6 +668,21 @@ get_supermicro_evt_desc(struct ipmi_intf *intf, struct sel_event_record *rec)
snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
(data2 >> 4) + 0x40 + (data3 & 0x3) * 3,
(data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else if (chipset_type == 3) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%d(P%dM%d)",
+ ((data2 & 0xf) >> 4) > 4
+ ? '@' - 4 + ((data2 & 0xff) >> 4)
+ : '@' + ((data2 & 0xff) >> 4),
+ (data2 & 0xf) - 0x09, (data3 & 0x0f) + 1,
+ (data2 & 0xff) >> 4 > 4 ? 2 : 1);
+ } else if (chipset_type == 4) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40,
+ (data2 & 0xf) + 0x27, (data3 & 0x03) + 1);
+ } else if (chipset_type == 5) {
+ snprintf(desc, SIZE_OF_DESC, "@DIMM%c%c(CPU%x)",
+ (data2 >> 4) + 0x40,
+ (data2 & 0xf) + 0x27, (data3 & 0x07) + 1);
} else {
/* No description. */
desc[0] = '\0';
@@ -1200,11 +1253,71 @@ ipmi_get_oem_desc(struct ipmi_intf * intf, struct sel_event_record * rec)
}
+const struct ipmi_event_sensor_types *
+ipmi_get_first_event_sensor_type(struct ipmi_intf *intf,
+ uint8_t sensor_type, uint8_t event_type)
+{
+ const struct ipmi_event_sensor_types *evt, *start, *next = NULL;
+ uint8_t code;
+
+ if (event_type == 0x6f) {
+ if (sensor_type >= 0xC0
+ && sensor_type < 0xF0
+ && ipmi_get_oem(intf) == IPMI_OEM_KONTRON) {
+ /* check Kontron OEM sensor event types */
+ start = oem_kontron_event_types;
+ } else if (intf->vita_avail) {
+ /* check VITA sensor event types first */
+ start = vita_sensor_event_types;
+
+ /* then check generic sensor types */
+ next = sensor_specific_event_types;
+ } else {
+ /* check generic sensor types */
+ start = sensor_specific_event_types;
+ }
+ code = sensor_type;
+ } else {
+ start = generic_event_types;
+ code = event_type;
+ }
+
+ for (evt = start; evt->desc != NULL || next != NULL; evt++) {
+ /* check if VITA sensor event types has finished */
+ if (evt->desc == NULL) {
+ /* proceed with next table */
+ evt = next;
+ next = NULL;
+ }
+
+ if (code == evt->code)
+ return evt;
+ }
+
+ return NULL;
+}
+
+
+const struct ipmi_event_sensor_types *
+ipmi_get_next_event_sensor_type(const struct ipmi_event_sensor_types *evt)
+{
+ const struct ipmi_event_sensor_types *start = evt;
+
+ for (evt = start + 1; evt->desc != NULL; evt++) {
+ if (evt->code == start->code) {
+ return evt;
+ }
+ }
+
+ return NULL;
+}
+
+
void
ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char ** desc)
{
- uint8_t code, offset;
- struct ipmi_event_sensor_types *evt = NULL;
+ uint8_t offset;
+ const struct ipmi_event_sensor_types *evt = NULL;
char *sfx = NULL; /* This will be assigned if the Platform is DELL,
additional info is appended to the current Description */
@@ -1223,86 +1336,61 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
case IPMI_OEM_KONTRON:
lprintf(LOG_DEBUG, "oem sensor type %x %d using oem type supplied description",
rec->sel_type.standard_type.sensor_type , iana);
-
- evt = oem_kontron_event_types;
- code = rec->sel_type.standard_type.sensor_type;
break;
case IPMI_OEM_DELL: /* OEM Bytes Decoding for DELLi */
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
(OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
{
- if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
- evt->data = rec->sel_type.standard_type.event_data[1];
-
sfx = ipmi_get_oem_desc(intf, rec);
}
break;
case IPMI_OEM_SUPERMICRO:
case IPMI_OEM_SUPERMICRO_47488:
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
sfx = ipmi_get_oem_desc(intf, rec);
break;
/* add your oem sensor assignation here */
default:
+ lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
+ rec->sel_type.standard_type.sensor_type );
break;
- }
- if( evt == NULL ){
- lprintf(LOG_DEBUG, "oem sensor type %x using standard type supplied description",
- rec->sel_type.standard_type.sensor_type );
}
} else {
switch (ipmi_get_oem(intf)) {
case IPMI_OEM_SUPERMICRO:
case IPMI_OEM_SUPERMICRO_47488:
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
sfx = ipmi_get_oem_desc(intf, rec);
break;
default:
break;
}
}
- if( evt == NULL ){
- evt = sensor_specific_types;
- code = rec->sel_type.standard_type.sensor_type;
- }
/*
* Check for the OEM DELL Interface based on the Dell Specific Vendor Code.
* If its Dell Platform, do the OEM Byte decode from the SEL Records.
* Additional information should be written by the ipmi_get_oem_desc()
*/
if(ipmi_get_oem(intf) == IPMI_OEM_DELL) {
- code = rec->sel_type.standard_type.sensor_type;
if ( (OEM_CODE_IN_BYTE2 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)) ||
(OEM_CODE_IN_BYTE3 == (rec->sel_type.standard_type.event_data[0] & DATA_BYTE3_SPECIFIED_MASK)) )
{
- if(rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK)
- evt->data = rec->sel_type.standard_type.event_data[1];
- sfx = ipmi_get_oem_desc(intf, rec);
-
+ sfx = ipmi_get_oem_desc(intf, rec);
}
else if(SENSOR_TYPE_OEM_SEC_EVENT == rec->sel_type.standard_type.event_data[0])
{
/* 0x23 : Sensor Number.*/
if(0x23 == rec->sel_type.standard_type.sensor_num)
- {
- evt->data = rec->sel_type.standard_type.event_data[1];
sfx = ipmi_get_oem_desc(intf, rec);
- }
}
}
- } else {
- evt = generic_event_types;
- code = rec->sel_type.standard_type.event_type;
}
offset = rec->sel_type.standard_type.event_data[0] & 0xf;
- while (evt->type) {
- if ((evt->code == code && evt->offset == offset && evt->desc != NULL) &&
+ for (evt = ipmi_get_first_event_sensor_type(intf,
+ rec->sel_type.standard_type.sensor_type,
+ rec->sel_type.standard_type.event_type);
+ evt != NULL; evt = ipmi_get_next_event_sensor_type(evt)) {
+ if ((evt->offset == offset && evt->desc != NULL) &&
((evt->data == ALL_OFFSETS_SPECIFIED) ||
((rec->sel_type.standard_type.event_data[0] & DATA_BYTE2_SPECIFIED_MASK) &&
(evt->data == rec->sel_type.standard_type.event_data[1]))))
@@ -1326,15 +1414,14 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
sprintf(*desc, "%s", evt->desc);
}
return;
- }
- evt++;
+ }
}
/* The Above while Condition was not met beacouse the below sensor type were Newly defined OEM
Secondary Events. 0xC1, 0xC2, 0xC3. */
if((sfx) && (0x6F == rec->sel_type.standard_type.event_type))
{
uint8_t flag = 0x00;
- switch(code)
+ switch(rec->sel_type.standard_type.sensor_type)
{
case SENSOR_TYPE_FRM_PROG:
if(0x0F == offset)
@@ -1379,74 +1466,58 @@ ipmi_get_event_desc(struct ipmi_intf * intf, struct sel_event_record * rec, char
}
-const char *
-ipmi_sel_get_oem_sensor_type(IPMI_OEM iana, uint8_t code)
+const char*
+ipmi_get_generic_sensor_type(uint8_t code)
{
- struct ipmi_event_sensor_types *st = NULL;
-
- switch(iana){
- case IPMI_OEM_KONTRON:
- st = oem_kontron_event_types;
- break;
- /* add you oem sensor type lookup assignement here */
- default:
- lprintf(LOG_DEBUG, "ipmitool: missing OEM sensor type for %ul",iana);
- break;
+ if (code <= SENSOR_TYPE_MAX) {
+ return ipmi_generic_sensor_type_vals[code];
}
- if( st != NULL )
- for (; st->type != NULL; st++)
- if (st->code == code)
- return st->type;
-
- return ipmi_sel_get_sensor_type(code);
+ return NULL;
}
+
const char *
-ipmi_sel_get_oem_sensor_type_offset(IPMI_OEM iana, uint8_t code, uint8_t offset)
+ipmi_get_oem_sensor_type(struct ipmi_intf *intf, uint8_t code)
{
- struct ipmi_event_sensor_types *st = NULL;
+ const struct oemvalstr *v, *found = NULL;
+ uint32_t iana = ipmi_get_oem(intf);
- switch(iana){
- case IPMI_OEM_KONTRON:
- st = oem_kontron_event_types;
- break;
- /* add you oem sensor type lookup assignement here */
- default:
- lprintf(LOG_DEBUG,
- "ipmitool: missing OEM sensor type offset for %ul",iana);
- break;
- }
+ for (v = ipmi_oem_sensor_type_vals; v->str; v++) {
+ if (v->oem == iana && v->val == code) {
+ return v->str;
+ }
- if( st != NULL )
- for (; st->type != NULL; st++)
- {
- if (st->code == code && st->offset == (offset&0xf))
- return st->type;
+ if ((intf->picmg_avail
+ && v->oem == IPMI_OEM_PICMG
+ && v->val == code)
+ || (intf->vita_avail
+ && v->oem == IPMI_OEM_VITA
+ && v->val == code)) {
+ found = v;
}
+ }
- return ipmi_sel_get_oem_sensor_type(iana,code);
+ return found ? found->str : NULL;
}
-const char *
-ipmi_sel_get_sensor_type(uint8_t code)
-{
- struct ipmi_event_sensor_types *st;
- for (st = sensor_specific_types; st->type != NULL; st++)
- if (st->code == code)
- return st->type;
- return "Unknown";
-}
const char *
-ipmi_sel_get_sensor_type_offset(uint8_t code, uint8_t offset)
+ipmi_get_sensor_type(struct ipmi_intf *intf, uint8_t code)
{
- struct ipmi_event_sensor_types *st;
- for (st = sensor_specific_types; st->type != NULL; st++)
- if (st->code == code && st->offset == (offset&0xf))
- return st->type;
+ const char *type;
+
+ if (code >= 0xC0) {
+ type = ipmi_get_oem_sensor_type(intf, code);
+ } else {
+ type = ipmi_get_generic_sensor_type(code);
+ }
+
+ if (type == NULL) {
+ type = "Unknown";
+ }
- return ipmi_sel_get_sensor_type(code);
+ return type;
}
static int
@@ -1693,13 +1764,7 @@ ipmi_sel_print_event_file(struct ipmi_intf * intf, struct sel_event_record * evt
evt->sel_type.standard_type.event_data[0],
evt->sel_type.standard_type.event_data[1],
evt->sel_type.standard_type.event_data[2],
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- ),
+ ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type),
evt->sel_type.standard_type.sensor_num,
(description != NULL) ? description : "Unknown");
@@ -1819,15 +1884,8 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
/* lookup SDR entry based on sensor number and type */
if (sdr != NULL) {
- printf("%s ",
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- )
- );
+ printf("%s ", ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
switch (sdr->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
printf("%s", sdr->record.full->id_string);
@@ -1852,13 +1910,8 @@ ipmi_sel_print_std_entry(struct ipmi_intf * intf, struct sel_event_record * evt)
break;
}
} else {
- printf("%s",(
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- ));
+ printf("%s", ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
if (evt->sel_type.standard_type.sensor_num != 0)
printf(" #0x%02x", evt->sel_type.standard_type.sensor_num);
}
@@ -2025,14 +2078,8 @@ ipmi_sel_print_std_entry_verbose(struct ipmi_intf * intf, struct sel_event_recor
printf(" EvM Revision : %02x\n",
evt->sel_type.standard_type.evm_rev);
printf(" Sensor Type : %s\n",
- (
- (evt->sel_type.standard_type.sensor_type >=0xC0 && evt->sel_type.standard_type.sensor_type < 0xF0)
- ?
- ipmi_sel_get_oem_sensor_type_offset(ipmi_get_oem(intf),evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- :
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0])
- )
- );
+ ipmi_get_sensor_type(intf,
+ evt->sel_type.standard_type.sensor_type));
printf(" Sensor Number : %02x\n",
evt->sel_type.standard_type.sensor_num);
printf(" Event Type : %s\n",
@@ -2096,7 +2143,7 @@ ipmi_sel_print_extended_entry_verbose(struct ipmi_intf * intf, struct sel_event_
printf(" EvM Revision : %02x\n",
evt->sel_type.standard_type.evm_rev);
printf(" Sensor Type : %s\n",
- ipmi_sel_get_sensor_type_offset(evt->sel_type.standard_type.sensor_type, evt->sel_type.standard_type.event_data[0]));
+ ipmi_get_sensor_type(intf, evt->sel_type.standard_type.sensor_type));
printf(" Sensor Number : %02x\n",
evt->sel_type.standard_type.sensor_num);
printf(" Event Type : %s\n",
@@ -2255,7 +2302,7 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
if (count < 0) {
/** Show only the most recent 'count' records. */
- int delta;
+ int i;
uint16_t entries;
req.msg.cmd = IPMI_CMD_GET_SEL_INFO;
@@ -2273,15 +2320,20 @@ __ipmi_sel_savelist_entries(struct ipmi_intf * intf, int count, const char * sav
if (-count > entries)
count = -entries;
- /* Get first record. */
- next_id = ipmi_sel_get_std_entry(intf, 0, &evt);
-
- delta = next_id - evt.record_id;
-
- /* Get last record. */
- next_id = ipmi_sel_get_std_entry(intf, 0xffff, &evt);
-
- next_id = evt.record_id + count * delta + delta;
+ for(i = 0; i < entries + count; i++) {
+ next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
+ if (next_id == 0) {
+ /*
+ * usually next_id of zero means end but
+ * retry because some hardware has quirks
+ * and will return 0 randomly.
+ */
+ next_id = ipmi_sel_get_std_entry(intf, next_id, &evt);
+ if (next_id == 0) {
+ break;
+ }
+ }
+ }
}
if (savefile != NULL) {
@@ -2402,7 +2454,7 @@ ipmi_sel_interpret(struct ipmi_intf *intf, unsigned long iana,
evt.sel_type.standard_type.evm_rev = 4;
/* FIXME: convert*/
- evt.sel_type.standard_type.timestamp;
+ /* evt.sel_type.standard_type.timestamp; */
/* skip timestamp */
cursor = index((const char *)cursor, ';');
diff --git a/lib/ipmi_sensor.c b/lib/ipmi_sensor.c
index 063dfb0..a0b7eb8 100644
--- a/lib/ipmi_sensor.c
+++ b/lib/ipmi_sensor.c
@@ -200,14 +200,14 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Discrete): %s\n",
- ipmi_sdr_get_sensor_type_desc(sensor->sensor.
+ ipmi_get_sensor_type(intf, sensor->sensor.
type));
if( sr->s_reading_valid )
{
if (sr->s_has_analog_value) {
printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units);
}
- ipmi_sdr_print_discrete_state("States Asserted",
+ ipmi_sdr_print_discrete_state(intf, "States Asserted",
sensor->sensor.type,
sensor->event_type,
sr->s_data2,
@@ -315,7 +315,7 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Threshold) : %s\n",
- ipmi_sdr_get_sensor_type_desc(sensor->sensor.
+ ipmi_get_sensor_type(intf, sensor->sensor.
type));
printf(" Sensor Reading : ");
diff --git a/lib/ipmi_session.c b/lib/ipmi_session.c
index 4855bc4..141f0f4 100644
--- a/lib/ipmi_session.c
+++ b/lib/ipmi_session.c
@@ -99,13 +99,8 @@ print_session_info_csv(const struct get_session_info_rsp * session_info,
buffer,
16));
- printf(",%02x:%02x:%02x:%02x:%02x:%02x",
- session_info->channel_data.lan_data.console_mac[0],
- session_info->channel_data.lan_data.console_mac[1],
- session_info->channel_data.lan_data.console_mac[2],
- session_info->channel_data.lan_data.console_mac[3],
- session_info->channel_data.lan_data.console_mac[4],
- session_info->channel_data.lan_data.console_mac[5]);
+ printf(",%s", mac2str(
+ session_info->channel_data.lan_data.console_mac));
console_port_tmp = session_info->channel_data.lan_data.console_port;
#if WORDS_BIGENDIAN
@@ -187,13 +182,8 @@ print_session_info_verbose(const struct get_session_info_rsp * session_info,
buffer,
16));
- printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
- session_info->channel_data.lan_data.console_mac[0],
- session_info->channel_data.lan_data.console_mac[1],
- session_info->channel_data.lan_data.console_mac[2],
- session_info->channel_data.lan_data.console_mac[3],
- session_info->channel_data.lan_data.console_mac[4],
- session_info->channel_data.lan_data.console_mac[5]);
+ printf("console mac : %s\n", mac2str(
+ session_info->channel_data.lan_data.console_mac));
console_port_tmp = session_info->channel_data.lan_data.console_port;
#if WORDS_BIGENDIAN
diff --git a/lib/ipmi_sol.c b/lib/ipmi_sol.c
index 333ce90..3acd5bb 100644
--- a/lib/ipmi_sol.c
+++ b/lib/ipmi_sol.c
@@ -1648,15 +1648,11 @@ ipmi_sol_red_pill(struct ipmi_intf * intf, int instance)
else if (FD_ISSET(intf->fd, &read_fds))
{
struct ipmi_rs * rs =intf->recv_sol(intf);
- if ( rs)
- {
+ if (rs) {
output(rs);
+ } else {
+ bShouldExit = bBmcClosedSession = 1;
}
- /*
- * Should recv_sol come back null, the incoming packet was not ours.
- * Just fall through, the keepalive logic will determine if
- * the BMC has dropped the session.
- */
}
diff --git a/lib/ipmi_strings.c b/lib/ipmi_strings.c
index 7fefee9..94b2abd 100644
--- a/lib/ipmi_strings.c
+++ b/lib/ipmi_strings.c
@@ -64,12 +64,13 @@ const struct valstr ipmi_oem_info[] = {
{ IPMI_OEM_TOSHIBA, "Toshiba" },
{ IPMI_OEM_HITACHI_116, "Hitachi" },
{ IPMI_OEM_HITACHI_399, "Hitachi" },
- { IPMI_OEM_NOKIA_SOLUTIONS_AND_NETWORKS, "Nokia Solutions and Networks (formerly 'Nokia Siemens Networks')" },
+ { IPMI_OEM_NOKIA_SOLUTIONS_AND_NETWORKS, "Nokia Solutions and Networks" },
{ IPMI_OEM_BULL, "Bull Company" },
{ IPMI_OEM_PPS, "Pigeon Point Systems" },
{ IPMI_OEM_BROADCOM, "Broadcom Corporation" },
{ IPMI_OEM_ERICSSON, "Ericsson AB"},
{ IPMI_OEM_QUANTA, "Quanta" },
+ { IPMI_OEM_VITA, "VITA" },
{ IPMI_OEM_ADVANTECH, "Advantech" },
/************************************************************************
* Add ID String for IANA Enterprise Number of IBM & ADLINK
@@ -286,34 +287,63 @@ const struct oemvalstr ipmi_oem_product_info[] = {
{ 0xffffff , 0xffff , NULL },
};
-const struct oemvalstr ipmi_oem_sdr_type_vals[] = {
+const char *ipmi_generic_sensor_type_vals[] = {
+ "reserved",
+ "Temperature", "Voltage", "Current", "Fan",
+ "Physical Security", "Platform Security", "Processor",
+ "Power Supply", "Power Unit", "Cooling Device", "Other",
+ "Memory", "Drive Slot / Bay", "POST Memory Resize",
+ "System Firmwares", "Event Logging Disabled", "Watchdog1",
+ "System Event", "Critical Interrupt", "Button",
+ "Module / Board", "Microcontroller", "Add-in Card",
+ "Chassis", "Chip Set", "Other FRU", "Cable / Interconnect",
+ "Terminator", "System Boot Initiated", "Boot Error",
+ "OS Boot", "OS Critical Stop", "Slot / Connector",
+ "System ACPI Power State", "Watchdog2", "Platform Alert",
+ "Entity Presence", "Monitor ASIC", "LAN",
+ "Management Subsys Health", "Battery", "Session Audit",
+ "Version Change", "FRU State",
+ NULL
+};
+
+const struct oemvalstr ipmi_oem_sensor_type_vals[] = {
/* Keep OEM grouped together */
- { IPMI_OEM_KONTRON , 0xC0 , "OEM Firmware Info" },
- { IPMI_OEM_KONTRON , 0xC2 , "OEM Init Agent" },
- { IPMI_OEM_KONTRON , 0xC3 , "OEM IPMBL Link State" },
- { IPMI_OEM_KONTRON , 0xC4 , "OEM Board Reset" },
- { IPMI_OEM_KONTRON , 0xC5 , "OEM FRU Information Agent" },
- { IPMI_OEM_KONTRON , 0xC6 , "OEM POST Value Sensor" },
- { IPMI_OEM_KONTRON , 0xC7 , "OEM FWUM Status" },
- { IPMI_OEM_KONTRON , 0xC8 , "OEM Switch Mngt Software Status" },
- { IPMI_OEM_KONTRON , 0xC9 , "OEM OEM Diagnostic Status" },
- { IPMI_OEM_KONTRON , 0xCA , "OEM Component Firmware Upgrade" },
- { IPMI_OEM_KONTRON , 0xCB , "OEM FRU Over Current" },
- { IPMI_OEM_KONTRON , 0xCC , "OEM FRU Sensor Error" },
- { IPMI_OEM_KONTRON , 0xCD , "OEM FRU Power Denied" },
- { IPMI_OEM_KONTRON , 0xCE , "OEM Reserved" },
- { IPMI_OEM_KONTRON , 0xCF , "OEM Board Reset" },
- { IPMI_OEM_KONTRON , 0xD0 , "OEM Clock Resource Control" },
- { IPMI_OEM_KONTRON , 0xD1 , "OEM Power State" },
- { IPMI_OEM_KONTRON , 0xD2 , "OEM FRU Mngt Power Failure" },
- { IPMI_OEM_KONTRON , 0xD3 , "OEM Jumper Status" },
- { IPMI_OEM_KONTRON , 0xF2 , "OEM RTM Module Hotswap" },
-
- { IPMI_OEM_PICMG , 0xF0 , "PICMG FRU Hotswap" },
- { IPMI_OEM_PICMG , 0xF1 , "PICMG IPMB0 Link State" },
- { IPMI_OEM_PICMG , 0xF2 , "PICMG Module Hotswap" },
-
- { 0xffffff, 0x00, NULL }
+ { IPMI_OEM_KONTRON, 0xC0, "Firmware Info" },
+ { IPMI_OEM_KONTRON, 0xC2, "Init Agent" },
+ { IPMI_OEM_KONTRON, 0xC2, "Board Reset(cPCI)" },
+ { IPMI_OEM_KONTRON, 0xC3, "IPMBL Link State" },
+ { IPMI_OEM_KONTRON, 0xC4, "Board Reset" },
+ { IPMI_OEM_KONTRON, 0xC5, "FRU Information Agent" },
+ { IPMI_OEM_KONTRON, 0xC6, "POST Value Sensor" },
+ { IPMI_OEM_KONTRON, 0xC7, "FWUM Status" },
+ { IPMI_OEM_KONTRON, 0xC8, "Switch Mngt Software Status" },
+ { IPMI_OEM_KONTRON, 0xC9, "OEM Diagnostic Status" },
+ { IPMI_OEM_KONTRON, 0xCA, "Component Firmware Upgrade" },
+ { IPMI_OEM_KONTRON, 0xCB, "FRU Over Current" },
+ { IPMI_OEM_KONTRON, 0xCC, "FRU Sensor Error" },
+ { IPMI_OEM_KONTRON, 0xCD, "FRU Power Denied" },
+ { IPMI_OEM_KONTRON, 0xCE, "Reserved" },
+ { IPMI_OEM_KONTRON, 0xCF, "Board Reset" },
+ { IPMI_OEM_KONTRON, 0xD0, "Clock Resource Control" },
+ { IPMI_OEM_KONTRON, 0xD1, "Power State" },
+ { IPMI_OEM_KONTRON, 0xD2, "FRU Mngt Power Failure" },
+ { IPMI_OEM_KONTRON, 0xD3, "Jumper Status" },
+ { IPMI_OEM_KONTRON, 0xF2, "RTM Module Hotswap" },
+ /* PICMG Sensor Types */
+ { IPMI_OEM_PICMG, 0xF0, "FRU Hot Swap" },
+ { IPMI_OEM_PICMG, 0xF1,"IPMB Physical Link" },
+ { IPMI_OEM_PICMG, 0xF2, "Module Hot Swap" },
+ { IPMI_OEM_PICMG, 0xF3, "Power Channel Notification" },
+ { IPMI_OEM_PICMG, 0xF4, "Telco Alarm Input" },
+ /* VITA 46.11 Sensor Types */
+ { IPMI_OEM_VITA, 0xF0, "FRU State" },
+ { IPMI_OEM_VITA, 0xF1, "System IPMB Link" },
+ { IPMI_OEM_VITA, 0xF2, "FRU Health" },
+ { IPMI_OEM_VITA, 0xF3, "FRU Temperature" },
+ { IPMI_OEM_VITA, 0xF4, "Payload Test Results" },
+ { IPMI_OEM_VITA, 0xF5, "Payload Test Status" },
+
+ { 0xffffff, 0x00, NULL }
};
const struct valstr ipmi_netfn_vals[] = {
@@ -591,6 +621,9 @@ const struct valstr ipmi_auth_algorithms[] = {
{ IPMI_AUTH_RAKP_NONE, "none" },
{ IPMI_AUTH_RAKP_HMAC_SHA1, "hmac_sha1" },
{ IPMI_AUTH_RAKP_HMAC_MD5, "hmac_md5" },
+#ifdef HAVE_CRYPTO_SHA256
+ { IPMI_AUTH_RAKP_HMAC_SHA256, "hmac_sha256" },
+#endif /* HAVE_CRYPTO_SHA256 */
{ 0x00, NULL }
};
@@ -599,6 +632,9 @@ const struct valstr ipmi_integrity_algorithms[] = {
{ IPMI_INTEGRITY_HMAC_SHA1_96, "hmac_sha1_96" },
{ IPMI_INTEGRITY_HMAC_MD5_128, "hmac_md5_128" },
{ IPMI_INTEGRITY_MD5_128 , "md5_128" },
+#ifdef HAVE_CRYPTO_SHA256
+ { IPMI_INTEGRITY_HMAC_SHA256_128, "sha256_128" },
+#endif /* HAVE_CRYPTO_SHA256 */
{ 0x00, NULL }
};
@@ -610,6 +646,14 @@ const struct valstr ipmi_encryption_algorithms[] = {
{ 0x00, NULL }
};
+const struct valstr ipmi_user_enable_status_vals[] = {
+ { 0x00, "unknown" },
+ { 0x40, "enabled" },
+ { 0x80, "disabled" },
+ { 0xC0, "reserved" },
+ { 0xFF, NULL },
+};
+
const struct valstr picmg_frucontrol_vals[] = {
{ 0, "Cold Reset" },
{ 1, "Warm Reset" },
diff --git a/lib/ipmi_sunoem.c b/lib/ipmi_sunoem.c
index e4fae65..ecbcbd9 100644
--- a/lib/ipmi_sunoem.c
+++ b/lib/ipmi_sunoem.c
@@ -1436,7 +1436,7 @@ ipmi_sunoem_echo(struct ipmi_intf * intf, int argc, char *argv[])
received++;
if (!quiet_mode) {
- printf("Receive %u Bytes - Seq. # %d time=%d ms\n",
+ printf("Receive %lu Bytes - Seq. # %d time=%d ms\n",
sizeof(sunoem_echo_msg_t), echo_rsp->seq_num, resp_time);
}
} /* for (i = 0; i < num; i++) */