From c7a6be575d3725781f454964a9b33848327dd3f1 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Sat, 8 Jan 2005 02:49:22 +0000 Subject: [PATCH] add more flexible way of handling OEM boards now pass a "-o " argument on the command line the currently defined oem types are "supermicro" and "intelwv2" the existing -g and -s options are still present for compatibility --- ipmitool/include/ipmitool/Makefile.am | 3 +- ipmitool/include/ipmitool/ipmi_intf.h | 5 +- ipmitool/include/ipmitool/ipmi_oem.h | 51 +++++++++ ipmitool/lib/Makefile.am | 3 +- ipmitool/lib/ipmi_oem.c | 146 ++++++++++++++++++++++++++ ipmitool/src/ipmitool.c | 52 +++++---- ipmitool/src/plugins/lan/lan.c | 12 ++- 7 files changed, 245 insertions(+), 27 deletions(-) create mode 100644 ipmitool/include/ipmitool/ipmi_oem.h create mode 100644 ipmitool/lib/ipmi_oem.c diff --git a/ipmitool/include/ipmitool/Makefile.am b/ipmitool/include/ipmitool/Makefile.am index 7fc1e5a..fb122d6 100644 --- a/ipmitool/include/ipmitool/Makefile.am +++ b/ipmitool/include/ipmitool/Makefile.am @@ -38,5 +38,6 @@ noinst_HEADERS = log.h bswap.h helper.h ipmi.h ipmi_intf.h \ ipmi_chassis.h ipmi_entity.h ipmi_fru.h ipmi_lanp.h \ ipmi_sdr.h ipmi_sel.h ipmi_sol.h ipmi_mc.h ipmi_raw.h \ ipmi_channel.h ipmi_sensor.h ipmi_event.h ipmi_session.h \ - ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h + ipmi_strings.h ipmi_constants.h ipmi_user.h ipmi_pef.h \ + ipmi_oem.h diff --git a/ipmitool/include/ipmitool/ipmi_intf.h b/ipmitool/include/ipmitool/ipmi_intf.h index db5b80c..204fa69 100644 --- a/ipmitool/include/ipmitool/ipmi_intf.h +++ b/ipmitool/include/ipmitool/ipmi_intf.h @@ -38,6 +38,7 @@ #define IPMI_INTF_H #include +#include #include #include @@ -80,7 +81,6 @@ struct ipmi_session { uint8_t authstatus; uint8_t authextra; uint8_t privlvl; - uint8_t authspecial; /* special auth flag */ int password; int port; int active; @@ -144,16 +144,15 @@ struct ipmi_session { } sol_data; }; - struct ipmi_intf { char name[16]; char desc[128]; int fd; int opened; int abort; - int thump; struct ipmi_session * session; + struct ipmi_oem_handle * oem; uint32_t my_addr; uint32_t target_addr; diff --git a/ipmitool/include/ipmitool/ipmi_oem.h b/ipmitool/include/ipmitool/ipmi_oem.h new file mode 100644 index 0000000..4f4654f --- /dev/null +++ b/ipmitool/include/ipmitool/ipmi_oem.h @@ -0,0 +1,51 @@ +/* + * 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 Sun Microsystems, Inc. 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 "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +#ifndef IPMI_OEM_H +#define IPMI_OEM_H + +#include + +/* oem handler, see lib/ipmi_oem.c */ +struct ipmi_oem_handle { + const char * name; + const char * desc; + int (*setup)(struct ipmi_intf * intf); +}; + +void ipmi_oem_print(void); +int ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype); +int ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype); + +#endif /*IPMI_OEM_H*/ diff --git a/ipmitool/lib/Makefile.am b/ipmitool/lib/Makefile.am index 184059b..0dd0c1b 100644 --- a/ipmitool/lib/Makefile.am +++ b/ipmitool/lib/Makefile.am @@ -39,7 +39,8 @@ noinst_LTLIBRARIES = libipmitool.la libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \ ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_mc.c log.c \ dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \ - ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c + ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \ + ipmi_oem.c libipmitool_la_LDFLAGS = -export-dynamic libipmitool_la_LIBADD = -lm libipmitool_la_DEPENDENCIES = diff --git a/ipmitool/lib/ipmi_oem.c b/ipmitool/lib/ipmi_oem.c new file mode 100644 index 0000000..fa8d1e8 --- /dev/null +++ b/ipmitool/lib/ipmi_oem.c @@ -0,0 +1,146 @@ +/* + * 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 Sun Microsystems, Inc. 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 "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +#include + +#include +#include +#include +#include +#include + +static int ipmi_oem_supermicro(struct ipmi_intf * intf); + +static struct ipmi_oem_handle ipmi_oem_list[] = { + { + name: "supermicro", + desc: "Supermicro BMC with OEM LAN authentication support", + setup: ipmi_oem_supermicro, + }, + { + name: "intelwv2", + desc: "Intel SE7501WV2 BMC with extra LAN communication support", + }, + { 0 }, +}; + +/* Supermicro IPMIv2 BMCs use OEM authtype */ +static int +ipmi_oem_supermicro(struct ipmi_intf * intf) +{ + ipmi_intf_session_set_authtype(intf, IPMI_SESSION_AUTHTYPE_OEM); + return 0; +} + +/* ipmi_oem_print - print list of OEM handles + */ +void +ipmi_oem_print(void) +{ + struct ipmi_oem_handle * oem; + lprintf(LOG_NOTICE, "\nOEM Support:"); + for (oem=ipmi_oem_list; oem->setup != NULL; oem++) { + if (oem->name == NULL || oem->desc == NULL) + continue; + lprintf(LOG_NOTICE, "\t%-12s %s", oem->name, oem->desc); + } + lprintf(LOG_NOTICE, ""); +} + +/* ipmi_oem_setup - do initial setup of OEM handle + * + * @intf: ipmi interface + * @oemtype: OEM handle name + * + * returns 0 on success + * returns -1 on error + */ +int +ipmi_oem_setup(struct ipmi_intf * intf, char * oemtype) +{ + struct ipmi_oem_handle * oem; + int rc = 0; + + if (strncmp(oemtype, "help", 4) == 0 || + strncmp(oemtype, "list", 4) == 0 || + oemtype == NULL) { + ipmi_oem_print(); + return -1; + } + + for (oem=ipmi_oem_list; oem->setup != NULL; oem++) { + if (oem->name == NULL) + continue; + if (strncmp(oemtype, oem->name, strlen(oem->name)) == 0) + break; + } + + if (oem->name == NULL) { + /* nothing was found */ + lprintf(LOG_ERR, "OEM support not found for \"%s\"", oemtype); + return -1; + } + + /* save pointer for later use */ + intf->oem = oem; + + /* run optional setup function if it is defined */ + if (oem->setup != NULL) { + lprintf(LOG_DEBUG, "Running OEM setup for \"%s\"", oem->desc); + rc = oem->setup(intf); + } + + return rc; +} + +/* ipmi_oem_active - used to determine if a particular OEM type is set + * + * @intf: ipmi interface + * @oemtype: string containing name of ipmi handle to check + * + * returns 1 if requested ipmi handle is active + * returns 0 otherwise + */ +int +ipmi_oem_active(struct ipmi_intf * intf, const char * oemtype) +{ + if (intf->oem == NULL) + return 0; + + if (strncmp(intf->oem->name, oemtype, strlen(oemtype)) == 0) + return 1; + + return 0; +} + diff --git a/ipmitool/src/ipmitool.c b/ipmitool/src/ipmitool.c index 04d933e..0cac755 100644 --- a/ipmitool/src/ipmitool.c +++ b/ipmitool/src/ipmitool.c @@ -63,15 +63,16 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H # include #endif #ifdef __sun -# define OPTION_STRING "I:hVvcgsH:f:U:p:t:m:" +# define OPTION_STRING "I:hVvcH:f:U:p:" #else -# define OPTION_STRING "I:hVvcgsEaH:P:f:U:p:L:A:t:m:" +# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:L:A:t:m:" #endif int csv_output = 0; @@ -123,7 +124,7 @@ ipmi_cmd_print(void) { struct ipmi_cmd * cmd; lprintf(LOG_NOTICE, "Commands:"); - for (cmd=ipmi_cmd_list; cmd->func; cmd++) { + for (cmd=ipmi_cmd_list; cmd->func != NULL; cmd++) { if (cmd->desc == NULL) continue; lprintf(LOG_NOTICE, "\t%-12s %s", cmd->name, cmd->desc); @@ -185,6 +186,7 @@ ipmitool_usage(void) lprintf(LOG_NOTICE, " -f file Read remote session password from file"); lprintf(LOG_NOTICE, " -m address Set local IPMB address"); lprintf(LOG_NOTICE, " -t address Bridge request to remote target address"); + lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)"); #endif lprintf(LOG_NOTICE, ""); ipmi_intf_print(); @@ -252,11 +254,10 @@ main(int argc, char ** argv) char * password = NULL; char * intfname = NULL; char * progname = NULL; + char * oemtype = NULL; int port = 0; int argflag, i; int rc = -1; - int thump = 0; - int authspecial = 0; /* save program name */ progname = strrchr(argv[0], '/'); @@ -328,11 +329,24 @@ main(int argc, char ** argv) } break; #ifndef __sun /* some options not enabled on solaris yet */ + case 'o': + oemtype = strdup(optarg); + if (oemtype == NULL) { + lprintf(LOG_ERR, "ipmitool: malloc failure"); + goto out_free; + } + if (strncmp(oemtype, "list", 4) == 0) { + ipmi_oem_print(); + goto out_free; + } + break; case 'g': - thump = 1; + /* backwards compatible oem hack */ + oemtype = strdup("intelwv2"); break; case 's': - authspecial = 1; + /* backwards compatible oem hack */ + oemtype = strdup("supermicro"); break; case 'P': if (password) @@ -448,16 +462,16 @@ main(int argc, char ** argv) goto out_free; } - intf->thump = thump; - - if (authspecial > 0) { - intf->session->authspecial = authspecial; - ipmi_intf_session_set_authtype(intf, IPMI_SESSION_AUTHTYPE_OEM); - } - /* setup log */ log_init(progname, 0, verbose); + /* run OEM setup if found */ + if (oemtype != NULL && + ipmi_oem_setup(intf, oemtype) < 0) { + lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype); + goto out_free; + } + /* set session variables */ if (hostname != NULL) ipmi_intf_session_set_hostname(intf, hostname); @@ -502,14 +516,16 @@ main(int argc, char ** argv) out_free: log_halt(); - if (intfname) + if (intfname != NULL) free(intfname); - if (hostname) + if (hostname != NULL) free(hostname); - if (username) + if (username != NULL) free(username); - if (password) + if (password != NULL) free(password); + if (oemtype != NULL) + free(oemtype); if (rc >= 0) exit(EXIT_SUCCESS); diff --git a/ipmitool/src/plugins/lan/lan.c b/ipmitool/src/plugins/lan/lan.c index d7e89ce..8339de5 100644 --- a/ipmitool/src/plugins/lan/lan.c +++ b/ipmitool/src/plugins/lan/lan.c @@ -54,6 +54,7 @@ #include #include #include +#include #include #include @@ -745,7 +746,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req) continue; } - if (intf->thump) + if (ipmi_oem_active(intf, "intelwv2")) ipmi_lan_thump(intf); usleep(100); @@ -1092,7 +1093,8 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf) msg_data[0] = s->authtype; msg_data[1] = s->privlvl; - if (s->authspecial) { + /* supermicro oem authentication hack */ + if (ipmi_oem_active(intf, "supermicro")) { uint8_t * special = ipmi_auth_special(s); memcpy(s->authcode, special, 16); memset(msg_data + 2, 0, 16); @@ -1293,10 +1295,12 @@ ipmi_lan_activate_session(struct ipmi_intf * intf) /* don't fail on ping because its not always supported. * Supermicro's IPMI LAN 1.5 cards don't tolerate pings. */ - if (intf->session->authspecial == 0) + if (ipmi_oem_active(intf, "supermicro")) ipmi_lan_ping(intf); - if (intf->thump) + /* Some particular Intel boards need special help + */ + if (ipmi_oem_active(intf, "intelwv2")) ipmi_lan_thump_first(intf); rc = ipmi_get_auth_capabilities_cmd(intf);