Jordan,

You left some cruft in lib/ipmi_delloem.c that you no longer need.

Per the IPMI Spec, request 2 is System name, not a hostname. Please change the 
command
argument from "hostname" to "system_name" so users aren't confused about how to 
interpret
the string returned.
From the IPMI Spec page 298.

   "System Name. A name for the overall system to be associated with the BMC. 
This
   may or may not match other names that are used for the system."


There is nothing in your code that is not in the IPMI spec, so you don't need 
to do any Dell specific
OEM checking.   I would instead prefix the dell specific commands with delloem_ 
to help clearly
identifiy what are IPMI spec defined commands and what are delloem defined 
commands.   So, your
command list would be

   0x02 system_name
   0x03 primary_os_name
   0x04 os_name
   0xe4 delloem_os_version
   0xde delloem_url

We can only hope that no other manufacturer decides to use parameter selectors 
0xe4 and 0xde.

You should then change the error code processing to handle the command specific 
error code 80h.
When you see a return code of 80h, simply display to the user the string "Parameter 
Not Supported"
This is what will make the code generic as each platform should return this 
error if they don't support
the input parameter selector.

Now for something a little more esoteric with regard to the set selector data 1 
field in the requests.
Per the IPMI Spec, this request is only required to have two data blocks, but 
your code as written
requires it to have 4.   So, if a platform only returns 2 data sets to 
represent the string, your code reports
an error when it attempts to read the third block.

   "data 1 - set selector = 16-byte data block number to access, 0 based. Two 
data
   blocks (32-bytes) for string data required, at least three recommended.
   Number of effective characters will be dependent on the encoding
   selected in string data byte 1."

I ran into this issue when I tested your code out on an HP Proliant platform.

-- Jim Mankovich | jm...@hp.com --

On 8/8/2012 9:57 AM, jordan_hargr...@dell.com wrote:
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


------------------------------------------------------------------------------
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

Reply via email to