I have moved the common code for getsysinfo/setsysinfo to ipmi_mc and added
tests for the Dell-specific commands.
Index: doc/ipmitool.1
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/doc/ipmitool.1,v
retrieving revision 1.48
diff -u -p -b -r1.48 ipmitool.1
--- doc/ipmitool.1 17 May 2012 15:52:35 -0000 1.48
+++ doc/ipmitool.1 8 Aug 2012 15:49:14 -0000
@@ -350,6 +350,23 @@ OEM\-Defined option #1
.br
OEM\-Defined option #2
+
+.RE
+.TP
+\fIgetsysinfo {os_name}|{primary_os_name}|{os_version}|{url}\fP
+.RS
+.br
+
+Retrieves system info from bmc for given argument
+.RE
+.TP
+\fIsetsysinfo\fP
\fI{os_name}\fP|\fI{primary_os_name}\fP|\fI{os_version}\fP|\fI{url}\fP
+.RS
+<\fBstring\fR>
+.br
+
+Stores system info string to bmc for given argument
+
.RE
.RE
.TP
Index: include/ipmitool/ipmi_delloem.h
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/include/ipmitool/ipmi_delloem.h,v
retrieving revision 1.5
diff -u -p -b -r1.5 ipmi_delloem.h
--- include/ipmitool/ipmi_delloem.h 27 Jul 2012 15:21:55 -0000 1.5
+++ include/ipmitool/ipmi_delloem.h 8 Aug 2012 15:49:14 -0000
@@ -39,10 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define MAX(a,b) ((a) > (b) ? (a) : (b))
-/* IPMI 2.0 command for system information*/
-#define IPMI_SET_SYS_INFO 0x58
-#define IPMI_GET_SYS_INFO 0x59
-
/* Dell selector for LCD control - get and set unless specified */
#define IPMI_DELL_LCD_STRING_SELECTOR 0xC1 /* RW get/set the
user string */
#define IPMI_DELL_LCD_CONFIG_SELECTOR 0xC2 /* RW set to
user/default/none */
Index: include/ipmitool/ipmi_mc.h
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/include/ipmitool/ipmi_mc.h,v
retrieving revision 1.10
diff -u -p -b -r1.10 ipmi_mc.h
--- include/ipmitool/ipmi_mc.h 9 Jun 2009 15:38:09 -0000 1.10
+++ include/ipmitool/ipmi_mc.h 8 Aug 2012 15:49:14 -0000
@@ -151,4 +151,18 @@ struct ipm_get_watchdog_rsp {
#define IPM_WATCHDOG_CLEAR_BIOS_POST 0x04
#define IPM_WATCHDOG_CLEAR_BIOS_FRB2 0x02
+/* IPMI 2.0 command for system information*/
+#define IPMI_SET_SYS_INFO 0x58
+#define IPMI_GET_SYS_INFO 0x59
+
+#define IPMI_SYSINFO_HOSTNAME 0x02
+#define IPMI_SYSINFO_PRIMARY_OS_NAME 0x03
+#define IPMI_SYSINFO_OS_NAME 0x04
+#define IPMI_SYSINFO_DELL_OS_VERSION 0xe4
+#define IPMI_SYSINFO_DELL_URL 0xde
+
+int ipmi_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,
+ int len, void *buffer);
+int ipmi_setsysinfo(struct ipmi_intf * intf, int len, void *buffer);
+
#endif /*IPMI_MC_H */
Index: lib/ipmi_delloem.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/lib/ipmi_delloem.c,v
retrieving revision 1.16
diff -u -p -b -r1.16 ipmi_delloem.c
--- lib/ipmi_delloem.c 3 Aug 2012 17:07:07 -0000 1.16
+++ lib/ipmi_delloem.c 8 Aug 2012 15:49:15 -0000
@@ -238,6 +238,8 @@ static int ipmi_delloem_setled_main(stru
static int ipmi_setled_state (struct ipmi_intf * intf, int bayId, int slotId,
int state);
static int ipmi_getdrivemap (struct ipmi_intf * intf, int b, int d, int f,
int *bayId, int *slotId);
+static int ipmi_delloem_sysinfo_main(struct ipmi_intf *intf, int argc, char ** argv);
+
/*****************************************************************
* Function Name: ipmi_delloem_main
*
@@ -323,6 +325,8 @@ static void usage(void)
lprintf(LOG_NOTICE, " setled");
lprintf(LOG_NOTICE, " powermonitor");
lprintf(LOG_NOTICE, " vFlash");
+ lprintf(LOG_NOTICE, " setsysinfo");
+ lprintf(LOG_NOTICE, " getsysinfo");
lprintf(LOG_NOTICE, "");
lprintf(LOG_NOTICE, "For help on individual commands type:");
lprintf(LOG_NOTICE, "delloem <command> help");
@@ -5291,53 +5295,3 @@ ipmi_delloem_setled_main(struct ipmi_int
/* Set drive LEDs */
return ipmi_setled_state (intf, bayId, slotId, mask);
}
-
-
-/*****************************************************************
- * Function Name: ipmi_getsysinfo
- *
- * Description: This function processes the IPMI Get System Info
command
- * Input: intf - ipmi interface
- * param - Parameter # (0xC0..0xFF = OEM)
- * block/set - Block/Set number of parameter
- * len - Length of buffer
- * buffer - Pointer to buffer
- * Output:
- *
- * Return: return code 0 - success
- * -1 - failure
- * other = IPMI ccode
- *
- ******************************************************************/
-static int
-ipmi_getsysinfo(struct ipmi_intf * intf, int param, int block, int set, int
len, void *buffer)
-{
- uint8_t data[4];
- struct ipmi_rs *rsp = NULL;
- struct ipmi_rq req={0};
-
- memset(buffer, 0, len);
- memset(data, 0, 4);
- req.msg.netfn = IPMI_NETFN_APP;
- req.msg.lun = 0;
- req.msg.cmd = IPMI_GET_SYS_INFO;
- req.msg.data_len = 4;
- req.msg.data = data;
-
- data[0] = 0; // get/set
- data[1] = param;
- data[2] = block;
- data[3] = set;
-
- rsp = intf->sendrecv(intf, &req);
- if (rsp != NULL) {
- if (rsp->ccode == 0) {
- if (len > rsp->data_len)
- len = rsp->data_len;
- if (len && buffer)
- memcpy(buffer, rsp->data, len);
- }
- return rsp->ccode;
- }
- return -1;
-}
Index: lib/ipmi_mc.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/lib/ipmi_mc.c,v
retrieving revision 1.24
diff -u -p -b -r1.24 ipmi_mc.c
--- lib/ipmi_mc.c 4 May 2010 14:44:19 -0000 1.24
+++ lib/ipmi_mc.c 8 Aug 2012 15:49:15 -0000
@@ -45,6 +45,8 @@
extern int verbose;
+static int ipmi_sysinfo_main(struct ipmi_intf *intf, int argc, char ** argv);
+
/* ipmi_mc_reset - attempt to reset an MC
*
* @intf: ipmi interface
@@ -793,9 +795,226 @@ ipmi_mc_main(struct ipmi_intf * intf, in
print_watchdog_usage();
}
}
+ else if (!strncmp(argv[0], "getsysinfo", 10) ||
+ !strncmp(argv[0], "setsysinfo", 10)) {
+ rc = ipmi_sysinfo_main(intf, argc, argv);
+ }
else {
lprintf(LOG_ERR, "Invalid mc/bmc command: %s", argv[0]);
rc = -1;
}
return rc;
}
+
+
+static int sysinfo_param(struct ipmi_intf *intf, const char *str, int *maxset)
+{
+ *maxset = 4;
+ if (!strcmp(str, "hostname"))
+ return IPMI_SYSINFO_HOSTNAME;
+ if (!strcmp(str, "primary_os_name"))
+ return IPMI_SYSINFO_PRIMARY_OS_NAME;
+ if (!strcmp(str, "os_name"))
+ return IPMI_SYSINFO_OS_NAME;
+
+ /* Need to open interface to read oem ID */
+ if (!intf->opened)
+ intf->open(intf);
+ if (ipmi_get_oem(intf) == IPMI_OEM_DELL) {
+ if (!strcmp(str, "os_version"))
+ return IPMI_SYSINFO_DELL_OS_VERSION;
+ if (!strcmp(str, "url")) {
+ *maxset = 2;
+ return IPMI_SYSINFO_DELL_URL;
+ }
+ }
+ return -1;
+}
+
+static void ipmi_sysinfo_usage()
+{
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " getsysinfo
(os_name|primary_os_name|os_version|url)");
+ lprintf(LOG_NOTICE, " Retrieves system info from bmc for given
argument");
+ lprintf(LOG_NOTICE, " setsysinfo
(os_name|primary_os_name|os_version|url)");
+ lprintf(LOG_NOTICE, " Stores system Info for given argument to
bmc");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " primary_os_name = primary operating system
name");
+ lprintf(LOG_NOTICE, " os_version = running version of operating
system");
+ lprintf(LOG_NOTICE, " os_name = operating system name");
+ lprintf(LOG_NOTICE, " hostname = hostname of server");
+ lprintf(LOG_NOTICE, " url = url of bmc webserver");
+
+ lprintf(LOG_NOTICE, "");
+}
+
+/*****************************************************************
+ * Function Name: ipmi_getsysinfo
+ *
+ * Description: This function processes the IPMI Get System Info
command
+ * Input: intf - ipmi interface
+ * param - Parameter # (0xC0..0xFF = OEM)
+ * block/set - Block/Set number of parameter
+ * len - Length of buffer
+ * buffer - Pointer to buffer
+ * Output:
+ *
+ * Return: return code 0 - success
+ * -1 - failure
+ * other = IPMI ccode
+ *
+ ******************************************************************/
+int
+ipmi_getsysinfo(struct ipmi_intf * intf, int param, int block, int set,
+ int len, void *buffer)
+{
+ uint8_t data[4];
+ struct ipmi_rs *rsp = NULL;
+ struct ipmi_rq req={0};
+
+ memset(buffer, 0, len);
+ memset(data, 0, 4);
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.lun = 0;
+ req.msg.cmd = IPMI_GET_SYS_INFO;
+ req.msg.data_len = 4;
+ req.msg.data = data;
+
+ data[0] = 0; // get/set
+ data[1] = param;
+ data[2] = block;
+ data[3] = set;
+
+ // Format of get output is:
+ // u8 param_rev
+ // u8 selector
+ // u8 encoding bit[0-3];
+ // u8 length
+ // u8 data0[14]
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp != NULL) {
+ if (rsp->ccode == 0) {
+ if (len > rsp->data_len)
+ len = rsp->data_len;
+ if (len && buffer)
+ memcpy(buffer, rsp->data, len);
+ }
+ return rsp->ccode;
+ }
+ return -1;
+}
+
+/*****************************************************************
+ * Function Name: ipmi_setsysinfo
+ *
+ * Description: This function processes the IPMI Set System Info
command
+ * Input: intf - ipmi interface
+ * len - Length of buffer
+ * buffer - Pointer to buffer
+ * Output:
+ *
+ * Return: return code 0 - success
+ * -1 - failure
+ * other = IPMI ccode
+ *
+ ******************************************************************/
+int
+ipmi_setsysinfo(struct ipmi_intf * intf, int len, void *buffer)
+{
+ struct ipmi_rs *rsp = NULL;
+ struct ipmi_rq req={0};
+
+ req.msg.netfn = IPMI_NETFN_APP;
+ req.msg.lun = 0;
+ req.msg.cmd = IPMI_SET_SYS_INFO;
+ req.msg.data_len = len;
+ req.msg.data = buffer;
+
+ // Format of set input:
+ // u8 param rev
+ // u8 selector
+ // u8 data1[16]
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp != NULL) {
+ return rsp->ccode;
+ }
+ return -1;
+}
+
+
+static int ipmi_sysinfo_main(struct ipmi_intf *intf, int argc, char ** argv)
+{
+ int param, isset;
+ char *str;
+ unsigned char infostr[256], *pos;
+ unsigned char paramdata[32];
+ int j, set, rc, maxset;
+
+ /* Is this a setsysinfo or getsysinfo */
+ isset = !strncmp(argv[0], "setsysinfo\0",11);
+
+ if (argc == 1 || strcmp(argv[1], "help") == 0 ||
+ argc < (isset ? 3 : 2)) {
+ ipmi_sysinfo_usage();
+ return 0;
+ }
+ memset(infostr, 0, sizeof(infostr));
+
+ // Parameters
+ param = sysinfo_param(intf, argv[1], &maxset);
+ if (param < 0) {
+ ipmi_sysinfo_usage();
+ return 0;
+ }
+
+ rc = 0;
+ if (isset) {
+ str = argv[2];
+ set = j = 0;
+ while (j <= strlen(str)) {
+ memset(paramdata, 0, sizeof(paramdata));
+ paramdata[0] = param;
+ paramdata[1] = set;
+ if (set == 0) {
+ /* First block is special case */
+ paramdata[2] = 0; // ascii encoding
+ paramdata[3] = strlen(str); // length;
+ strncpy(paramdata+4, str+j, 14);
+ j += 14;
+ } else {
+ strncpy(paramdata+2, str+j, 16);
+ j += 16;
+ }
+ rc = ipmi_setsysinfo(intf, 18, paramdata);
+ if (rc)
+ break;
+ set++;
+ }
+ } else {
+ pos = infostr;
+
+ /* Read 4 blocks of data (64 bytes) */
+ for (set=0; set<maxset; set++) {
+ rc = ipmi_getsysinfo(intf, param, set, 0, 18, paramdata);
+ if (rc)
+ break;
+ if (set == 0) {
+ /* First block is special case */
+ memcpy(pos, paramdata+4, 14);
+ pos += 14;
+ } else {
+ memcpy(pos, paramdata+2, 16);
+ pos += 16;
+ }
+ }
+ printf("%s\n", infostr);
+ }
+ if (rc < 0) {
+ lprintf(LOG_ERR, "%s %s set %d command failed", argv[0], argv[1], set);
+ } else if (rc > 0) {
+ lprintf(LOG_ERR, "%s %s set %d command failed: %s",
+ argv[0], argv[1], set,
+ val2str(rc, completion_code_vals));
+ }
+ return rc;
+}
--jordan hargrave
Dell Enterprise Linux Engineering
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel