summaryrefslogtreecommitdiff
path: root/util/ipmi_sample.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/ipmi_sample.c')
-rw-r--r--util/ipmi_sample.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/util/ipmi_sample.c b/util/ipmi_sample.c
new file mode 100644
index 0000000..ddda7f3
--- /dev/null
+++ b/util/ipmi_sample.c
@@ -0,0 +1,312 @@
+/*
+ * ipmi_sample.c
+ *
+ * A sample IPMI utility, to which more commands can be added.
+ *
+ * 02/27/06 Andy Cress - created
+ * 02/25/11 Andy Cress - added get_chassis_status
+ */
+/*M*
+Copyright (c) 2007, Kontron America, Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ a.. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+ b.. Redistributions 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.
+ c.. Neither the name of Kontron America, Inc. nor the names of its 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 THE COPYRIGHT OWNER OR CONTRIBUTORS 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.
+ *M*/
+#ifdef WIN32
+#include <windows.h>
+#include <stdio.h>
+#include "getopt.h"
+#else
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#if defined(HPUX)
+/* getopt is defined in stdio.h */
+#elif defined(MACOS)
+/* getopt is defined in unistd.h */
+#include <unistd.h>
+#else
+#include <getopt.h>
+#endif
+#endif
+#include <string.h>
+#include "ipmicmd.h"
+#ifdef GET_SENSORS
+/* need to also include isensor.o, ievents.o when linking. */
+#include "isensor.h"
+#endif
+#ifdef GET_FRU
+#include "ifru.h"
+#endif
+
+/*
+ * Global variables
+ */
+static char * progname = "ipmi_sample";
+static char * progver = "1.2";
+static char fdebug = 0;
+static char fset_mc = 0;
+static uchar g_bus = PUBLIC_BUS;
+static uchar g_sa = BMC_SA;
+static uchar g_lun = BMC_LUN;
+static uchar g_addrtype = ADDR_SMI;
+static char *mytag = NULL;
+static char *sdrfile = NULL;
+
+static int get_chassis_status(uchar *rdata, int rlen)
+{
+ uchar idata[4];
+ uchar ccode;
+ int ret;
+
+ ret = ipmi_cmdraw( CHASSIS_STATUS, NETFN_CHAS, g_sa,g_bus,g_lun,
+ idata,0, rdata,&rlen,&ccode, fdebug);
+ if (ret == 0 && ccode != 0) ret = ccode;
+ return(ret);
+} /*end get_chassis_status()*/
+
+#ifdef WIN32
+int __cdecl
+#else
+int
+#endif
+main(int argc, char **argv)
+{
+ int ret = 0;
+ char c;
+ uchar devrec[16];
+ uchar chstatus[4];
+ char *s1;
+ int loops = 1;
+ int nsec = 10;
+ char *nodefile = NULL;
+ int done = 0;
+ FILE *fp = NULL;
+ char nod[40]; char usr[24]; char psw[24];
+ char drvtyp[10];
+ char biosstr[40];
+ int n;
+#ifdef GET_SENSORS
+ uchar *sdrlist;
+#endif
+
+ printf("%s ver %s\n", progname,progver);
+
+ while ((c = getopt( argc, argv,"i:l:m:f:s:t:xEF:N:P:R:T:U:V:YZ:?")) != EOF )
+ switch(c) {
+ case 'm': /* specific IPMB MC, 3-byte address, e.g. "409600" */
+ g_bus = htoi(&optarg[0]); /*bus/channel*/
+ g_sa = htoi(&optarg[2]); /*device slave address*/
+ g_lun = htoi(&optarg[4]); /*LUN*/
+ g_addrtype = ADDR_IPMB;
+ if (optarg[6] == 's') {
+ g_addrtype = ADDR_SMI; s1 = "SMI";
+ } else { g_addrtype = ADDR_IPMB; s1 = "IPMB"; }
+ fset_mc = 1;
+ ipmi_set_mc(g_bus,g_sa,g_lun,g_addrtype);
+ printf("Use MC at %s bus=%x sa=%x lun=%x\n",
+ s1,g_bus,g_sa,g_lun);
+ break;
+ case 'f': nodefile = optarg; break; /* specific sensor tag */
+ case 'l': loops = atoi(optarg); break;
+ case 'i': nsec = atoi(optarg); break; /*interval in sec*/
+ case 's': sdrfile = optarg; break;
+ case 't': mytag = optarg; break; /* specific sensor tag */
+ case 'x': fdebug = 1; break; /* debug messages */
+ case 'N': /* nodename */
+ case 'U': /* remote username */
+ case 'P': /* remote password */
+ case 'R': /* remote password */
+ case 'E': /* get password from IPMI_PASSWORD environment var */
+ case 'F': /* force driver type */
+ case 'T': /* auth type */
+ case 'V': /* priv level */
+ case 'Y': /* prompt for remote password */
+ case 'Z': /* set local MC address */
+ parse_lan_options(c,optarg,fdebug);
+ if (c == 'F') strncpy(drvtyp,optarg,sizeof(drvtyp));
+ break;
+ default:
+ printf("Usage: %s [-filmstx -NUPREFTVY]\n", progname);
+ printf(" where -x show eXtra debug messages\n");
+ printf(" -f File use list of remote nodes from File\n");
+ printf(" -i 10 interval for each loop in seconds\n");
+ printf(" -l 10 loops sensor readings 10 times\n");
+ printf(" -m002000 specific MC (bus 00,sa 20,lun 00)\n");
+ printf(" -s File loads SDRs from File\n");
+ printf(" -t tag search for 'tag' in SDRs\n");
+ print_lan_opt_usage();
+ exit(1);
+ }
+ /* Rather than parse_lan_options above, the set_lan_options function
+ * could be used if the program already knows the nodename, etc. */
+ ret = get_BiosVersion(biosstr);
+ if (ret == 0) printf("BIOS Version: %s\n",biosstr);
+
+ while(!done)
+ {
+ if (nodefile != NULL) {
+ /* This will loop for each node in the file if -f was used.
+ * The file should contain one line per node:
+ * node1 user1 password1
+ * node2 user2 password2
+ */
+ if (fp == NULL) {
+ fp = fopen(nodefile,"r");
+ if (fp == NULL) {
+ printf("Cannot open file %s\n",nodefile);
+ ret = ERR_FILE_OPEN;
+ goto do_exit;
+ }
+ if (fdebug) printf("opened file %s ok\n",nodefile);
+ }
+ n = fscanf(fp,"%s %s %s", nod, usr, psw);
+ if (fdebug) printf("fscanf returned %d \n",n);
+ if (n == EOF || n <= 0) {
+ fclose(fp);
+ done = 1;
+ goto do_exit;
+ }
+ printf("Using -N %s -U %s -P %s ...\n",nod,usr,psw);
+ if (n > 0) parse_lan_options('N',nod,0);
+ if (n > 1) parse_lan_options('U',usr,0);
+ if (n > 2) parse_lan_options('P',psw,0);
+ if (drvtyp != NULL) parse_lan_options('F',drvtyp,0);
+ }
+
+ ret = ipmi_getdeviceid(devrec,16,fdebug);
+ if (ret != 0) {
+ printf("Cannot do ipmi_getdeviceid, ret = %d\n",ret);
+ goto do_exit;
+ } else { /*success*/
+ uchar ipmi_maj, ipmi_min;
+ ipmi_maj = devrec[4] & 0x0f;
+ ipmi_min = devrec[4] >> 4;
+ show_devid( devrec[2], devrec[3], ipmi_maj, ipmi_min);
+ }
+
+ ret = get_chassis_status(chstatus,4);
+ if (ret == 0) {
+ if (chstatus[0] & 0x01) s1 = "on";
+ else s1 = "off";
+ printf("Chassis Status = %02x (%s)\n",chstatus[0],s1);
+ }
+
+#ifdef GET_FRU
+ {
+ uchar *fru_data = NULL;
+ printf("Getting FRU ...\n");
+ ret = load_fru(0x20,0,0x07, &fru_data);
+ if (ret == 0)
+ ret = show_fru(0x20,0,0x07,fru_data);
+ if (fru_data != NULL)
+ free_fru(fru_data);
+ }
+#endif
+#ifdef GET_SENSORS
+ printf("Getting SDRs ...\n");
+ if (sdrfile != NULL) {
+ ret = get_sdr_file(sdrfile,&sdrlist);
+ } else {
+ ret = get_sdr_cache(&sdrlist);
+ }
+ printf("get_sdr_cache ret = %d\n",ret);
+ if (ret == 0) {
+ uchar sdrbuf[SDR_SZ];
+ uchar reading[4];
+ uchar snum = 0;
+ ushort id;
+ double val;
+ char *typestr;
+ char tag[17];
+ int j;
+
+ for (j = 0; j < loops; j++)
+ {
+ if (j > 0) {
+ printf("loop %d: wait %d seconds ...\n",j,nsec);
+ os_usleep(nsec,0); /*sleep 5 sec between loops*/
+ }
+ id = 0;
+ /* Get sensor readings for all full SDRs */
+ while(find_sdr_next(sdrbuf,sdrlist,id) == 0) {
+ id = sdrbuf[0] + (sdrbuf[1] << 8); /*this SDR id*/
+ if (sdrbuf[3] != 0x01) continue; /*only type 1 full SDRs*/
+ strncpy(tag,&sdrbuf[48],16);
+ tag[16] = 0;
+ snum = sdrbuf[7];
+ ret = GetSensorReading(snum, sdrbuf, reading);
+ if (ret == 0) {
+ val = RawToFloat(reading[0], sdrbuf);
+ typestr = get_unit_type( sdrbuf[20], sdrbuf[21], sdrbuf[22],0);
+ } else {
+ val = 0;
+ typestr = "na";
+ printf("%04x: get sensor %x reading ret = %d\n",id,snum,ret);
+ }
+ printf("%04x: sensor %x %s \treading = %.2f %s\n",
+ id,snum,tag,val,typestr);
+ memset(sdrbuf,0,SDR_SZ);
+ } /*end while*/
+ } /*end for(loops) */
+
+ /* Find a specific sensor by its tag and get a reading */
+ if (mytag != NULL) {
+ /* see option -t, mytag = "System"; or "System Temp" */
+ memset(sdrbuf,0,SDR_SZ);
+ ret = find_sdr_by_tag(sdrbuf, sdrlist, mytag, fdebug);
+ printf("find_sdr_by_tag(%s) ret = %d\n",mytag,ret);
+ strncpy(tag,&sdrbuf[48],16); /*assume full sdr tag offset*/
+ tag[16] = 0;
+ snum = sdrbuf[7];
+ ret = GetSensorReading(snum, sdrbuf, reading);
+ printf("get sensor %x reading ret = %d\n",snum,ret);
+ if (sdrbuf[3] == 0x01) { /*full SDR*/
+ if (ret == 0) {
+ val = RawToFloat(reading[0], sdrbuf);
+ typestr = get_unit_type(sdrbuf[20],sdrbuf[21],sdrbuf[22],0);
+ } else {
+ val = 0;
+ typestr = "na";
+ }
+ printf("sensor %x %s reading = %.2f %s\n",snum,tag,val,typestr);
+ } else printf("sensor %x type %x reading = %02x\n",
+ snum,sdrbuf[3],reading[2]);
+ }
+
+ free_sdr_cache(sdrlist);
+ } /*endif sdr_cache is valid*/
+#endif
+ ipmi_close_();
+ if (nodefile == NULL) done = 1;
+ } /*end while not done */
+
+do_exit:
+ show_outcome(progname,ret);
+ exit (ret);
+} /* end main()*/
+
+/* end ipmi_sample.c */