summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Styblik <stybla@turnovfree.net>2014-04-09 21:24:05 +0200
committerZdenek Styblik <stybla@turnovfree.net>2014-04-09 21:24:05 +0200
commita88db0d181b30ecca928d1eb6cec5f2a91c39d84 (patch)
treeb907361a2e792218bf99d6a67f96cccbbbf77e9b
parent42aba7eb4f8c813a362f149ba217493edd7f7cf8 (diff)
downloadipmitool-a88db0d181b30ecca928d1eb6cec5f2a91c39d84.tar.gz
ID: 300 - new sunoem functionality
Main changes include: * direct connection to ILOM command line interface * ability to add/delete ssh keys fot ILOM users * ability to set ILOM properties * ability to retrieve various logs from SP * removal of obsolete/non-functioning code and other misc changes Commit for Martin Hovorka of Oracle
-rw-r--r--include/ipmitool/ipmi_sunoem.h38
-rw-r--r--lib/ipmi_sunoem.c2145
2 files changed, 1887 insertions, 296 deletions
diff --git a/include/ipmitool/ipmi_sunoem.h b/include/ipmitool/ipmi_sunoem.h
index b2cddd1..78afbf2 100644
--- a/include/ipmitool/ipmi_sunoem.h
+++ b/include/ipmitool/ipmi_sunoem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,19 +39,35 @@
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_sdr.h>
-#define IPMI_NETFN_SUNOEM 0x2e
+#define IPMI_NETFN_SUNOEM 0x2e
-#define IPMI_SUNOEM_SET_SSH_KEY 0x01
-#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
-#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
-#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
-#define IPMI_SUNOEM_LED_GET 0x21
-#define IPMI_SUNOEM_LED_SET 0x22
+#define IPMI_SUNOEM_SET_SSH_KEY 0x01
+#define IPMI_SUNOEM_DEL_SSH_KEY 0x02
+#define IPMI_SUNOEM_GET_HEALTH_STATUS 0x10
+#define IPMI_SUNOEM_CLI 0x19
+#define IPMI_SUNOEM_SET_FAN_SPEED 0x20
+#define IPMI_SUNOEM_LED_GET 0x21
+#define IPMI_SUNOEM_LED_SET 0x22
+#define IPMI_SUNOEM_ECHO 0x23
+#define IPMI_SUNOEM_VERSION 0x24
+#define IPMI_SUNOEM_NACNAME 0x29
+#define IPMI_SUNOEM_GETVAL 0x2A
+#define IPMI_SUNOEM_SETVAL 0x2C
+#define IPMI_SUNOEM_SENSOR_SET 0x3A
+#define IPMI_SUNOEM_SET_FAN_MODE 0x41
+#define IPMI_SUNOEM_CORE_TUNNEL 0x44
-int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
+/*
+ * Error codes of sunoem functions
+ */
+typedef enum {
+ SUNOEM_EC_SUCCESS = 0,
+ SUNOEM_EC_INVALID_ARG = 1,
+ SUNOEM_EC_BMC_NOT_RESPONDING = 2,
+ SUNOEM_EC_BMC_CCODE_NONZERO = 3
+} sunoem_ec_t;
-struct ipmi_rs * sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype);
-struct ipmi_rs * sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev, int ledtype, int ledmode);
+int ipmi_sunoem_main(struct ipmi_intf *, int, char **);
#endif /*IPMI_SUNOEM_H*/
diff --git a/lib/ipmi_sunoem.c b/lib/ipmi_sunoem.c
index 9fa7d02..16a6090 100644
--- a/lib/ipmi_sunoem.c
+++ b/lib/ipmi_sunoem.c
@@ -1,21 +1,21 @@
/*
- * Copyright (c) 2005 Sun Microsystems, Inc. All Rights Reserved.
- *
+ * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights 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 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
@@ -33,14 +33,22 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
+#include <time.h>
#include <unistd.h>
#include <signal.h>
#include <ctype.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <fcntl.h>
+
+#include <termios.h>
#include <ipmitool/ipmi.h>
#include <ipmitool/ipmi_intf.h>
@@ -69,6 +77,7 @@ static const struct valstr sunoem_led_mode_vals[] = {
{ 4, "FAST" },
{ 0xFF, NULL },
};
+
static const struct valstr sunoem_led_mode_optvals[] = {
{ 0, "STEADY_OFF" },
{ 1, "STEADY_ON" },
@@ -78,232 +87,269 @@ static const struct valstr sunoem_led_mode_optvals[] = {
{ 0xFF, NULL },
};
-int is_sbcmd = 0;
+#define SUNOEM_SUCCESS 1
+
+#define IPMI_SUNOEM_GETFILE_VERSION {3,2,0,0}
+#define IPMI_SUNOEM_GETBEHAVIOR_VERSION {3,2,0,0}
+
+/*
+ * PRINT_NORMAL: print out the LED value as normal
+ * PRINT_ERROR: print out "na" for the LED value
+ */
+typedef enum
+{
+ PRINT_NORMAL = 0, PRINT_ERROR
+} print_status_t;
+
+int ret_get = 0;
+int ret_set = 0;
static void
ipmi_sunoem_usage(void)
{
- lprintf(LOG_NOTICE, "usage: sunoem <command> [option...]");
+ lprintf(LOG_NOTICE, "Usage: sunoem <command> [option...]");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, "Commands:");
+ lprintf(LOG_NOTICE, " - cli [<command string> ...]");
+ lprintf(LOG_NOTICE, " Execute SP CLI commands.");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - led get [<sensor_id>] [ledtype]");
+ lprintf(LOG_NOTICE, " - Read status of LED found in Generic Device Locator.");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - led set <sensor_id> <led_mode> [led_type]");
+ lprintf(LOG_NOTICE, " - Set mode of LED found in Generic Device Locator.");
+ lprintf(LOG_NOTICE, " - You can pass 'all' as the <senso_rid> to change the LED mode of all sensors.");
+ lprintf(LOG_NOTICE, " - Use 'sdr list generic' command to get list of Generic");
+ lprintf(LOG_NOTICE, " - Devices that are controllable LEDs.");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - Required SIS LED Mode:");
+ lprintf(LOG_NOTICE, " OFF Off");
+ lprintf(LOG_NOTICE, " ON Steady On");
+ lprintf(LOG_NOTICE, " STANDBY 100ms on 2900ms off blink rate");
+ lprintf(LOG_NOTICE, " SLOW 1HZ blink rate");
+ lprintf(LOG_NOTICE, " FAST 4HZ blink rate");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - Optional SIS LED Type:");
+ lprintf(LOG_NOTICE, " OK2RM OK to Remove");
+ lprintf(LOG_NOTICE, " SERVICE Service Required");
+ lprintf(LOG_NOTICE, " ACT Activity");
+ lprintf(LOG_NOTICE, " LOCATE Locate");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - nacname <ipmi_nac_name>");
+ lprintf(LOG_NOTICE, " - Returns the full nac name");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - ping NUMBER <q>");
+ lprintf(LOG_NOTICE, " - Send and Receive NUMBER (64 Byte) packets.");
+ lprintf(LOG_NOTICE, "");
+ lprintf(LOG_NOTICE, " - q - Quiet. Displays output at start and end");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " fan speed <0-100>");
- lprintf(LOG_NOTICE, " Set system fan speed (PWM duty cycle)");
+ lprintf(LOG_NOTICE, " - getval <target_name>");
+ lprintf(LOG_NOTICE, " - Returns the ILOM property value");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " sshkey set <userid> <id_rsa.pub>");
- lprintf(LOG_NOTICE, " Set ssh key for a userid into authorized_keys,");
- lprintf(LOG_NOTICE, " view users with 'user list' command.");
+ lprintf(LOG_NOTICE, " - setval <property name> <property value> <timeout>");
+ lprintf(LOG_NOTICE, " - Sets the ILOM property value");
+ lprintf(LOG_NOTICE, " - If timeout is not specified, the default is 5 sec.");
+ lprintf(LOG_NOTICE, " - NOTE: must be executed locally on host, not remotely over LAN!");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " sshkey del <userid>");
- lprintf(LOG_NOTICE, " Delete ssh key for userid from authorized_keys,");
- lprintf(LOG_NOTICE, " view users with 'user list' command.");
+ lprintf(LOG_NOTICE, " - sshkey del <user_id>");
+ lprintf(LOG_NOTICE, " - Delete ssh key for user id from authorized_keys,");
+ lprintf(LOG_NOTICE, " - view users with 'user list' command.");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " led get <sensorid> [ledtype]");
- lprintf(LOG_NOTICE,
- " Read status of LED found in Generic Device Locator.");
+ lprintf(LOG_NOTICE, " - sshkey set <user_id> <id_rsa.pub>");
+ lprintf(LOG_NOTICE, " - Set ssh key for a userid into authorized_keys,");
+ lprintf(LOG_NOTICE, " - view users with 'user list' command.");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " led set <sensorid> <ledmode> [ledtype]");
- lprintf(LOG_NOTICE,
- " Set mode of LED found in Generic Device Locator.");
+ lprintf(LOG_NOTICE, " - version");
+ lprintf(LOG_NOTICE, " - Display the software version");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " sbled get <sensorid> [ledtype]");
- lprintf(LOG_NOTICE,
- " Read status of LED found in Generic Device Locator");
- lprintf(LOG_NOTICE, " for Sun Blade Modular Systems.");
+ lprintf(LOG_NOTICE, " - nacname <ipmi_nac_name>");
+ lprintf(LOG_NOTICE, " - Returns the full nac name");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " sbled set <sensorid> <ledmode> [ledtype]");
- lprintf(LOG_NOTICE, " Set mode of LED found in Generic Device Locator");
- lprintf(LOG_NOTICE, " for Sun Blade Modular Systems.");
+ lprintf(LOG_NOTICE, " - getfile <file_string_id> <destination_file_name>");
+ lprintf(LOG_NOTICE, " - Copy file <file_string_id> to <destination_file_name>");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE,
- " Use 'sdr list generic' command to get list of Generic");
- lprintf(LOG_NOTICE, " Devices that are controllable LEDs.");
+ lprintf(LOG_NOTICE, " - File string ids:");
+ lprintf(LOG_NOTICE, " SSH_PUBKEYS");
+ lprintf(LOG_NOTICE, " DIAG_PASSED");
+ lprintf(LOG_NOTICE, " DIAG_FAILED");
+ lprintf(LOG_NOTICE, " DIAG_END_TIME");
+ lprintf(LOG_NOTICE, " DIAG_INVENTORY");
+ lprintf(LOG_NOTICE, " DIAG_TEST_LOG");
+ lprintf(LOG_NOTICE, " DIAG_START_TIME");
+ lprintf(LOG_NOTICE, " DIAG_UEFI_LOG");
+ lprintf(LOG_NOTICE, " DIAG_TEST_LOG");
+ lprintf(LOG_NOTICE, " DIAG_LAST_LOG");
+ lprintf(LOG_NOTICE, " DIAG_LAST_CMD");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " Required SIS LED Mode:");
- lprintf(LOG_NOTICE, " OFF Off");
- lprintf(LOG_NOTICE, " ON Steady On");
- lprintf(LOG_NOTICE, " STANDBY 100ms on 2900ms off blink rate");
- lprintf(LOG_NOTICE, " SLOW 1HZ blink rate");
- lprintf(LOG_NOTICE, " FAST 4HZ blink rate");
+ lprintf(LOG_NOTICE, " - getbehavior <behavior_string_id>");
+ lprintf(LOG_NOTICE, " - Test if ILOM behavior is enabled");
lprintf(LOG_NOTICE, "");
- lprintf(LOG_NOTICE, " Optional SIS LED Type:");
- lprintf(LOG_NOTICE, " OK2RM OK to Remove");
- lprintf(LOG_NOTICE, " SERVICE Service Required");
- lprintf(LOG_NOTICE, " ACT Activity");
- lprintf(LOG_NOTICE, " LOCATE Locate");
+ lprintf(LOG_NOTICE, " - Behavior string ids:");
+ lprintf(LOG_NOTICE, " SUPPORTS_SIGNED_PACKAGES");
+ lprintf(LOG_NOTICE, " REQUIRES_SIGNED_PACKAGES");
lprintf(LOG_NOTICE, "");
}
-/*
- * IPMI Request Data: 1 byte
- *
- * [byte 0] FanSpeed Fan speed as percentage
- */
-static int
-ipmi_sunoem_fan_speed(struct ipmi_intf * intf, uint8_t speed)
-{
- struct ipmi_rs * rsp;
- struct ipmi_rq req;
-
- /*
- * sunoem fan speed <percent>
- */
-
- if (speed > 100) {
- lprintf(LOG_NOTICE, "Invalid fan speed: %d", speed);
- return -1;
- }
-
- req.msg.netfn = IPMI_NETFN_SUNOEM;
- req.msg.cmd = IPMI_SUNOEM_SET_FAN_SPEED;
- req.msg.data = &speed;
- req.msg.data_len = 1;
-
- rsp = intf->sendrecv(intf, &req);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed");
- return -1;
- }
- else if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Sun OEM Set Fan Speed command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return -1;
- }
-
- printf("Set Fan speed to %d%%\n", speed);
-
- return 0;
-}
+#define SUNOEM_FAN_MODE_AUTO 0x00
+#define SUNOEM_FAN_MODE_MANUAL 0x01
static void
__sdr_list_empty(struct sdr_record_list * head)
{
- struct sdr_record_list * e, * f;
+ struct sdr_record_list * e, *f;
for (e = head; e != NULL; e = f) {
f = e->next;
free(e);
- e = NULL;
}
head = NULL;
}
+/*
+ * led_print
+ * Print out the led name and the state, if stat is PRINT_NORMAL.
+ * Otherwise, print out the led name and "na".
+ * The state parameter is not referenced if stat is not PRINT_NORMAL.
+ */
static void
-led_print(const char * name, uint8_t state)
+led_print(const char * name, print_status_t stat, uint8_t state)
{
- if (csv_output)
- printf("%s,%s\n", name, val2str(state, sunoem_led_mode_vals));
- else
- printf("%-16s | %s\n", name, val2str(state, sunoem_led_mode_vals));
+ const char *theValue;
+
+ if (stat == PRINT_NORMAL) {
+ theValue = val2str(state, sunoem_led_mode_vals);
+ } else {
+ theValue = "na";
+ }
+
+ if (csv_output) {
+ printf("%s,%s\n", name, theValue);
+ } else {
+ printf("%-16s | %s\n", name, theValue);
+ }
}
-struct ipmi_rs *
-sunoem_led_get(struct ipmi_intf * intf,
- struct sdr_record_generic_locator * dev,
- int ledtype)
+#define CC_NORMAL 0x00
+#define CC_PARAM_OUT_OF_RANGE 0xc9
+#define CC_DEST_UNAVAILABLE 0xd3
+#define CC_UNSPECIFIED_ERR 0xff
+#define CC_INSUFFICIENT_PRIVILEGE 0xd4
+#define CC_INV_CMD 0xc1
+#define CC_INV_DATA_FIELD 0xcc
+
+/*
+ * sunoem_led_get(....)
+ *
+ * OUTPUT:
+ * SUNOEM_EC_INVALID_ARG if dev is NULL,
+ * SUNOEM_EC_BMC_NOT_RESPONDING if no reply is obtained from BMC,
+ * SUNOEM_EC_BMC_CCODE_NONZERO if completion code is nonzero,
+ * SUNOEM_EC_SUCCESS otherwise.
+ */
+static sunoem_ec_t
+sunoem_led_get(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev,
+ int ledtype, struct ipmi_rs **loc_rsp)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t rqdata[7];
- int rqdata_len = 5;
+ int rqdata_len;
- if (dev == NULL)
- return NULL;
+ if (dev == NULL) {
+ *loc_rsp = NULL;
+ return (SUNOEM_EC_INVALID_ARG);
+ }
rqdata[0] = dev->dev_slave_addr;
if (ledtype == 0xFF)
rqdata[1] = dev->oem;
else
rqdata[1] = ledtype;
+
rqdata[2] = dev->dev_access_addr;
rqdata[3] = dev->oem;
- if (is_sbcmd) {
- rqdata[4] = dev->entity.id;
- rqdata[5] = dev->entity.instance;
- rqdata[6] = 0;
- rqdata_len = 7;
- }
- else {
- rqdata[4] = 0;
- }
+ rqdata[4] = dev->entity.id;
+ rqdata[5] = dev->entity.instance;
+ rqdata[6] = 0;
+ rqdata_len = 7;
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_LED_GET;
req.msg.lun = dev->lun;
req.msg.data = rqdata;
req.msg.data_len = rqdata_len;
-
+
rsp = intf->sendrecv(intf, &req);
+ /*
+ * Just return NULL if there was
+ * an error.
+ */
if (rsp == NULL) {
- lprintf(LOG_ERR, "Sun OEM Get LED command failed");
- return NULL;
- }
- else if (rsp->ccode > 0) {
- lprintf(LOG_ERR, "Sun OEM Get LED command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
- return NULL;
+ *loc_rsp = NULL;
+ return (SUNOEM_EC_BMC_NOT_RESPONDING);
+ } else if (rsp->ccode > 0) {
+ *loc_rsp = rsp;
+ return (SUNOEM_EC_BMC_CCODE_NONZERO);
+ } else {
+ *loc_rsp = rsp;
+ return (SUNOEM_EC_SUCCESS);
}
-
- return rsp;
}
-struct ipmi_rs *
-sunoem_led_set(struct ipmi_intf * intf,
- struct sdr_record_generic_locator * dev,
- int ledtype, int ledmode)
+static struct ipmi_rs *
+sunoem_led_set(struct ipmi_intf * intf, struct sdr_record_generic_locator * dev,
+ int ledtype, int ledmode)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t rqdata[9];
- int rqdata_len = 7;
+ int rqdata_len;
if (dev == NULL)
return NULL;
rqdata[0] = dev->dev_slave_addr;
+
if (ledtype == 0xFF)
rqdata[1] = dev->oem;
else
rqdata[1] = ledtype;
+
rqdata[2] = dev->dev_access_addr;
rqdata[3] = dev->oem;
rqdata[4] = ledmode;
- if (is_sbcmd) {
- rqdata[5] = dev->entity.id;
- rqdata[6] = dev->entity.instance;
- rqdata[7] = 0;
- rqdata[8] = 0;
- rqdata_len = 9;
- }
- else {
- rqdata[5] = 0;
- rqdata[6] = 0;
- }
+ rqdata[5] = dev->entity.id;
+ rqdata[6] = dev->entity.instance;
+ rqdata[7] = 0;
+ rqdata[8] = 0;
+ rqdata_len = 9;
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_LED_SET;
req.msg.lun = dev->lun;
req.msg.data = rqdata;
req.msg.data_len = rqdata_len;
-
+
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
- lprintf(LOG_ERR, "Sun OEM Set LED command failed");
+ lprintf(LOG_ERR, "Sun OEM Set LED command failed.");
return NULL;
- }
- else if (rsp->ccode > 0) {
+ } else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Sun OEM Set LED command failed: %s",
- val2str(rsp->ccode, completion_code_vals));
+ val2str(rsp->ccode, completion_code_vals));
return NULL;
}
- return rsp;
+ return (rsp);
}
static void
sunoem_led_get_byentity(struct ipmi_intf * intf, uint8_t entity_id,
- uint8_t entity_inst, int ledtype)
+ uint8_t entity_inst, int ledtype)
{
struct ipmi_rs * rsp;
struct sdr_record_list *elist, *e;
struct entity_id entity;
+ sunoem_ec_t res;
if (entity_id == 0)
return;
@@ -315,22 +361,34 @@ sunoem_led_get_byentity(struct ipmi_intf * intf, uint8_t entity_id,
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
- /* for each generic sensor set its led state */
+ if (elist == NULL)
+ ret_get = -1;
+
+ /* for each generic sensor get its led state */
for (e = elist; e != NULL; e = e->next) {
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
- rsp = sunoem_led_get(intf, e->record.genloc, ledtype);
- if (rsp && rsp->data_len == 1) {
- led_print((const char *)e->record.genloc->id_string, rsp->data[0]);
+
+ res = sunoem_led_get(intf, e->record.genloc, ledtype, &rsp);
+
+ if (res == SUNOEM_EC_SUCCESS && rsp && rsp->data_len == 1) {
+ led_print((const char *) e->record.genloc->id_string, PRINT_NORMAL,
+ rsp->data[0]);
+ } else {
+ led_print((const char *) e->record.genloc->id_string, PRINT_ERROR,
+ 0);
+ if (res != SUNOEM_EC_BMC_CCODE_NONZERO|| !rsp
+ || rsp->ccode != CC_DEST_UNAVAILABLE) {
+ ret_get = -1;
+ }
}
}
-
__sdr_list_empty(elist);
}
static void
sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
- uint8_t entity_inst, int ledtype, int ledmode)
+ uint8_t entity_inst, int ledtype, int ledmode)
{
struct ipmi_rs * rsp;
struct sdr_record_list *elist, *e;
@@ -346,20 +404,28 @@ sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
elist = ipmi_sdr_find_sdr_byentity(intf, &entity);
+ if (elist == NULL)
+ ret_set = -1;
+
/* for each generic sensor set its led state */
for (e = elist; e != NULL; e = e->next) {
+
if (e->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
+
rsp = sunoem_led_set(intf, e->record.genloc, ledtype, ledmode);
if (rsp && rsp->data_len == 0) {
- led_print((const char *)e->record.genloc->id_string, ledmode);
+ led_print((const char *) e->record.genloc->id_string, PRINT_NORMAL,
+ ledmode);
+ } else if (rsp == NULL) {
+ ret_set = -1;
}
}
__sdr_list_empty(elist);
}
-/*
+/*
* IPMI Request Data: 5 bytes
*
* [byte 0] devAddr Value from the "Device Slave Address" field in
@@ -371,7 +437,7 @@ sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
* [byte 4] force 1 = directly access the device
* 0 = go thru its controller
* Ignored if LED is local
- *
+ *
* The format below is for Sun Blade Modular systems only
* [byte 4] entityID The entityID field from the SDR record
* [byte 5] entityIns The entityIns field from the SDR record
@@ -380,7 +446,7 @@ sunoem_led_set_byentity(struct ipmi_intf * intf, uint8_t entity_id,
* Ignored if LED is local
*/
static int
-ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
+ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct sdr_record_list *sdr;
@@ -388,38 +454,58 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
struct sdr_record_entity_assoc *assoc;
int ledtype = 0xFF;
int i;
+ sunoem_ec_t res;
- /*
+ /*
* sunoem led/sbled get <id> [type]
*/
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
ipmi_sunoem_usage();
- return 0;
+ return (0);
}
if (argc > 1) {
ledtype = str2val(argv[1], sunoem_led_type_vals);
- if (ledtype == 0xFF)
- lprintf(LOG_ERR, "Unknow ledtype, will use data from the SDR oem field");
+ if (ledtype == 0xFF)
+ lprintf(LOG_ERR,
+ "Unknow ledtype, will use data from the SDR oem field");
}
if (strncasecmp(argv[0], "all", 3) == 0) {
/* do all generic sensors */
alist = ipmi_sdr_find_sdr_bytype(intf,
- SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
+ SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
+
+ if (alist == NULL)
+ return (-1);
+
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
if (a->record.genloc->entity.logical)
continue;
- rsp = sunoem_led_get(intf, a->record.genloc, ledtype);
- if (rsp && rsp->data_len == 1) {
- led_print((const char *)a->record.genloc->id_string, rsp->data[0]);
+
+ res = sunoem_led_get(intf, a->record.genloc, ledtype, &rsp);
+
+ if (res == SUNOEM_EC_SUCCESS && rsp && rsp->data_len == 1) {
+ led_print((const char *) a->record.genloc->id_string,
+ PRINT_NORMAL, rsp->data[0]);
+ } else {
+ led_print((const char *) a->record.genloc->id_string,
+ PRINT_ERROR, 0);
+ if (res != SUNOEM_EC_BMC_CCODE_NONZERO|| !rsp ||
+ rsp->ccode != CC_DEST_UNAVAILABLE) {
+ ret_get = -1;
+ }
}
}
__sdr_list_empty(alist);
- return 0;
+
+ if (ret_get == -1)
+ return (-1);
+
+ return (0);
}
/* look up generic device locator record in SDR */
@@ -427,26 +513,41 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
if (sdr == NULL) {
lprintf(LOG_ERR, "No Sensor Data Record found for %s", argv[0]);
- return -1;
+ return (-1);
}
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
- return -1;
+ return (-1);
}
if (!sdr->record.genloc->entity.logical) {
/*
* handle physical entity
*/
- rsp = sunoem_led_get(intf, sdr->record.genloc, ledtype);
- if (rsp && rsp->data_len == 1) {
- led_print((const char *)sdr->record.genloc->id_string, rsp->data[0]);
+
+ res = sunoem_led_get(intf, sdr->record.genloc, ledtype, &rsp);
+
+ if (res == SUNOEM_EC_SUCCESS && rsp && rsp->data_len == 1) {
+ led_print((const char *) sdr->record.genloc->id_string,
+ PRINT_NORMAL, rsp->data[0]);
+
+ } else {
+ led_print((const char *) sdr->record.genloc->id_string, PRINT_ERROR,
+ 0);
+ if (res != SUNOEM_EC_BMC_CCODE_NONZERO|| !rsp
+ || rsp->ccode != CC_DEST_UNAVAILABLE) {
+ ret_get = -1;
+ }
}
- return 0;
+
+ if (ret_get == -1)
+ return (-1);
+
+ return (0);
}
- /*
+ /*
* handle logical entity for LED grouping
*/
@@ -454,6 +555,10 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
/* get entity assoc records */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
+
+ if (alist == NULL)
+ return (-1);
+
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
continue;
@@ -462,8 +567,9 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
continue;
/* check that the entity id/instance matches our generic record */
- if (assoc->entity.id != sdr->record.genloc->entity.id ||
- assoc->entity.instance != sdr->record.genloc->entity.instance)
+ if (assoc->entity.id != sdr->record.genloc->entity.id
+ || assoc->entity.instance
+ != sdr->record.genloc->entity.instance)
continue;
if (assoc->flags.isrange) {
@@ -477,34 +583,38 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
/* first range set - id 1 and 2 must be equal */
if (assoc->entity_id_1 == assoc->entity_id_2)
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
- sunoem_led_get_byentity(intf, assoc->entity_id_1, i, ledtype);
+ sunoem_led_get_byentity(intf, assoc->entity_id_1, i,
+ ledtype);
/* second range set - id 3 and 4 must be equal */
if (assoc->entity_id_3 == assoc->entity_id_4)
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
- sunoem_led_get_byentity(intf, assoc->entity_id_3, i, ledtype);
- }
- else {
+ sunoem_led_get_byentity(intf, assoc->entity_id_3, i,
+ ledtype);
+ } else {
/*
* handle entity list
*/
sunoem_led_get_byentity(intf, assoc->entity_id_1,
- assoc->entity_inst_1, ledtype);
+ assoc->entity_inst_1, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_2,
- assoc->entity_inst_2, ledtype);
+ assoc->entity_inst_2, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_3,
- assoc->entity_inst_3, ledtype);
+ assoc->entity_inst_3, ledtype);
sunoem_led_get_byentity(intf, assoc->entity_id_4,
- assoc->entity_inst_4, ledtype);
+ assoc->entity_inst_4, ledtype);
}
}
__sdr_list_empty(alist);
- return 0;
+ if (ret_get == -1)
+ return (-1);
+
+ return (0);
}
-/*
+/*
* IPMI Request Data: 7 bytes
*
* [byte 0] devAddr Value from the "Device Slave Address" field in
@@ -529,12 +639,12 @@ ipmi_sunoem_led_get(struct ipmi_intf * intf, int argc, char ** argv)
*
*
* IPMI Response Data: 1 byte
- *
+ *
* [byte 0] mode LED Mode: OFF, ON, STANDBY, SLOW, FAST
*/
static int
-ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
+ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
{
struct ipmi_rs * rsp;
struct sdr_record_list *sdr;
@@ -544,13 +654,13 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
int ledtype = 0xFF;
int i;
- /*
+ /*
* sunoem led/sbled set <id> <mode> [type]
*/
if (argc < 2 || strncmp(argv[0], "help", 4) == 0) {
ipmi_sunoem_usage();
- return 0;
+ return (0);
}
ledmode = str2val(argv[1], sunoem_led_mode_vals);
@@ -558,46 +668,56 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
ledmode = str2val(argv[1], sunoem_led_mode_optvals);
if (ledmode == 0xFF) {
lprintf(LOG_NOTICE, "Invalid LED Mode: %s", argv[1]);
- return -1;
+ return (-1);
}
}
if (argc > 3) {
ledtype = str2val(argv[2], sunoem_led_type_vals);
- if (ledtype == 0xFF)
- lprintf(LOG_ERR, "Unknow ledtype, will use data from the SDR oem field");
+ if (ledtype == 0xFF)
+ lprintf(LOG_ERR,
+ "Unknow ledtype, will use data from the SDR oem field");
}
if (strncasecmp(argv[0], "all", 3) == 0) {
/* do all generic sensors */
alist = ipmi_sdr_find_sdr_bytype(intf,
- SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
+ SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR);
+
+ if (alist == NULL)
+ return (-1);
+
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR)
continue;
if (a->record.genloc->entity.logical)
continue;
rsp = sunoem_led_set(intf, a->record.genloc, ledtype, ledmode);
- if (rsp && rsp->ccode == 0) {
- led_print((const char *)a->record.genloc->id_string, ledmode);
- }
+ if (rsp && rsp->ccode == 0)
+ led_print((const char *) a->record.genloc->id_string,
+ PRINT_NORMAL, ledmode);
+ else
+ ret_set = -1;
}
__sdr_list_empty(alist);
- return 0;
+
+ if (ret_set == -1)
+ return (-1);
+
+ return (0);
}
/* look up generic device locator records in SDR */
sdr = ipmi_sdr_find_sdr_byid(intf, argv[0]);
if (sdr == NULL) {
- lprintf(LOG_ERR, "No Sensor Data Record found for %s",
- argv[0]);
- return -1;
+ lprintf(LOG_ERR, "No Sensor Data Record found for %s", argv[0]);
+ return (-1);
}
if (sdr->type != SDR_RECORD_TYPE_GENERIC_DEVICE_LOCATOR) {
lprintf(LOG_ERR, "Invalid SDR type %d", sdr->type);
- return -1;
+ return (-1);
}
if (!sdr->record.genloc->entity.logical) {
@@ -605,13 +725,15 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
* handle physical entity
*/
rsp = sunoem_led_set(intf, sdr->record.genloc, ledtype, ledmode);
- if (rsp && rsp->ccode == 0) {
- led_print(argv[0], ledmode);
- }
- return 0;
+ if (rsp && rsp->ccode == 0)
+ led_print(argv[0], PRINT_NORMAL, ledmode);
+ else
+ return (-1);
+
+ return (0);
}
- /*
+ /*
* handle logical entity for LED grouping
*/
@@ -619,6 +741,10 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
/* get entity assoc records */
alist = ipmi_sdr_find_sdr_bytype(intf, SDR_RECORD_TYPE_ENTITY_ASSOC);
+
+ if (alist == NULL)
+ return (-1);
+
for (a = alist; a != NULL; a = a->next) {
if (a->type != SDR_RECORD_TYPE_ENTITY_ASSOC)
continue;
@@ -627,8 +753,9 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
continue;
/* check that the entity id/instance matches our generic record */
- if (assoc->entity.id != sdr->record.genloc->entity.id ||
- assoc->entity.instance != sdr->record.genloc->entity.instance)
+ if (assoc->entity.id != sdr->record.genloc->entity.id
+ || assoc->entity.instance
+ != sdr->record.genloc->entity.instance)
continue;
if (assoc->flags.isrange) {
@@ -642,33 +769,35 @@ ipmi_sunoem_led_set(struct ipmi_intf * intf, int argc, char ** argv)
/* first range set - id 1 and 2 must be equal */
if (assoc->entity_id_1 == assoc->entity_id_2)
for (i = assoc->entity_inst_1; i <= assoc->entity_inst_2; i++)
- sunoem_led_set_byentity(intf, assoc->entity_id_1, i, ledtype,
- ledmode);
+ sunoem_led_set_byentity(intf, assoc->entity_id_1, i,
+ ledtype, ledmode);
/* second range set - id 3 and 4 must be equal */
if (assoc->entity_id_3 == assoc->entity_id_4)
for (i = assoc->entity_inst_3; i <= assoc->entity_inst_4; i++)
- sunoem_led_set_byentity(intf, assoc->entity_id_3, i, ledtype,
- ledmode);
- }
- else {
+ sunoem_led_set_byentity(intf, assoc->entity_id_3, i,
+ ledtype, ledmode);
+ } else {
/*
* handle entity list
*/
sunoem_led_set_byentity(intf, assoc->entity_id_1,
- assoc->entity_inst_1, ledtype, ledmode);
+ assoc->entity_inst_1, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_2,
- assoc->entity_inst_2, ledtype, ledmode);
+ assoc->entity_inst_2, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_3,
- assoc->entity_inst_3, ledtype, ledmode);
+ assoc->entity_inst_3, ledtype, ledmode);
sunoem_led_set_byentity(intf, assoc->entity_id_4,
- assoc->entity_inst_4, ledtype, ledmode);
+ assoc->entity_inst_4, ledtype, ledmode);
}
}
__sdr_list_empty(alist);
- return 0;
+ if (ret_set == -1)
+ return (-1);
+
+ return (0);
}
static int
@@ -686,16 +815,15 @@ ipmi_sunoem_sshkey_del(struct ipmi_intf * intf, uint8_t uid)
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d", uid);
- return -1;
- }
- else if (rsp->ccode > 0) {
+ return (-1);
+ } else if (rsp->ccode > 0) {
lprintf(LOG_ERR, "Unable to delete ssh key for UID %d: %s", uid,
- val2str(rsp->ccode, completion_code_vals));
- return -1;
+ val2str(rsp->ccode, completion_code_vals));
+ return (-1);
}
printf("Deleted SSH key for user id %d\n", uid);
- return 0;
+ return (0);
}
#define SSHKEY_BLOCK_SIZE 64
@@ -705,31 +833,60 @@ ipmi_sunoem_sshkey_set(struct ipmi_intf * intf, uint8_t uid, char * ifile)
struct ipmi_rs * rsp;
struct ipmi_rq req;
FILE * fp;
- int count;
- uint16_t i_size, r, size;
+ int count = 0;
uint8_t wbuf[SSHKEY_BLOCK_SIZE + 3];
+ int32_t i_size = 0;
+ int32_t r = 0;
+ int32_t size = 0;
if (ifile == NULL) {
- lprintf(LOG_ERR, "Invalid or misisng input filename");
- return -1;
+ lprintf(LOG_ERR, "Invalid or misisng input filename.");
+ return (-1);
}
fp = ipmi_open_file_read(ifile);
if (fp == NULL) {
- lprintf(LOG_ERR, "Unable to open file %s for reading", ifile);
- return -1;
+ lprintf(LOG_ERR, "Unable to open file '%s' for reading.", ifile);
+ return (-1);
}
- printf("Setting SSH key for user id %d...", uid);
-
memset(&req, 0, sizeof(struct ipmi_rq));
req.msg.netfn = IPMI_NETFN_SUNOEM;
req.msg.cmd = IPMI_SUNOEM_SET_SSH_KEY;
req.msg.data = wbuf;
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
+ if (fseek(fp, 0, SEEK_END) == (-1)) {
+ lprintf(LOG_ERR, "Failed to seek in file '%s'.", ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ }
+
+ size = (int32_t) ftell(fp);
+ if (size < 0) {
+ lprintf(LOG_ERR, "Failed to seek in file '%s'.", ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ } else if (size == 0) {
+ lprintf(LOG_ERR, "File '%s' is empty.", ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ }
+
+ if (fseek(fp, 0, SEEK_SET) == (-1)) {
+ lprintf(LOG_ERR, "Failed to seek in file '%s'.", ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ }
+
+ printf("Setting SSH key for user id %d...", uid);
for (r = 0; r < size; r += i_size) {
i_size = size - r;
@@ -737,15 +894,16 @@ ipmi_sunoem_sshkey_set(struct ipmi_intf * intf, uint8_t uid, char * ifile)
i_size = SSHKEY_BLOCK_SIZE;
memset(wbuf, 0, SSHKEY_BLOCK_SIZE);
- if (-1 == fseek(fp, r, SEEK_SET)) {
- lprintf(LOG_ERR, "Seek error %s. %s", ifile, strerror(errno));
- return -1;
- }
- count = fread(wbuf+3, 1, i_size, fp);
+ fseek(fp, r, SEEK_SET);
+ count = fread(wbuf + 3, 1, i_size, fp);
if (count != i_size) {
- lprintf(LOG_ERR, "Unable to read %d bytes from file %s", i_size, ifile);
- fclose(fp);
- return -1;
+ printf("failed\n");
+ lprintf(LOG_ERR, "Unable to read %ld bytes from file '%s'.", i_size,
+ ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
}
printf(".");
@@ -754,106 +912,1523 @@ ipmi_sunoem_sshkey_set(struct ipmi_intf * intf, uint8_t uid, char * ifile)
wbuf[0] = uid;
if ((r + SSHKEY_BLOCK_SIZE) >= size)
wbuf[1] = 0xff;
- else
- wbuf[1] = (uint8_t)(r / SSHKEY_BLOCK_SIZE);
- wbuf[2] = i_size;
+ else {
+ if ((r / SSHKEY_BLOCK_SIZE) > UINT8_MAX) {
+ printf("failed\n");
+ lprintf(LOG_ERR, "Unable to pack byte %ld from file '%s'.", r,
+ ifile);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ }
+ wbuf[1] = (uint8_t) (r / SSHKEY_BLOCK_SIZE);
+ }
+
+ wbuf[2] = (uint8_t) i_size;
+
req.msg.data_len = i_size + 3;
rsp = intf->sendrecv(intf, &req);
if (rsp == NULL) {
- lprintf(LOG_ERR, "Unable to set ssh key for UID %d", uid);
- break;
- }
+ printf("failed\n");
+ lprintf(LOG_ERR, "Unable to set ssh key for UID %d.", uid);
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ } /* if (rsp == NULL) */
+ if (rsp->ccode != 0) {
+ printf("failed\n");
+ lprintf(LOG_ERR, "Unable to set ssh key for UID %d, %s.", uid,
+ val2str(rsp->ccode, completion_code_vals));
+ if (fp != NULL)
+ fclose(fp);
+
+ return (-1);
+ } /* if (rsp->ccode != 0) */
}
printf("done\n");
fclose(fp);
- return 0;
+ return (0);
}
+/*
+ * This structure is used in both the request to and response from the BMC.
+ */
+#define SUNOEM_CLI_LEGACY_VERSION 1
+#define SUNOEM_CLI_SEQNUM_VERSION 2
+#define SUNOEM_CLI_VERSION SUNOEM_CLI_SEQNUM_VERSION
+#define SUNOEM_CLI_HEADER 8 /* command + spare + handle */
+#define SUNOEM_CLI_BUF_SIZE (80 - SUNOEM_CLI_HEADER) /* Total 80 bytes */
+#define SUNOEM_CLI_MSG_SIZE(msg) (SUNOEM_CLI_HEADER + strlen((msg).buf) + 1)
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ /*
+ * Set version to SUNOEM_CLI_VERSION.
+ */
+ uint8_t version;
+ /*
+ * The command in a request, or in a response indicates an error if
+ * non-zero.
+ */
+ uint8_t command_response;
+ uint8_t seqnum;
+ uint8_t spare;
+ /*
+ * Opaque 4-byte handle, supplied in the response to an OPEN request,
+ * and used in all subsequent POLL and CLOSE requests.
+ */
+ uint8_t handle[4];
+ /*
+ * The client data in a request, or the server data in a response. Must
+ * by null terminated, i.e., it must be at least one byte, but can be
+ * smaller if there's less data.
+ */
+ char buf[SUNOEM_CLI_BUF_SIZE];
+}__attribute__((packed)) sunoem_cli_msg_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
-int
-ipmi_sunoem_main(struct ipmi_intf * intf, int argc, char ** argv)
+/*
+ * Command codes for the command_request field in each request.
+ */
+#define SUNOEM_CLI_CMD_OPEN 0 /* Open a new connection */
+#define SUNOEM_CLI_CMD_FORCE 1 /* Close any existing connection, then open */
+#define SUNOEM_CLI_CMD_CLOSE 2 /* Close the current connection */
+#define SUNOEM_CLI_CMD_POLL 3 /* Poll for new data to/from the server */
+#define SUNOEM_CLI_CMD_EOF 4 /* Poll, client is out of data */
+
+#define SUNOEM_CLI_MAX_RETRY 3 /* Maximum number of retries */
+
+#define SUNOEM_CLI_INVALID_VER_ERR "Invalid version"
+#define SUNOEM_CLI_BUSY_ERR "Busy"
+
+typedef enum
{
- int rc = (-1);
+ C_CTL_B = 0x02, /* same as left arrow */
+ C_CTL_C = 0x03,
+ C_CTL_D = 0x04,
+ C_CTL_F = 0x06, /* same as right arrow */
+ C_CTL_N = 0x0E, /* same as down arrow */
+ C_CTL_P = 0x10, /* same as up arrow */
+ C_DEL = 0x7f
+} canon_char_t;
- if (argc == 0 || strncmp(argv[0], "help", 4) == 0) {
- ipmi_sunoem_usage();
- return 0;
+static int
+sunoem_cli_unbufmode_start(FILE *f, struct termios *orig_ts)
+{
+ struct termios ts;
+ int rc;
+
+ if ((rc = tcgetattr(fileno(f), &ts))) {
+ return (rc);
+ }
+ *orig_ts = ts;
+ ts.c_lflag &= ~(ICANON | ECHO | ISIG);
+ ts.c_cc[VMIN] = 1;
+ if ((rc = tcsetattr(fileno(f), TCSAFLUSH, &ts))) {
+ return (rc);
}
- if (strncmp(argv[0], "fan", 3) == 0) {
- if (argc == 3 && strncmp(argv[1], "speed", 5) == 0) {
- uint8_t pct = 0;
- if (str2uchar(argv[2], &pct) != 0 || pct > 100) {
- lprintf(LOG_ERR, "Fan speed is limited to range <0..100>.");
+ return (0);
+}
+
+static int
+sunoem_cli_unbufmode_stop(FILE *f, struct termios *ts)
+{
+ int rc;
+
+ if ((rc = tcsetattr(fileno(f), TCSAFLUSH, ts))) {
+ return (rc);
+ }
+
+ return (0);
+}
+
+static int
+ipmi_sunoem_cli(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_cli_msg_t cli_req;
+ sunoem_cli_msg_t *cli_rsp;
+ int arg_num = 0;
+ int arg_pos = 0;
+ time_t wait_time = 0;
+ int retries;
+ static uint8_t SunOemCliActingVersion = SUNOEM_CLI_VERSION;
+
+ unsigned short first_char = 0; /*first char on the line*/
+ struct termios orig_ts;
+ int error = 0;
+
+ time_t now = 0;
+ int delay = 0;
+
+ /* Prepare to open an SP shell session */
+ memset(&cli_req, 0, sizeof(cli_req));
+ cli_req.version = SunOemCliActingVersion;
+ cli_req.command_response = SUNOEM_CLI_CMD_OPEN;
+ if (argc > 0 && strcmp(argv[0], "force") == 0) {
+ cli_req.command_response = SUNOEM_CLI_CMD_FORCE;
+ argc--;
+ argv++;
+ }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_CLI;
+ req.msg.data = (uint8_t *) &cli_req;
+ req.msg.data_len = SUNOEM_CLI_HEADER + 1;
+ retries = 0;
+ while (1) {
+ cli_req.version = SunOemCliActingVersion;
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM cli command failed");
+ return (-1);
+ }
+ cli_rsp = (sunoem_cli_msg_t *) rsp->data;
+ if ((cli_rsp->command_response != 0) || (rsp->ccode != 0)) {
+ if (strncmp(cli_rsp->buf, SUNOEM_CLI_INVALID_VER_ERR,
+ sizeof(SUNOEM_CLI_INVALID_VER_ERR) - 1) == 0
+ || strncmp(&(cli_rsp->buf[1]), SUNOEM_CLI_INVALID_VER_ERR,
+ sizeof(SUNOEM_CLI_INVALID_VER_ERR) - 1) == 0) {
+ if (SunOemCliActingVersion == SUNOEM_CLI_VERSION) {
+ /* Server doesn't support version SUNOEM_CLI_VERSION
+ Fall back to legacy version, and try again*/
+ SunOemCliActingVersion = SUNOEM_CLI_LEGACY_VERSION;
+ continue;
+ }
+ /* Server doesn't support legacy version either */
+ lprintf(LOG_ERR, "Failed to connect: %s", cli_rsp->buf);
+ return (-1);
+ } else if (strncmp(cli_rsp->buf, SUNOEM_CLI_BUSY_ERR,
+ sizeof(SUNOEM_CLI_BUSY_ERR) - 1) == 0) {
+ if (retries++ < SUNOEM_CLI_MAX_RETRY) {
+ lprintf(LOG_INFO, "Failed to connect: %s, retrying",
+ cli_rsp->buf);
+ sleep(2);
+ continue;
+ }
+ lprintf(LOG_ERR, "Failed to connect: %s", cli_rsp->buf);
+ return (-1);
+ } else {
+ lprintf(LOG_ERR, "Failed to connect: %s", cli_rsp->buf);
return (-1);
}
- rc = ipmi_sunoem_fan_speed(intf, pct);
}
- else {
- ipmi_sunoem_usage();
+ break;
+ }
+ if (SunOemCliActingVersion == SUNOEM_CLI_SEQNUM_VERSION) {
+ /*
+ * Bit 1 of seqnum is used as an alternating sequence number
+ * to allow a server that supports it to detect when a retry is being sent from the host IPMI driver.
+ * Typically when this occurs, the server's last response message would have been dropped.
+ * Once the server detects this condition, it will know that it should retry sending the response.
+ */
+ cli_req.seqnum ^= 0x1;
+ }
+ printf("Connected. Use ^D to exit.\n");
+ fflush(NULL);
+
+ /*
+ * Remember the handle provided in the response, and issue a
+ * series of "poll" commands to send and get data
+ */
+ memcpy(cli_req.handle, cli_rsp->handle, 4);
+ cli_req.command_response = SUNOEM_CLI_CMD_POLL;
+ /*
+ * If no arguments make input unbuffered and so interactive
+ */
+ if (argc == 0) {
+ if (sunoem_cli_unbufmode_start(stdin, &orig_ts)) {
+ lprintf(LOG_ERR, "Failed to set interactive mode: %s",
+ strerror(errno));
+ return (-1);
+ }
+ }
+ while (rsp->ccode == 0 && cli_rsp->command_response == 0) {
+ int rc = 0;
+ int count = 0;
+ cli_req.buf[0] = '\0';
+ if (argc == 0) {
+ /*
+ * Accept input from stdin. Use select so we don't hang if
+ * there's no input to read. Select timeout is 500 msec.
+ */
+ struct timeval tv = { 0, 500000 }; /* 500 msec */
+ fd_set rfds;
+ FD_ZERO(&rfds);
+ FD_SET(0, &rfds);
+ rc = select(1, &rfds, NULL, NULL, &tv);
+ if (rc < 0) {
+ /* Select returned an error so close and exit */
+ printf("Broken pipe\n");
+ cli_req.command_response = SUNOEM_CLI_CMD_CLOSE;
+ } else if (rc > 0) {
+ /* Read data from stdin */
+ count = read(0, cli_req.buf, 1 /* sizeof (cli_req.buf) - 1 */);
+ /*
+ * If select said there was data but there was nothing to
+ * read. This implies user hit ^D.
+ * Also handle ^D input when pressed as first char at a new line.
+ */
+ if (count <= 0 || (first_char && cli_req.buf[0] == C_CTL_D)) {
+ cli_req.command_response = SUNOEM_CLI_CMD_EOF;
+ count = 0;
+ }
+ first_char = cli_req.buf[0] == '\n' || cli_req.buf[0] == '\r';
+ }
+ } else {
+ /*
+ * Get data from command line arguments
+ */
+ now = time(NULL);
+ if (now < wait_time) {
+ /* Do nothing; we're waiting */
+ } else if (arg_num >= argc) {
+ /* Last arg was sent. Set EOF */
+ cli_req.command_response = SUNOEM_CLI_CMD_EOF;
+ } else if (strncmp(argv[arg_num], "@wait=", 6) == 0) {
+ /* This is a wait command */
+ char *s = &argv[arg_num][6];
+ delay = 0;
+ if (*s != '\0') {
+ if (str2int(s, &delay)) {
+ delay = 0;
+ }
+ if (delay < 0) {
+ delay = 0;
+ }
+ }
+ wait_time = now + delay;
+ arg_num++;
+ } else {
+ /*
+ * Take data from args. It may be that the argument is larger
+ * than the request buffer can hold. So pull off BUF_SIZE
+ * number of characters at a time. When we've consumed the
+ * entire arg, append a newline and advance to the next arg.
+ */
+ int i;
+ char *s = argv[arg_num];
+ for (i = arg_pos;
+ s[i] != '\0' && count < (SUNOEM_CLI_BUF_SIZE - 2);
+ i++, count++) {
+ cli_req.buf[count] = s[i];
+ }
+ if (s[i] == '\0') {
+ /* Reached end of the arg string, so append a newline */
+ cli_req.buf[count++] = '\n';
+ /* Reset pos to 0 and advance to the next arg next time */
+ arg_pos = 0;
+ arg_num++;
+ } else {
+ /*
+ * Otherwise, there's still more characters in the arg
+ * to send, so remember where we left off
+ */
+ arg_pos = i;
+ }
+ }
+ }
+ /*
+ * Now send the clients's data (if any) and get data back from the
+ * server. Loop while the server is giving us data until we suck
+ * it dry.
+ */
+ do {
+ cli_req.buf[count++] = '\0'; /* Terminate the string */
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = 0x19;
+ req.msg.data = (uint8_t *) &cli_req;
+ req.msg.data_len = SUNOEM_CLI_HEADER + count;
+ for (retries = 0; retries <= SUNOEM_CLI_MAX_RETRY; retries++) {
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Communication error.");
+ error = 1;
+ goto cleanup;
+ }
+ if (rsp->ccode == IPMI_CC_TIMEOUT) { /* Retry if timed out. */
+ if (retries == SUNOEM_CLI_MAX_RETRY) { /* If it's the last retry. */
+ lprintf(LOG_ERR, "Excessive timeout.");
+ error = 1;
+ goto cleanup;
+ }
+ continue;
+ }
+ break;
+ } /* for (retries = 0; retries <= SUNOEM_CLI_MAX_RETRY; retries++) */
+
+ if (SunOemCliActingVersion == SUNOEM_CLI_SEQNUM_VERSION) {
+ cli_req.seqnum ^= 0x1; /* Toggle sequence number after request is sent */
+ }
+
+ cli_rsp = (sunoem_cli_msg_t *) rsp->data;
+ /* Make sure response string is null terminated */
+ cli_rsp->buf[sizeof(cli_rsp->buf) - 1] = '\0';
+ printf("%s", cli_rsp->buf);
+ fflush(NULL); /* Flush partial lines to stdout */
+ count = 0; /* Don't re-send the client's data */
+ if (cli_req.command_response == SUNOEM_CLI_CMD_EOF
+ && cli_rsp->command_response != 0 && rsp->ccode == 0) {
+ cli_rsp->command_response = 1;
+ }
+ } while (cli_rsp->command_response == 0 && cli_rsp->buf[0] != '\0');
+ }
+
+cleanup:
+ /* Restore original input mode if cli was running interactively */
+ if (argc == 0) {
+ if (sunoem_cli_unbufmode_stop(stdin, &orig_ts)) {
+ lprintf(LOG_ERR, "Failed to restore interactive mode: %s",
+ strerror(errno));
+ return (-1);
+ }
+ }
+
+ return ((error == 0 && cli_rsp->command_response == SUNOEM_SUCCESS) ? 0 : -1);
+}
+#define ECHO_DATA_SIZE 64
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ uint16_t seq_num;
+ unsigned char data[ECHO_DATA_SIZE];
+}__attribute__((packed)) sunoem_echo_msg_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/*
+ * Send and receive X packets to the BMC. Each packet has a
+ * payload size of (sunoem_echo_msg_t) bytes. Each packet is tagged with a
+ * sequence number
+ */
+static int
+ipmi_sunoem_echo(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_echo_msg_t echo_req;
+ sunoem_echo_msg_t *echo_rsp;
+ struct timeval start_time;
+ struct timeval end_time;
+
+ int rc = 0;
+ int received = 0;
+ int transmitted = 0;
+ int quiet_mode = 0;
+
+ uint16_t num, i, j;
+ uint32_t total_time, resp_time, min_time, max_time;
+
+ if (argc < 1) {
+ return (1);
+ }
+
+ if (argc == 2) {
+ if (*(argv[1]) == 'q') {
+ quiet_mode = 1;
+ } else {
+ lprintf(LOG_ERR, "Unknown option '%s' given.", argv[1]);
return (-1);
}
+ } else if (argc > 2) {
+ lprintf(LOG_ERR,
+ "Too many parameters given. See help for more information.");
+ return (-1);
+ }
+ /* The number of packets to send/receive */
+ if (str2ushort(argv[0], &num) != 0) {
+ lprintf(LOG_ERR,
+ "Given number of packets is either invalid or out of range.");
+ return (-1);
+ }
+
+ /* Fill in data packet */
+ for (i = 0; i < ECHO_DATA_SIZE; i++) {
+ if (i > UINT8_MAX)
+ break;
+
+ echo_req.data[i] = (uint8_t) i;
+ }
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_ECHO;
+ req.msg.data = (uint8_t *) &echo_req;
+ req.msg.data_len = sizeof(sunoem_echo_msg_t);
+ echo_req.seq_num = i;
+ min_time = INT_MAX;
+ max_time = 0;
+ total_time = 0;
+ for (i = 0; i < num; i++) {
+ echo_req.seq_num = i;
+ transmitted++;
+ gettimeofday(&start_time, NULL);
+ rsp = intf->sendrecv(intf, &req);
+ gettimeofday(&end_time, NULL);
+ resp_time = ((end_time.tv_sec - start_time.tv_sec) * 1000)
+ + ((end_time.tv_usec - start_time.tv_usec) / 1000);
+ if ((rsp == NULL) || (rsp->ccode != 0)) {
+ lprintf(LOG_ERR, "Sun OEM echo command failed. Seq # %d",
+ echo_req.seq_num);
+ rc = (-2);
+ break;
+ }
+ echo_rsp = (sunoem_echo_msg_t *) rsp->data;
+
+ /* Test if sequence # is valid */
+ if (echo_rsp->seq_num != echo_req.seq_num) {
+ printf("Invalid Seq # Expecting %d Received %d\n", echo_req.seq_num,
+ echo_rsp->seq_num);
+ rc = (-2);
+ break;
+ }
+
+ /* Test if response length is valid */
+ if (rsp->session.msglen == req.msg.data_len) {
+ printf("Invalid payload size for seq # %d. "
+ "Expecting %d Received %d\n", echo_rsp->seq_num,
+ req.msg.data_len, rsp->session.msglen);
+ rc = (-2);
+ break;
+ }
+
+ /* Test if the data is valid */
+ for (j = 0; j < ECHO_DATA_SIZE; j++) {
+ if (echo_rsp->data[j] != j) {
+ printf("Corrupt data packet. Seq # %d Offset %d\n",
+ echo_rsp->seq_num, j);
+ break;
+ }
+ } /* for (j = 0; j < ECHO_DATA_SIZE; j++) */
+
+ /* If the for loop terminated early - data is corrupt */
+ if (j != ECHO_DATA_SIZE) {
+ rc = (-2);
+ break;
+ }
+
+ /* cumalative time */
+ total_time += resp_time;
+
+ /* min time */
+ if (resp_time < min_time) {
+ min_time = resp_time;
+ }
+
+ /* max time */
+ if (resp_time > max_time) {
+ max_time = resp_time;
+ }
+
+ received++;
+ if (!quiet_mode) {
+ printf("Receive %u Bytes - Seq. # %d time=%d ms\n",
+ sizeof(sunoem_echo_msg_t), echo_rsp->seq_num, resp_time);
+ }
+ } /* for (i = 0; i < num; i++) */
+ printf("%d packets transmitted, %d packets received\n", transmitted,
+ received);
+ if (received) {
+ printf("round-trip min/avg/max = %d/%d/%d ms\n", min_time,
+ total_time / received, max_time);
}
- else if ((strncmp(argv[0], "led", 3) == 0)
- || (strncmp(argv[0], "sbled", 5) == 0)) {
+
+ return (rc);
+} /* ipmi_sunoem_echo(...) */
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char oem_record_ver_num;
+ unsigned char major;
+ unsigned char minor;
+ unsigned char update;
+ unsigned char micro;
+ char nano[10];
+ char revision[10];
+ char version[40];
+ /*
+ * When adding new fields (using the spare bytes),
+ * add it immediately after the spare field to
+ * ensure backward compatability.
+ *
+ * e.g. char version[40];
+ * unsigned char spare[11];
+ * int new_item;
+ * } sunoem_version_response_t;
+ */
+ unsigned char spare[15];
+}__attribute__((packed)) sunoem_version_response_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+typedef struct
+{
+ unsigned char major;
+ unsigned char minor;
+ unsigned char update;
+ unsigned char micro;
+} supported_version_t;
+
+static int
+ipmi_sunoem_getversion(struct ipmi_intf * intf,
+ sunoem_version_response_t **version_rsp)
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_VERSION;
+ req.msg.data = NULL;
+ req.msg.data_len = 0;
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM Get SP Version Failed.");
+ return (-1);
+ }
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM Get SP Version Failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ *version_rsp = (sunoem_version_response_t *) rsp->data;
+
+ return (0);
+}
+
+static void
+ipmi_sunoem_print_required_version(const supported_version_t* supp_ver)
+{
+ lprintf(LOG_ERR, "Command is not supported by this version of ILOM,"
+ " required at least: %d.%d.%d.%d", supp_ver->major, supp_ver->minor,
+ supp_ver->update, supp_ver->micro);
+}
+
+/*
+ * Function checks current version result against required version.
+ * Returns:
+ * - negative value if current ILOM version is smaller than required or
+ * in case of error
+ * - positive value if current ILOM version is greater than required
+ * - 0 if there is an exact ILOM version match
+ */
+static int
+ipmi_sunoem_checkversion(struct ipmi_intf * intf, supported_version_t* supp_ver)
+{
+ sunoem_version_response_t *version_rsp;
+ int i = 1;
+
+ if (ipmi_sunoem_getversion(intf, &version_rsp)) {
+ lprintf(LOG_ERR, "Unable to get ILOM version");
+ return (-1);
+ }
+
+ if (version_rsp->major < supp_ver->major) return (-i);
+ if (version_rsp->major > supp_ver->major) return (i);
+ /*version_rsp->major == supp_ver->major*/
+ ++i;
+
+ if (version_rsp->minor < supp_ver->minor) return (-i);
+ if (version_rsp->minor > supp_ver->minor) return (i);
+ /*version_rsp->minor == supp_ver->minor*/
+ ++i;
+
+ if (version_rsp->update < supp_ver->update) return (-i);
+ if (version_rsp->update > supp_ver->update) return (i);
+ /*version_rsp->update == supp_ver->update*/
+ ++i;
+
+ if (version_rsp->micro < supp_ver->micro) return (-i);
+ if (version_rsp->micro > supp_ver->micro) return (i);
+ /*version_rsp->micro == supp_ver->micro*/
+
+ return (0);
+}
+
+/*
+ * Extract the SP version data including
+ * - major #
+ * - minor #
+ * - update #
+ * - micro #
+ * - nano #
+ * - Revision/Build #
+ */
+static int
+ipmi_sunoem_version(struct ipmi_intf * intf)
+{
+ sunoem_version_response_t *version_rsp;
+ int rc = ipmi_sunoem_getversion(intf, &version_rsp);
+
+ if (!rc) {
+ printf("Version: %s\n", version_rsp->version);
+ }
+
+ return (rc);
+}
+
+/*
+ * IPMI Max string length is 16 bytes
+ * define in usr/src/common/include/ami/IPMI_SDRRecord.h
+ */
+#define MAX_ID_STR_LEN 16
+#define MAX_SUNOEM_NAC_SIZE 64
+#define LUAPI_MAX_OBJ_PATH_LEN 256
+#define LUAPI_MAX_OBJ_VAL_LEN 1024
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char seq_num;
+ char nac_name[MAX_SUNOEM_NAC_SIZE];
+}__attribute__((packed)) sunoem_nacname_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/*
+ * Retrieve the full NAC name of the IPMI target.
+ *
+ * The returned nac name may be larger than the payload size.
+ * In which case, it make take several request/payload to retrieve
+ * the entire full path name
+ *
+ * The initial seq_num is set to 0. If the return seq_num is incremented,
+ * only the 1st 72 bytes of the nac name is returned and the caller
+ * needs to get the next set of string data.
+ * If the returned seq_num is identical to the input seq_num, all data
+ * has been returned.
+ */
+static int
+ipmi_sunoem_nacname(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_nacname_t nacname_req;
+ sunoem_nacname_t *nacname_rsp;
+ char full_nac_name[LUAPI_MAX_OBJ_PATH_LEN];
+
+ if (argc < 1) {
+ return (1);
+ }
+
+ if (strlen(argv[0]) > MAX_ID_STR_LEN) {
+ lprintf(LOG_ERR,
+ "Sun OEM nacname command failed: Max size on IPMI name");
+ return (-1);
+ }
+
+ nacname_req.seq_num = 0;
+ strcpy(nacname_req.nac_name, argv[0]);
+
+ full_nac_name[0] = '\0';
+ while (1) {
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_NACNAME;
+ req.msg.data = (uint8_t *) &nacname_req;
+ req.msg.data_len = sizeof(sunoem_nacname_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM nacname command failed.");
+ return (-1);
+ }
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM nacname command failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ nacname_rsp = (sunoem_nacname_t *) rsp->data;
+ strncat(full_nac_name, nacname_rsp->nac_name, MAX_SUNOEM_NAC_SIZE);
+
+ /*
+ * break out of the loop if there is no more data
+ * In most cases, if not all, the NAC name fits into a
+ * single payload
+ */
+ if (nacname_req.seq_num == nacname_rsp->seq_num) {
+ break;
+ }
+
+ /* Get the next seq of string bytes */
+ nacname_req.seq_num = nacname_rsp->seq_num;
+
+ /* Check if we exceeded the size of the full nac name */
+ if ((nacname_req.seq_num * MAX_SUNOEM_NAC_SIZE) > LUAPI_MAX_OBJ_PATH_LEN) {
+ lprintf(LOG_ERR,
+ "Sun OEM nacname command failed: invalid path length");
+ return (-1);
+ }
+ }
+
+ printf("NAC Name: %s\n", full_nac_name);
+ return (0);
+}
+
+/* Constants used by ipmi_sunoem_getval */
+#define MAX_SUNOEM_VAL_PAYLOAD 79
+#define MAX_SUNOEM_VAL_COMPACT_PAYLOAD 56
+
+/*
+ * SUNOEM GET/SET LUAPI Commands
+ *
+ * SUNOEM_REQ_VAL - Request LUAPI Property Value
+ * SUNOEM_GET_VAL - Return the value from SUNOEM_REQ_VAL
+ * SUNOEM_SET_VAL - Set the LUAPI Property value
+ * SUNOEM_GET_STATUS - Return the Status from SUNOEM_SET_VAL
+ */
+#define SUNOEM_REQ_VAL 1
+#define SUNOEM_GET_VAL 2
+#define SUNOEM_SET_VAL 3
+#define SUNOEM_GET_STATUS 4
+
+/* Status Code */
+#define SUNOEM_REQ_RECV 1
+#define SUNOEM_REQ_FAILED 2
+#define SUNOEM_DATA_READY 3
+#define SUNOEM_DATA_NOT_READY 4
+#define SUNOEM_DATA_NOT_FOUND 5
+#define GETVAL_MAX_RETRIES 5
+
+/* Parameter type Codes */
+#define SUNOEM_LUAPI_TARGET 0
+#define SUNOEM_LUAPI_VALUE 1
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char cmd_code;
+ unsigned char luapi_value[MAX_SUNOEM_VAL_PAYLOAD];
+}__attribute__((packed)) sunoem_getval_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/*
+ * REQUEST PAYLOAD
+ *
+ * cmd_code - SUNOEM GET/SET LUAPI Cmds - see above
+ * param_type: 0: luapi_data contains the luapi property name
+ * 1: luapi_data contains the luapi value
+ * luapi_data: Either luapi property name or value
+ * tid: Transaction ID. If 0. This is the initial request for the
+ * param_type. If tid > 0, this luapi_data string is a concatenation
+ * of the previous request. Handle cases where the LUAPI target name
+ * or value is > MAX_SUNOEM_VAL_COMPACT_PAYLOAD
+ * eof: If non zero, this is the last payload for the request
+ */
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char cmd_code;
+ unsigned char param_type;
+ unsigned char tid;
+ unsigned char eof;
+ char luapi_data[MAX_SUNOEM_VAL_COMPACT_PAYLOAD];
+}__attribute__((packed)) sunoem_setval_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/*
+ * RESPONSE PAYLOAD
+ *
+ * status_code - see above for code definitions
+ * tid - transaction ID - assigned ny the ILOM stack
+ */
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char status_code;
+ unsigned char tid;
+}__attribute__((packed)) sunoem_setval_resp_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+/*
+ * Return the ILOM target property value
+ */
+static int
+ipmi_sunoem_getval(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_getval_t getval_req;
+ sunoem_getval_t *getval_rsp;
+ int i;
+
+ const char* sp_path = "/SP";
+ supported_version_t supp_ver = { 3, 2, 0, 0 };
+
+ if (argc < 1) {
+ return (1);
+ }
+
+ if (strlen(argv[0]) > MAX_SUNOEM_VAL_PAYLOAD) {
+ lprintf(LOG_ERR,
+ "Sun OEM get value command failed: Max size on IPMI name");
+ return (-1);
+ }
+
+ if ((ipmi_sunoem_checkversion(intf, &supp_ver) < 0)
+ && (!strncmp(argv[0], sp_path, strlen(sp_path)))) {
+ argv[0][1] = 'X'; /*replace SP by X to gain access to hidden properties*/
+ memmove(&argv[0][2], &argv[0][3], strlen(argv[0]) - 2);
+ }
+
+ /*
+ * Setup the initial request to fetch the data.
+ * Upon function return, the next cmd (SUNOEM_GET_VAL)
+ * can be requested.
+ */
+ memset(&getval_req, 0, sizeof(getval_req));
+ strncpy((char*) getval_req.luapi_value, argv[0], MAX_SUNOEM_VAL_PAYLOAD);
+ getval_req.cmd_code = SUNOEM_REQ_VAL;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_GETVAL;
+ req.msg.data = (uint8_t *) &getval_req;
+ req.msg.data_len = sizeof(sunoem_getval_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM getval1 command failed.");
+ return (-1);
+ }
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM getval1 command failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ /*
+ * Fetch the data value - if it is not ready,
+ * retry the request up to GETVAL_MAX_RETRIES
+ */
+ for (i = 0; i < GETVAL_MAX_RETRIES; i++) {
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_GETVAL;
+ getval_req.cmd_code = SUNOEM_GET_VAL;
+ req.msg.data = (uint8_t *) &getval_req;
+ req.msg.data_len = sizeof(sunoem_getval_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM getval2 command failed.");
+ return (-1);
+ }
+
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM getval2 command failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ getval_rsp = (sunoem_getval_t *) rsp->data;
+
+ if (getval_rsp->cmd_code == SUNOEM_DATA_READY) {
+ printf("Target Value: %s\n", getval_rsp->luapi_value);
+ return (0);
+ } else if (getval_rsp->cmd_code == SUNOEM_DATA_NOT_FOUND) {
+ lprintf(LOG_ERR, "Target: %s not found", getval_req.luapi_value);
+ return (-1);
+ }
+
+ sleep(1);
+ }
+
+ lprintf(LOG_ERR, "Unable to retrieve target value.");
+ return (-1);
+}
+
+static int
+send_luapi_prop_name(struct ipmi_intf * intf, int len, char *prop_name,
+ unsigned char *tid_num)
+{
+ int i = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_setval_t setval_req;
+ sunoem_setval_resp_t *setval_rsp;
+
+ *tid_num = 0;
+ while (i < len) {
+ /*
+ * Setup the request,
+ * Upon function return, the next cmd (SUNOEM_SET_VAL)
+ * can be requested.
+ */
+ memset(&req, 0, sizeof(req));
+ memset(&setval_req, 0, sizeof(sunoem_setval_t));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_SETVAL;
+ setval_req.cmd_code = SUNOEM_SET_VAL;
+ setval_req.param_type = SUNOEM_LUAPI_TARGET;
+ setval_req.tid = *tid_num;
+ setval_req.eof = 0;
+ /*
+ * If the property name is > payload, only copy
+ * the payload size and increment the string offset (i)
+ * for the next payload
+ */
+ if (strlen(&(prop_name[i])) > MAX_SUNOEM_VAL_COMPACT_PAYLOAD) {
+ strncpy(setval_req.luapi_data, &(prop_name[i]),
+ MAX_SUNOEM_VAL_COMPACT_PAYLOAD);
+ } else {
+ strncpy(setval_req.luapi_data, &(prop_name[i]),
+ strlen(&(prop_name[i])));
+ }
+ req.msg.data = (uint8_t *) &setval_req;
+ req.msg.data_len = sizeof(sunoem_setval_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM setval prop name: response is NULL");
+ return (-1);
+ }
+
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM setval prop name: request failed: %d",
+ rsp->ccode);
+ return (-1);
+ }
+
+ setval_rsp = (sunoem_setval_resp_t *) rsp->data;
+
+ /*
+ * If the return code is other than data received, the
+ * request failed
+ */
+ if (setval_rsp->status_code != SUNOEM_REQ_RECV) {
+ lprintf(LOG_ERR,
+ "Sun OEM setval prop name: invalid status code: %d",
+ setval_rsp->status_code);
+ return (-1);
+ }
+ /* Use the tid returned by ILOM */
+ *tid_num = setval_rsp->tid;
+ /* Increment the string offset */
+ i += MAX_SUNOEM_VAL_COMPACT_PAYLOAD;
+ }
+
+ return (0);
+}
+
+static int
+send_luapi_prop_value(struct ipmi_intf * intf, int len, char *prop_value,
+ unsigned char tid_num)
+{
+ int i = 0;
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_setval_t setval_req;
+ sunoem_setval_resp_t *setval_rsp;
+
+ while (i < len) {
+ /*
+ * Setup the request,
+ * Upon function return, the next cmd (SUNOEM_GET_VAL)
+ * can be requested.
+ */
+ memset(&req, 0, sizeof(req));
+ memset(&setval_req, 0, sizeof(sunoem_setval_t));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_SETVAL;
+ setval_req.cmd_code = SUNOEM_SET_VAL;
+ setval_req.param_type = SUNOEM_LUAPI_VALUE;
+ setval_req.tid = tid_num;
+ /*
+ * If the property name is > payload, only copy the
+ * the payload size and increment the string offset
+ * for the next payload
+ */
+ if (strlen(&(prop_value[i])) > MAX_SUNOEM_VAL_COMPACT_PAYLOAD) {
+ strncpy(setval_req.luapi_data, &(prop_value[i]),
+ MAX_SUNOEM_VAL_COMPACT_PAYLOAD);
+ } else {
+ /* Captured the entire string, mark this as the last payload */
+ strncpy(setval_req.luapi_data, &(prop_value[i]),
+ strlen(&(prop_value[i])));
+ setval_req.eof = 1;
+ }
+ req.msg.data = (uint8_t *) &setval_req;
+ req.msg.data_len = sizeof(sunoem_setval_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM setval prop value: response is NULL");
+ return (-1);
+ }
+
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM setval prop value: request failed: %d",
+ rsp->ccode);
+ return (-1);
+ }
+
+ setval_rsp = (sunoem_setval_resp_t *) rsp->data;
+
+ /*
+ * If the return code is other than data received, the
+ * request failed
+ */
+ if (setval_rsp->status_code != SUNOEM_REQ_RECV) {
+ lprintf(LOG_ERR,
+ "Sun OEM setval prop value: invalid status code: %d",
+ setval_rsp->status_code);
+ return (-1);
+ }
+
+ /* Increment the string offset */
+ i += MAX_SUNOEM_VAL_COMPACT_PAYLOAD;
+ }
+ return (0);
+}
+
+static int
+ipmi_sunoem_setval(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ sunoem_setval_t setval_req;
+ sunoem_setval_resp_t *setval_rsp;
+ int prop_len;
+ int value_len;
+ int i;
+ unsigned char tid_num;
+ int retries;
+
+ prop_len = strlen(argv[0]);
+ value_len = strlen(argv[1]);
+ if (prop_len > LUAPI_MAX_OBJ_PATH_LEN) {
+ lprintf(LOG_ERR,
+ "Sun OEM set value command failed: Max size on property name");
+ return (-1);
+ }
+ if (value_len > LUAPI_MAX_OBJ_VAL_LEN) {
+ lprintf(LOG_ERR,
+ "Sun OEM set value command failed: Max size on property value");
+ return (-1);
+ }
+
+ /* Test if there is a timeout specified */
+ if (argc == 3) {
+ if ((str2int(argv[2], &retries) != 0) || retries < 0) {
+ lprintf(LOG_ERR,
+ "Invalid input given or out of range for time-out parameter.");
+ return (-1);
+ }
+ } else {
+ retries = GETVAL_MAX_RETRIES;
+ }
+
+ /* Send the property name 1st */
+ if (send_luapi_prop_name(intf, prop_len, argv[0], &tid_num) != 0) {
+ /* return if there is an error */
+ return (-1);
+ }
+
+ if (send_luapi_prop_value(intf, value_len, argv[1], tid_num) != 0) {
+ /* return if there is an error */
+ return (-1);
+ }
+
+ /*
+ * Get The status of the command.
+ * if it is not ready, retry the request up to
+ * GETVAL_MAX_RETRIES
+ */
+ for (i = 0; i < retries; i++) {
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_SETVAL;
+ setval_req.cmd_code = SUNOEM_GET_STATUS;
+ setval_req.tid = tid_num;
+ req.msg.data = (uint8_t *) &setval_req;
+ req.msg.data_len = sizeof(sunoem_setval_t);
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM setval command failed.");
+ return (-1);
+ }
+
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM setval command failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ setval_rsp = (sunoem_setval_resp_t *) rsp->data;
+
+ if (setval_rsp->status_code == SUNOEM_DATA_READY) {
+ printf("Sun OEM setval command successful.\n");
+ return (0);
+ } else if (setval_rsp->status_code != SUNOEM_DATA_NOT_READY) {
+ lprintf(LOG_ERR, "Sun OEM setval command failed.");
+ return (-1);
+ }
+
+ sleep(1);
+ }
+ /* If we reached here, retries exceeded */
+ lprintf(LOG_ERR, "Sun OEM setval command failed: Command Timed Out");
+
+ return (-1);
+}
+
+#define MAX_FILE_DATA_SIZE 1024
+#define MAX_FILEID_LEN 16
+#define CORE_TUNNEL_SUBCMD_GET_FILE 11
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char cmd_code;
+ unsigned char file_id[MAX_FILEID_LEN];
+ unsigned int block_num;
+}__attribute__((packed)) getfile_req_t;
+
+typedef struct
+{
+ unsigned int block_num;
+ unsigned int data_size;
+ unsigned char eof;
+ unsigned char data[MAX_FILE_DATA_SIZE];
+}__attribute__((packed)) getfile_rsp_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+static int
+ipmi_sunoem_getfile(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rs *rsp;
+ struct ipmi_rq req;
+ getfile_req_t getfile_req;
+ getfile_rsp_t *getfile_rsp;
+ int block_num = 0;
+ int nbo_blk_num; /* Network Byte Order Block Num */
+ FILE *fp;
+ unsigned data_size;
+ supported_version_t supp_ver = IPMI_SUNOEM_GETFILE_VERSION;
+
+ if (argc < 1) {
+ return (-1);
+ }
+
+ /*check if command is supported by this version of ilom*/
+ if (ipmi_sunoem_checkversion(intf, &supp_ver) < 0) {
+ ipmi_sunoem_print_required_version(&supp_ver);
+ return (-1);
+ }
+
+ /*
+ * File ID is < MAX_FILEID_LEN
+ * Save 1 byte for null Terminated string
+ */
+ if (strlen(argv[0]) >= MAX_FILE_DATA_SIZE) {
+ lprintf(LOG_ERR, "File ID >= %d characters", MAX_FILEID_LEN);
+ return (-1);
+ }
+
+ memset(&getfile_req, 0, sizeof(getfile_req));
+ strncpy((char*) getfile_req.file_id, argv[0], MAX_FILEID_LEN - 1);
+
+ /* Create the destination file */
+ fp = ipmi_open_file_write(argv[1]);
+ if (fp == NULL) {
+ lprintf(LOG_ERR, "Unable to open file: %s", argv[1]);
+ return (-1);
+ }
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_CORE_TUNNEL;
+ req.msg.data = (uint8_t *) &getfile_req;
+ req.msg.data_len = sizeof(getfile_req_t);
+ getfile_req.cmd_code = CORE_TUNNEL_SUBCMD_GET_FILE;
+
+ do {
+
+ nbo_blk_num = htonl(block_num);
+ /* Block Num must be in network byte order */
+ memcpy(&(getfile_req.block_num), &nbo_blk_num,
+ sizeof(getfile_req.block_num));
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM getfile command failed.");
+ fclose(fp);
+ return (-1);
+ }
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM getfile command failed: %d", rsp->ccode);
+ fclose(fp);
+ return (-1);
+ }
+
+ getfile_rsp = (getfile_rsp_t *) rsp->data;
+
+ memcpy(&data_size, &(getfile_rsp->data_size),
+ sizeof(getfile_rsp->data_size));
+ data_size = ntohl(data_size);
+
+ if (data_size > MAX_FILE_DATA_SIZE) {
+ lprintf(LOG_ERR, "Sun OEM getfile invalid data size: %d",
+ data_size);
+ fclose(fp);
+ return (-1);
+ }
+
+ /* Check if Block Num matches */
+ if (memcmp(&(getfile_req.block_num), &(getfile_rsp->block_num),
+ sizeof(getfile_req.block_num)) != 0) {
+ lprintf(LOG_ERR, "Sun OEM getfile Incorrect Block Num Returned");
+ lprintf(LOG_ERR, "Expecting: %x Received: %x",
+ getfile_req.block_num, getfile_rsp->block_num);
+ fclose(fp);
+ return (-1);
+ }
+
+ if (fwrite(getfile_rsp->data, 1, data_size, fp) != data_size) {
+ lprintf(LOG_ERR, "Sun OEM getfile write failed: %d", rsp->ccode);
+ fclose(fp);
+ return (-1);
+ }
+
+ block_num++;
+ } while (getfile_rsp->eof == 0);
+
+ fclose(fp);
+
+ return (0);
+}
+
+/*
+ * Query BMC for capability/behavior.
+ */
+
+#define CORE_TUNNEL_SUBCMD_GET_BEHAVIOR 15
+#define SUNOEM_BEHAVIORID_SIZE 32
+
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(push, 1)
+#endif
+typedef struct
+{
+ unsigned char cmd_code;
+ unsigned char behavior_id[SUNOEM_BEHAVIORID_SIZE];
+}__attribute__((packed)) getbehavior_req_t;
+
+typedef struct
+{
+ unsigned char enabled;
+}__attribute__((packed)) getbehavior_rsp_t;
+#ifdef HAVE_PRAGMA_PACK
+#pragma pack(pop)
+#endif
+
+static int
+ipmi_sunoem_getbehavior(struct ipmi_intf * intf, int argc, char *argv[])
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ getbehavior_req_t getbehavior_req;
+ getbehavior_rsp_t *getbehavior_rsp;
+ supported_version_t supp_ver = IPMI_SUNOEM_GETBEHAVIOR_VERSION;
+
+ if (argc < 1) {
+ return (-1);
+ }
+
+ /*check if command is supported by this version of ilom*/
+ if (ipmi_sunoem_checkversion(intf, &supp_ver) < 0) {
+ ipmi_sunoem_print_required_version(&supp_ver);
+ return (-1);
+ }
+
+ /*
+ * Behavior ID is < SUNOEM_BEHAVIORID_SIZE.
+ * Save 1 byte for null terminated string
+ */
+ if (strlen(argv[0]) >= SUNOEM_BEHAVIORID_SIZE) {
+ lprintf(LOG_ERR, "Behavior ID >= %d characters",
+ SUNOEM_BEHAVIORID_SIZE);
+ return (-1);
+ }
+
+ memset(&getbehavior_req, 0, sizeof(getbehavior_req));
+ strncpy(getbehavior_req.behavior_id, argv[0], SUNOEM_BEHAVIORID_SIZE - 1);
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_SUNOEM;
+ req.msg.cmd = IPMI_SUNOEM_CORE_TUNNEL;
+ req.msg.data = (uint8_t *) &getbehavior_req;
+ req.msg.data_len = sizeof(getbehavior_req_t);
+ getbehavior_req.cmd_code = CORE_TUNNEL_SUBCMD_GET_BEHAVIOR;
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (rsp == NULL) {
+ lprintf(LOG_ERR, "Sun OEM getbehavior command failed.");
+ return (-1);
+ }
+
+ if (rsp->ccode != 0) {
+ lprintf(LOG_ERR, "Sun OEM getbehavior command failed: %d", rsp->ccode);
+ return (-1);
+ }
+
+ getbehavior_rsp = (getbehavior_rsp_t *) rsp->data;
+ printf("ILOM behavior %s %s enabled\n", getbehavior_req.behavior_id,
+ getbehavior_rsp->enabled ? "is" : "is not");
+
+ return (0);
+}
+
+int
+ipmi_sunoem_main(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ int rc = 0;
+
+ if (argc == 0 || strcmp(argv[0], "help") == 0) {
+ ipmi_sunoem_usage();
+ return (0);
+ } /* if (argc == 0 || strcmp(argv[0], "help") == 0) */
+
+ if (strcmp(argv[0], "cli") == 0) {
+ rc = ipmi_sunoem_cli(intf, argc - 1, &argv[1]);
+ } else if ((strcmp(argv[0], "led") == 0) || (strcmp(argv[0], "sbled") == 0)) {
if (argc < 2) {
ipmi_sunoem_usage();
return (-1);
}
- if (strncmp(argv[0], "sbled", 5) == 0) {
- is_sbcmd = 1;
- }
- if (strncmp(argv[1], "get", 3) == 0) {
+
+ if (strcmp(argv[1], "get") == 0) {
if (argc < 3) {
char * arg[] = { "all" };
rc = ipmi_sunoem_led_get(intf, 1, arg);
+ } else {
+ rc = ipmi_sunoem_led_get(intf, argc - 2, &(argv[2]));
}
- else {
- rc = ipmi_sunoem_led_get(intf, argc-2, &(argv[2]));
- }
- }
- else if (strncmp(argv[1], "set", 3) == 0) {
+ } else if (strcmp(argv[1], "set") == 0) {
if (argc < 4) {
ipmi_sunoem_usage();
return (-1);
}
- rc = ipmi_sunoem_led_set(intf, argc-2, &(argv[2]));
- }
- else {
+ rc = ipmi_sunoem_led_set(intf, argc - 2, &(argv[2]));
+ } else {
ipmi_sunoem_usage();
return (-1);
}
- }
- else if (strncmp(argv[0], "sshkey", 6) == 0) {
+ } else if (strcmp(argv[0], "sshkey") == 0) {
uint8_t uid = 0;
if (argc < 3) {
ipmi_sunoem_usage();
return (-1);
}
-
- if (str2uchar(argv[2], &uid) != 0 || uid < 1 || uid > 63) {
- lprintf(LOG_ERR, "User ID is limited to range <1..63>.");
+ rc = str2uchar(argv[2], &uid);
+ if (rc == 0) {
+ /* conversion should be OK. */
+ } else if (rc == 2) {
+ lprintf(LOG_NOTICE, "Invalid interval given.");
+ return (-1);
+ } else {
+ /* defaults to rc = 3 */
+ lprintf(LOG_NOTICE, "Given interval is too big.");
return (-1);
}
- if (strncmp(argv[1], "del", 3) == 0) {
+ if (strcmp(argv[1], "del") == 0) {
+ /* number of arguments, three, is already checked at this point */
rc = ipmi_sunoem_sshkey_del(intf, uid);
- }
- else if (argc == 4 && strncmp(argv[1], "set", 3) == 0) {
+ } else if (strcmp(argv[1], "set") == 0) {
+ if (argc < 4) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
rc = ipmi_sunoem_sshkey_set(intf, uid, argv[3]);
+ } else {
+ ipmi_sunoem_usage();
+ return (-1);
}
- else {
+ } else if (strcmp(argv[0], "ping") == 0) {
+ if (argc < 2) {
ipmi_sunoem_usage();
return (-1);
}
- }
- else {
- ipmi_sunoem_usage();
+ rc = ipmi_sunoem_echo(intf, argc - 1, &(argv[1]));
+ } else if (strcmp(argv[0], "version") == 0) {
+ rc = ipmi_sunoem_version(intf);
+ } else if (strcmp(argv[0], "nacname") == 0) {
+ if (argc < 2) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
+ rc = ipmi_sunoem_nacname(intf, argc - 1, &(argv[1]));
+ } else if (strcmp(argv[0], "getval") == 0) {
+ if (argc < 2) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
+ rc = ipmi_sunoem_getval(intf, argc - 1, &(argv[1]));
+ } else if (strcmp(argv[0], "setval") == 0) {
+ if (argc < 3) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
+ rc = ipmi_sunoem_setval(intf, argc - 1, &(argv[1]));
+ } else if (strcmp(argv[0], "getfile") == 0) {
+ if (argc < 3) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
+ rc = ipmi_sunoem_getfile(intf, argc - 1, &(argv[1]));
+ } else if (strcmp(argv[0], "getbehavior") == 0) {
+ if (argc < 2) {
+ ipmi_sunoem_usage();
+ return (-1);
+ }
+ rc = ipmi_sunoem_getbehavior(intf, argc - 1, &(argv[1]));
+ } else {
+ lprintf(LOG_ERR, "Invalid sunoem command: %s", argv[0]);
return (-1);
- }
+ } /* if (strcmp(argv[0], "cli") == 0) */
- return rc;
+ return (rc);
}