unknown
1970-01-01 00:00:00 UTC
/* rsAddr */
- msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
+ if (bridgedRequest)
+ msg[len++] = intf->target_addr;
+ else
+ msg[len++] = IPMI_BMC_SLAVE_ADDR;
/* net Fn */
msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
@@ -1440,7 +1428,7 @@ void getIpmiPayloadWireRep(
cs = len;
/* rqAddr */
- if (!bridgedRequest)
+ if (bridgedRequest < 2)
msg[len++] = IPMI_REMOTE_SWID;
else /* Bridged message */
msg[len++] = intf->my_addr;
@@ -1551,7 +1539,7 @@ void getSolPayloadWireRep(
* ipmi_lanplus_build_v2x_msg
*
* Encapsulates the payload data to create the IPMI v2.0 / RMCP+ packet.
- *
+ *
*
* IPMI v2.0 LAN Request Message Format
* +----------------------+
@@ -1690,7 +1678,7 @@ ipmi_lanplus_build_v2x_msg(
curr_seq);
break;
- case IPMI_PAYLOAD_TYPE_SOL:
+ case IPMI_PAYLOAD_TYPE_SOL:
getSolPayloadWireRep(intf,
msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
payload);
@@ -1903,13 +1891,15 @@ ipmi_lanplus_build_v2x_ipmi_cmd(
if(entry)
{
- /* Add entry for bridge cmd */
- backup_cmd = req->msg.cmd;
- req->msg.cmd = 0x34;
- entry = ipmi_req_add_entry(intf, req, curr_seq);
- req->msg.cmd = backup_cmd;
+ entry->req.msg.target_cmd = entry->req.msg.cmd;
+ entry->req.msg.cmd = 0x34;
+
+ if(intf->transit_addr && intf->transit_addr != intf->my_addr)
+ entry->bridging_level = 2;
+ else
+ entry->bridging_level = 1;
}
- }
+ }
if (entry == NULL)
return NULL;
@@ -2091,7 +2081,7 @@ sol_response_acks_packet(
{
return (is_sol_packet(rsp) &&
payload &&
- (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) &&
+ (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) &&
(rsp->payload.sol_packet.acked_packet_number ==
payload->payload.sol_packet.packet_sequence_number));
}
@@ -2125,7 +2115,7 @@ ipmi_lanplus_send_payload(
* so it will only be valid after the open completes.
*/
saved_timeout = session->timeout;
- while (try < session->retry) {
+ while (try < intf->ssn_params.retry) {
//ltime = time(NULL);
if (xmit) {
@@ -2186,8 +2176,7 @@ ipmi_lanplus_send_payload(
else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST)
{
lprintf(LOG_DEBUG, ">> SENDING AN OPEN SESSION REQUEST\n");
- assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION
- || session->v2_data.session_state == LANPLUS_STATE_OPEN_SESSION_SENT);
+ assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION);
ipmi_lanplus_build_v2x_msg(intf, /* in */
payload, /* in */
@@ -2263,16 +2252,16 @@ ipmi_lanplus_send_payload(
case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:
session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT;
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
break;
case IPMI_PAYLOAD_TYPE_RAKP_1:
session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT;
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
break;
case IPMI_PAYLOAD_TYPE_RAKP_3:
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT;
break;
}
@@ -2419,7 +2408,7 @@ static void set_sol_packet_sequence_number(
*
* Returns a pointer to the SOL ACK we received, or
* 0 on failure
- *
+ *
*/
struct ipmi_rs *
ipmi_lanplus_send_sol(
@@ -2656,7 +2645,7 @@ ipmi_lanplus_send_ipmi_cmd(
* param auth_cap [out] will be initialized to hold the Get Channel
* Authentication Capabilities return data on success. Its
* contents will be undefined on error.
- *
+ *
* returns 0 on success
* non-zero if we were unable to contact the BMC, or we cannot
* get a successful response
@@ -2677,7 +2666,7 @@ ipmi_get_auth_capabilities_cmd(
bridgePossible = 0;
msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well
- msg_data[1] = intf->session->privlvl;
+ msg_data[1] = intf->ssn_params.privlvl;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; // 0x06
@@ -2809,8 +2798,8 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE);
msg[0] = 0; /* Message tag */
- if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN)
- msg[1] = session->privlvl;
+ if (ipmi_oem_active(intf, "intelplus") || intf->ssn_params.privlvl != IPMI_SESSION_PRIV_ADMIN)
+ msg[1] = intf->ssn_params.privlvl;
else
msg[1] = 0; /* Give us highest privlg level based on supported algorithms */
msg[2] = 0; /* reserved */
@@ -2824,13 +2813,13 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[7] = (session->v2_data.console_id >> 24) & 0xff;
- if (lanplus_get_requested_ciphers(session->cipher_suite_id,
+ if (lanplus_get_requested_ciphers(intf->ssn_params.cipher_suite_id,
&(session->v2_data.requested_auth_alg),
&(session->v2_data.requested_integrity_alg),
&(session->v2_data.requested_crypt_alg)))
{
lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n",
- session->cipher_suite_id);
+ intf->ssn_params.cipher_suite_id);
free(msg);
msg = NULL;
return 1;
@@ -2845,9 +2834,9 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[10] = 0; /* reserved */
msg[11] = 8; /* payload length */
msg[12] = session->v2_data.requested_auth_alg;
- msg[13] = 0; /* reserved */
+ msg[13] = 0; /* reserved */
msg[14] = 0; /* reserved */
- msg[15] = 0; /* reserved */
+ msg[15] = 0; /* reserved */
/*
* Integrity payload
@@ -2857,7 +2846,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[18] = 0; /* reserved */
msg[19] = 8; /* payload length */
msg[20] = session->v2_data.requested_integrity_alg;
- msg[21] = 0; /* reserved */
+ msg[21] = 0; /* reserved */
msg[22] = 0; /* reserved */
msg[23] = 0; /* reserved */
@@ -2869,7 +2858,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[26] = 0; /* reserved */
msg[27] = 8; /* payload length */
msg[28] = session->v2_data.requested_crypt_alg;
- msg[29] = 0; /* reserved */
+ msg[29] = 0; /* reserved */
msg[30] = 0; /* reserved */
msg[31] = 0; /* reserved */
@@ -3034,14 +3023,14 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
/*
* Requested maximum privilege level.
*/
- msg[24] = session->privlvl | session->v2_data.lookupbit;
+ msg[24] = intf->ssn_params.privlvl | intf->ssn_params.lookupbit;
session->v2_data.requested_role = msg[24];
msg[25] = 0; /* reserved */
msg[26] = 0; /* reserved */
/* Username specification */
- msg[27] = strlen((const char *)session->username);
+ msg[27] = strlen((const char *)intf->ssn_params.username);
if (msg[27] > IPMI_MAX_USER_NAME_LENGTH)
{
lprintf(LOG_ERR, "ERROR: user name too long. "
@@ -3051,7 +3040,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
msg = NULL;
return 1;
}
- memcpy(msg + 28, session->username, msg[27]);
+ memcpy(msg + 28, intf->ssn_params.username, msg[27]);
v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1;
v2_payload.payload_length =
@@ -3097,7 +3086,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
* whether the BMC has authenticated.
*/
if (! lanplus_rakp2_hmac_matches(session,
- rsp->payload.rakp2_message.key_exchange_auth_code,
+ rsp->payload.rakp2_message.key_exchange_auth_code,
intf))
{
/* Error */
@@ -3142,7 +3131,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
struct ipmi_rs * rsp;
assert(session->v2_data.session_state == LANPLUS_STATE_RAKP_2_RECEIVED);
-
+
/*
* Build a RAKP 3 message
*/
@@ -3156,7 +3145,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
msg[0] = 0; /* Message tag */
msg[1] = session->v2_data.rakp2_return_code;
-
+
msg[2] = 0; /* reserved */
msg[3] = 0; /* reserved */
@@ -3179,7 +3168,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS)
{
uint32_t auth_length;
-
+
if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf))
{
/* Error */
@@ -3220,7 +3209,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
return 1;
}
}
-
+
rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
@@ -3248,7 +3237,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
*/
if (verbose)
lanplus_dump_rakp4_message(rsp, session->v2_data.auth_alg);
-
+
if (rsp->payload.open_session_response.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS)
{
@@ -3288,34 +3277,34 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
void
ipmi_lanplus_close(struct ipmi_intf * intf)
{
- if (!intf->abort)
- ipmi_close_session_cmd(intf);
-
- if (intf->fd >= 0)
- close(intf->fd);
-
- ipmi_req_clear_entries();
-
if (intf->session) {
+ if (!intf->abort) {
+ ipmi_close_session_cmd(intf);
+ }
free(intf->session);
intf->session = NULL;
}
- intf->session = NULL;
+ if (intf->fd >= 0) {
+ close(intf->fd);
+ intf->fd = -1;
+ }
+
+ /* clear entries after sending Close Session command */
+ ipmi_req_clear_entries();
+
intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL;
}
-
-
static int
ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t backupBridgePossible;
- uint8_t privlvl = intf->session->privlvl;
+ uint8_t privlvl = intf->ssn_params.privlvl;
if (privlvl <= IPMI_SESSION_PRIV_USER)
return 0; /* no need to set higher */
@@ -3365,54 +3354,58 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
int rc;
int retry;
struct get_channel_auth_cap_rsp auth_cap;
- struct ipmi_session *session;
+ struct sockaddr_in addr;
+ struct ipmi_session_params *params;
+ struct ipmi_session * session;
- if (!intf || !intf->session)
+ if (!intf || !intf->session) {
return -1;
- session = intf->session;
+ }
+ params = &intf->ssn_params;
- if (!session->port)
- session->port = IPMI_LANPLUS_PORT;
- if (!session->privlvl)
- session->privlvl = IPMI_SESSION_PRIV_ADMIN;
- if (!session->timeout)
- session->timeout = IPMI_LAN_TIMEOUT;
- if (!session->retry)
- session->retry = IPMI_LAN_RETRY;
+ if (!params->port)
+ params->port = IPMI_LANPLUS_PORT;
+ if (!params->privlvl)
+ params->privlvl = IPMI_SESSION_PRIV_ADMIN;
+ if (!params->timeout)
+ params->timeout = IPMI_LAN_TIMEOUT;
+ if (!params->retry)
+ params->retry = IPMI_LAN_RETRY;
- if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) {
- lprintf(LOG_ERR, "No hostname specified!");
+ if (ipmi_intf_socket_connect(intf) == -1) {
+ lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
+ /* alllocate new session */
+ session = (struct ipmi_session *)malloc(sizeof (struct ipmi_session));
+
+ if (!session) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ goto fail;
+ }
+
+ /* clear session data */
+ memset(session, 0, sizeof (struct ipmi_session));
+
+ /* need no to close session */
intf->abort = 1;
+ /* save interface session pointer */
+ intf->session = session;
/* Setup our lanplus session state */
+ session->timeout = params->timeout;
+ memcpy(&session->authcode, ¶ms->authcode_set,
+ sizeof (session->authcode));
+ memcpy(&session->addr, &addr, sizeof (session->addr));
+ session->v2_data.session_state = LANPLUS_STATE_PRESESSION;
session->v2_data.auth_alg = IPMI_AUTH_RAKP_NONE;
session->v2_data.crypt_alg = IPMI_CRYPT_NONE;
session->v2_data.console_id = 0x00;
session->v2_data.bmc_id = 0x00;
session->sol_data.sequence_number = 1;
- //session->sol_data.last_received_sequence_number = 0;
- //session->sol_data.last_received_byte_count = 0;
- memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
-
- /* Kg is set in ipmi_intf */
- //memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
-
- if (ipmi_intf_socket_connect (intf) == -1) {
- lprintf(LOG_ERR, "Could not open socket!");
- return -1;
- }
-
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Connect to %s failed",
- session->hostname);
- intf->close(intf);
- return -1;
- }
intf->opened = 1;
@@ -3440,6 +3433,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
*/
for (retry = 0; retry < IPMI_LAN_RETRY; retry++) {
session->v2_data.session_state = LANPLUS_STATE_PRESESSION;
+
/*
* Open session
*/
@@ -3451,6 +3445,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
lprintf(LOG_DEBUG, "Retry lanplus open session, %d", retry);
continue;
}
+
/*
* RAKP 1
*/
@@ -3489,10 +3484,24 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
hpm2_detect_max_payload_size(intf);
return intf->fd;
-
+ close_fail:
+ ipmi_close_session_cmd(intf);
fail:
lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session");
+ if (intf->session) {
+ free(intf->session);
+ intf->session = NULL;
+ }
+
+ ipmi_req_clear_entries();
+
+ if (intf->fd >= 0) {
+ close(intf->fd);
+ intf->fd = -1;
+ }
+
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
return -1;
}
@@ -3527,7 +3536,7 @@ void test_crypt1(void)
assert(0);
}
printbuf(encrypt_buffer, bytes_encrypted, "encrypted payload");
-
+
if (lanplus_decrypt_payload(IPMI_CRYPT_AES_CBC_128,
key,
@@ -3538,12 +3547,12 @@ void test_crypt1(void)
{
lprintf(LOG_ERR, "Decrypt test failed\n");
assert(0);
- }
+ }
printbuf(decrypt_buffer, bytes_decrypted, "decrypted payload");
-
+
lprintf(LOG_DEBUG, "\nDone testing the encrypt/decyrpt methods!\n");
exit(0);
-}
+}
@@ -3633,13 +3642,6 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)
if (lanplus_seed_prng(16))
return -1;
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;
intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE;
@@ -3649,7 +3651,7 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)
static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)
{
- if (intf->session->cipher_suite_id == 3) {
+ if (intf->ssn_params.cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
@@ -3667,7 +3669,7 @@ static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t siz
static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)
{
- if (intf->session->cipher_suite_id == 3) {
+ if (intf->ssn_params.cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c
index 54fd5cb..1cdd050 100644
--- a/src/plugins/lanplus/lanplus_crypt.c
+++ b/src/plugins/lanplus/lanplus_crypt.c
@@ -95,7 +95,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
16 + /* GUIDc */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username); /* optional */
+ strlen((const char *)intf->ssn_params.username); /* optional */
buffer = malloc(bufferLength);
if (buffer == NULL) {
@@ -163,11 +163,11 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
}
/* ULENGTHm */
- buffer[57] = strlen((const char *)session->username);
+ buffer[57] = strlen((const char *)intf->ssn_params.username);
/* UserName [optional] */
for (i = 0; i < buffer[57]; ++i)
- buffer[58 + i] = session->username[i];
+ buffer[58 + i] = intf->ssn_params.username[i];
if (verbose > 2)
{
@@ -375,7 +375,7 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
4 + /* SIDm */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username);
+ strlen((const char *)intf->ssn_params.username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
@@ -406,16 +406,16 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
/* ROLEm */
if (ipmi_oem_active(intf, "intelplus") || ipmi_oem_active(intf, "i82571spt"))
- input_buffer[20] = session->privlvl;
+ input_buffer[20] = intf->ssn_params.privlvl;
else
input_buffer[20] = session->v2_data.requested_role;
/* ULENGTHm */
- input_buffer[21] = strlen((const char *)session->username);
+ input_buffer[21] = strlen((const char *)intf->ssn_params.username);
/* USERNAME */
for (i = 0; i < input_buffer[21]; ++i)
- input_buffer[22 + i] = session->username[i];
+ input_buffer[22 + i] = intf->ssn_params.username[i];
if (verbose > 2)
{
@@ -491,7 +491,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
16 + /* Rc */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username);
+ strlen((const char *)intf->ssn_params.username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
@@ -536,13 +536,13 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
}
/* ULENGTHm */
- input_buffer[33] = strlen((const char *)session->username);
+ input_buffer[33] = strlen((const char *)intf->ssn_params.username);
/* USERNAME */
for (i = 0; i < input_buffer[33]; ++i)
- input_buffer[34 + i] = session->username[i];
+ input_buffer[34 + i] = intf->ssn_params.username[i];
- if (session->v2_data.kg[0])
+ if (intf->ssn_params.kg[0])
{
/* We will be hashing with Kg */
/*
@@ -550,7 +550,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
* using Kg. It specifies that Kg should not be truncated.
* Kg is set in ipmi_intf.
*/
- input_key = session->v2_data.kg;
+ input_key = intf->ssn_params.kg;
}
else
{
diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c
index 5f4b926..eb8305e 100644
--- a/src/plugins/serial/serial_basic.c
+++ b/src/plugins/serial/serial_basic.c
@@ -178,21 +178,15 @@ static const struct {
static int is_system;
/*
- * Setup serial interface
- */
+ Setup serial interface
+*/
static int
serial_bm_setup(struct ipmi_intf * intf)
{
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = SERIAL_BM_MAX_RQ_SIZE;
intf->max_response_data_size = SERIAL_BM_MAX_RS_SIZE;
+
return 0;
}
@@ -285,10 +279,10 @@ serial_bm_open(struct ipmi_intf * intf)
/* set the new options for the port with flushing */
tcsetattr(intf->fd, TCSAFLUSH, &ti);
- if (intf->session->timeout == 0)
- intf->session->timeout = SERIAL_BM_TIMEOUT;
- if (intf->session->retry == 0)
- intf->session->retry = SERIAL_BM_RETRY_COUNT;
+ if (intf->ssn_params.timeout == 0)
+ intf->ssn_params.timeout = SERIAL_BM_TIMEOUT;
+ if (intf->ssn_params.retry == 0)
+ intf->ssn_params.retry = SERIAL_BM_RETRY_COUNT;
intf->opened = 1;
@@ -306,11 +300,6 @@ serial_bm_close(struct ipmi_intf * intf)
intf->fd = -1;
}
- if (intf->session) {
- free(intf->session);
- intf->session = NULL;
- }
-
intf->opened = 0;
}
@@ -464,7 +453,7 @@ serial_bm_wait_for_data(struct ipmi_intf * intf)
pfd.events = POLLIN;
pfd.revents = 0;
- n = poll(&pfd, 1, intf->session->timeout*1000);
+ n = poll(&pfd, 1, intf->ssn_params.timeout*1000);
if (n < 0) {
lperror(LOG_ERR, "Poll for serial data failed");
return -1;
@@ -892,7 +881,7 @@ serial_bm_get_message(struct ipmi_intf * intf,
tm = clock() - start;
tm /= CLOCKS_PER_SEC;
- } while (tm < intf->session->timeout);
+ } while (tm < intf->ssn_params.timeout);
return 0;
}
@@ -915,7 +904,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
read_ctx.max_buffer_size = SERIAL_BM_MAX_BUFFER_SIZE;
/* Send the message and receive the answer */
- for (retry = 0; retry < intf->session->retry; retry++) {
+ for (retry = 0; retry < intf->ssn_params.retry; retry++) {
/* build output message */
bridging_level = serial_bm_build_msg(intf, req, msg,
sizeof (msg), req_ctx, &msg_len);
@@ -961,7 +950,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
/* check if response for inner request is not encapsulated */
} else if (rv == 1) {
/* wait for response for inner request */
- rv = serial_bm_wait_response(intf, &req_ctx[0],
+ rv = serial_bm_wait_response(intf, &req_ctx[1],
&read_ctx, msg, sizeof (msg));
/* check for IO error */
diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c
index 41d3753..0c377f1 100644
--- a/src/plugins/serial/serial_terminal.c
+++ b/src/plugins/serial/serial_terminal.c
@@ -225,10 +225,10 @@ ipmi_serial_term_open(struct ipmi_intf * intf)
/* set the new options for the port with flushing */
tcsetattr(intf->fd, TCSAFLUSH, &ti);
- if (intf->session->timeout == 0)
- intf->session->timeout = IPMI_SERIAL_TIMEOUT;
- if (intf->session->retry == 0)
- intf->session->retry = IPMI_SERIAL_RETRY;
+ if (intf->ssn_params.timeout == 0)
+ intf->ssn_params.timeout = IPMI_SERIAL_TIMEOUT;
+ if (intf->ssn_params.retry == 0)
+ intf->ssn_params.retry = IPMI_SERIAL_RETRY;
intf->opened = 1;
@@ -243,11 +243,6 @@ ipmi_serial_term_close(struct ipmi_intf * intf)
intf->fd = -1;
}
- if (intf->session) {
- free(intf->session);
- intf->session = NULL;
- }
-
intf->opened = 0;
}
@@ -264,7 +259,7 @@ serial_wait_for_data(struct ipmi_intf * intf)
pfd.events = POLLIN;
pfd.revents = 0;
- n = poll(&pfd, 1, intf->session->timeout*1000);
+ n = poll(&pfd, 1, intf->ssn_params.timeout*1000);
if (n < 0) {
lperror(LOG_ERR, "Poll for serial data failed");
return -1;
@@ -362,7 +357,7 @@ recv_response(struct ipmi_intf * intf, unsigned char *data, int len)
{
char hex_rs[IPMI_SERIAL_MAX_RESPONSE * 3];
int i, j, resp_len = 0;
- unsigned long rv;
+ long rv;
char *p, *pp;
char ch, str_hex[3];
@@ -774,7 +769,7 @@ serial_term_get_message(struct ipmi_intf * intf,
tm = clock() - start;
tm /= CLOCKS_PER_SEC;
- } while (tm < intf->session->timeout);
+ } while (tm < intf->ssn_params.timeout);
return 0;
}
@@ -792,7 +787,7 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
}
/* Send the message and receive the answer */
- for (retry = 0; retry < intf->session->retry; retry++) {
+ for (retry = 0; retry < intf->ssn_params.retry; retry++) {
/* build output message */
bridging_level = serial_term_build_msg(intf, req, msg,
sizeof (msg), req_ctx, &msg_len);
@@ -887,14 +882,6 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
static int
ipmi_serial_term_setup(struct ipmi_intf * intf)
{
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
-
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;
intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;
--------------070703040500050105010503
Content-Type: text/x-patch;
name="vita-support.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="vita-support.diff"
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index 437a427..d97df3c 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -168,6 +168,7 @@ struct ipmi_intf {
int abort;
int noanswer;
int picmg_avail;
+ int vita_avail;
IPMI_OEM manufacturer_id;
struct ipmi_session * session;
diff --git a/include/ipmitool/ipmi_vita.h b/include/ipmitool/ipmi_vita.h
new file mode 100644
index 0000000..71d471a
--- /dev/null
+++ b/include/ipmitool/ipmi_vita.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Pigeon Point Systems. All right reserved
+ */
+
+#ifndef _IPMI_VITA_H_
+#define _IPMI_VITA_H_
+
+/* VITA 46.11 commands */
+#define VITA_GET_VSO_CAPABILITIES_CMD 0x00
+#define VITA_FRU_CONTROL_CMD 0x04
+#define VITA_GET_FRU_LED_PROPERTIES_CMD 0x05
+#define VITA_GET_LED_COLOR_CAPABILITIES_CMD 0x06
+#define VITA_SET_FRU_LED_STATE_CMD 0x07
+#define VITA_GET_FRU_LED_STATE_CMD 0x08
+#define VITA_SET_FRU_STATE_POLICY_BITS_CMD 0x0A
+#define VITA_GET_FRU_STATE_POLICY_BITS_CMD 0x0B
+#define VITA_SET_FRU_ACTIVATION_CMD 0x0C
+#define VITA_GET_FRU_ADDRESS_INFO_CMD 0x40
+
+/* VITA 46.11 site types */
+#define VITA_FRONT_VPX_MODULE 0x00
+#define VITA_POWER_ENTRY 0x01
+#define VITA_CHASSIS_FRU 0x02
+#define VITA_DEDICATED_CHMC 0x03
+#define VITA_FAN_TRAY 0x04
+#define VITA_FAN_TRAY_FILTER 0x05
+#define VITA_ALARM_PANEL 0x06
+#define VITA_XMC 0x07
+#define VITA_VPX_RTM 0x09
+#define VITA_FRONT_VME_MODULE 0x0A
+#define VITA_FRONT_VXS_MODULE 0x0B
+#define VITA_POWER_SUPPLY 0x0C
+#define VITA_FRONT_VITA62_MODULE 0x0D
+#define VITA_71_MODULE 0x0E
+#define VITA_FMC 0x0F
+
+
+#define GROUP_EXT_VITA 0x03
+
+extern uint8_t
+vita_discover(struct ipmi_intf *intf);
+
+extern uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf);
+
+extern int
+ipmi_vita_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /* _IPMI_VITA_H_ */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d878b11..2a316db 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,7 +39,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
- ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c \
+ ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index 14ca183..4b723c4 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -338,6 +338,18 @@ ipmi_parse_hex(const char *str)
return out;
}
+static uint8_t
+ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
+{
+ if (intf->picmg_avail) {
+ return ipmi_picmg_ipmb_address(intf);
+ } else if (intf->vita_avail) {
+ return ipmi_vita_ipmb_address(intf);
+ } else {
+ return 0;
+ }
+}
+
/* ipmi_parse_options - helper function to handle parsing command line options
*
* @argc: count of options
@@ -900,15 +912,24 @@ ipmi_main(int argc, char ** argv,
goto out_free;
}
}
+
/*
- * Attempt picmg discovery of the actual interface address unless
+ * Attempt picmg/vita discovery of the actual interface address unless
* the users specified an address.
* Address specification always overrides discovery
*/
- if (picmg_discover(ipmi_main_intf) && !arg_addr) {
- lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
- addr = ipmi_picmg_ipmb_address(ipmi_main_intf);
- lprintf(LOG_INFO, "Discovered IPMB-0 address 0x%x", addr);
+ if (picmg_discover(ipmi_main_intf)) {
+ ipmi_main_intf->picmg_avail = 1;
+ } else if (vita_discover(ipmi_main_intf)) {
+ ipmi_main_intf->vita_avail = 1;
+ }
+
+ if (arg_addr) {
+ addr = arg_addr;
+ } else {
+ lprintf(LOG_DEBUG, "Acquire IPMB address");
+ addr = ipmi_acquire_ipmb_address(ipmi_main_intf);
+ lprintf(LOG_INFO, "Discovered IPMB address 0x%x", addr);
}
/*
@@ -916,41 +937,44 @@ ipmi_main(int argc, char ** argv,
* used for open, Set the discovered IPMB address as my address if the
* interface supports it.
*/
- if (addr != 0 && addr != ipmi_main_intf->my_addr &&
- ipmi_main_intf->set_my_addr) {
- /*
- * Only set the interface address on interfaces which support
- * it
- */
- (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ if (addr != 0 && addr != ipmi_main_intf->my_addr) {
+ if (ipmi_main_intf->set_my_addr) {
+ /*
+ * Some interfaces need special handling
+ * when changing local address
+ */
+ (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ }
+
+ /* set local address */
+ ipmi_main_intf->my_addr = addr;
}
+ ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
+
/* If bridging addresses are specified, handle them */
- if (target_addr > 0) {
- ipmi_main_intf->target_addr = target_addr;
- ipmi_main_intf->target_lun = target_lun ;
- ipmi_main_intf->target_channel = target_channel ;
- }
- if (transit_addr > 0) {
+ if (transit_addr > 0 || target_addr > 0) {
/* sanity check, transit makes no sense without a target */
if ((transit_addr != 0 || transit_channel != 0) &&
- ipmi_main_intf->target_addr == 0) {
+ target_addr == 0) {
lprintf(LOG_ERR,
"Transit address/channel %#x/%#x ignored. "
"Target address must be specified!",
transit_addr, transit_channel);
goto out_free;
}
+ ipmi_main_intf->target_addr = target_addr;
+ ipmi_main_intf->target_channel = target_channel ;
ipmi_main_intf->transit_addr = transit_addr;
ipmi_main_intf->transit_channel = transit_channel;
- }
- if (ipmi_main_intf->target_addr > 0) {
+
+
/* must be admin level to do this over lan */
ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
/* Get the ipmb address of the targeted entity */
ipmi_main_intf->target_ipmb_addr =
- ipmi_picmg_ipmb_address(ipmi_main_intf);
+ ipmi_acquire_ipmb_address(ipmi_main_intf);
lprintf(LOG_DEBUG, "Specified addressing Target %#x:%#x Transit %#x:%#x",
ipmi_main_intf->target_addr,
ipmi_main_intf->target_channel,
@@ -962,6 +986,9 @@ ipmi_main(int argc, char ** argv,
}
}
+ /* set target LUN (for RAW command) */
+ ipmi_main_intf->target_lun = target_lun ;
+
lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
"transit %#x:%#x target %#x:%#x "
"ipmb_target %#x\n",
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index d1c82b2..1f3849d 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -2335,37 +2335,36 @@ picmg_discover(struct ipmi_intf *intf) {
struct ipmi_rq req;
struct ipmi_rs *rsp;
char msg_data;
+ uint8_t picmg_avail = 0;
- if (intf->picmg_avail == 0) {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
- intf->my_addr, intf->transit_addr, intf->target_addr);
- rsp = intf->sendrecv(intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
- || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
- intf->picmg_avail = 1;
- lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- } else {
- if (rsp == NULL) {
- lprintf(LOG_INFO,"No Response from Get PICMG Properties");
- } else {
- lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
- }
- }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if ( (rsp->data[0] == 0) &&
+ ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
+ || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
+ picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
+ }
+ } else if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get PICMG Properties");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
}
- if (intf->picmg_avail == 0) {
+
+ if (picmg_avail == 0) {
lprintf(LOG_INFO, "No PICMG Extenstion discovered");
}
- return intf->picmg_avail;
+
+ return picmg_avail;
}
diff --git a/lib/ipmi_vita.c b/lib/ipmi_vita.c
new file mode 100644
index 0000000..261759e
--- /dev/null
+++ b/lib/ipmi_vita.c
@@ -0,0 +1,777 @@
+/*
+ Copyright (c) Pigeon Point Systems. All right 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 Pigeon Point Systems, or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_picmg.h>
+#include <ipmitool/ipmi_vita.h>
+#include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
+#include <ipmitool/ipmi_strings.h>
+#include <ipmitool/log.h>
+
+/* check if VITA 46.11 is supported */
+uint8_t
+vita_discover(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+ int vita_avail = 0;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = GROUP_EXT_VITA;
+
+ lprintf(LOG_INFO, "Running Get VSO Capabilities my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if (rsp->data[0] == GROUP_EXT_VITA && (rsp->data[3] & 0x03) == 0) {
+ vita_avail = 1;
+ lprintf(LOG_INFO, "Discovered VITA 46.11 (Supported spec. rev. %d.%d)",
+ (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
+ }
+ } else if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get VSO Capabilities");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get VSO Capabilities", rsp->ccode);
+ }
+
+ if (vita_avail == 0) {
+ lprintf(LOG_INFO, "No VITA support discovered");
+ }
+
+ return vita_avail;
+}
+
+uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = GROUP_EXT_VITA;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ return rsp->data[2];
+ }
+ if (rsp) {
+ lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
+ } else {
+ lprintf(LOG_DEBUG, "Get Address Info failed: No Response");
+ }
+ return 0;
+}
+
+
+void
+ipmi_vita_help (void)
+{
+ lprintf(LOG_NOTICE, "VITA commands:");
+ lprintf(LOG_NOTICE, " properties - get VSO properties");
+ lprintf(LOG_NOTICE, " frucontrol - FRU control");
+ lprintf(LOG_NOTICE, " addrinfo - get address information");
+ lprintf(LOG_NOTICE, " activate - activate a FRU");
+ lprintf(LOG_NOTICE, " deactivate - deactivate a FRU");
+ lprintf(LOG_NOTICE, " policy get - get the FRU activation policy");
+ lprintf(LOG_NOTICE, " policy set - set the FRU activation policy");
+ lprintf(LOG_NOTICE, " led prop - get led properties");
+ lprintf(LOG_NOTICE, " led cap - get led color capabilities");
+ lprintf(LOG_NOTICE, " led get - get led state");
+ lprintf(LOG_NOTICE, " led set - set led state");
+}
+
+int
+ipmi_vita_getaddr(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = 0; /* default fru id */
+
+ if(argc > 0) {
+ msg_data[1] = strtoul(argv[0], NULL,0); /* FRU ID */
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("Get FRU Address Info: no response\n");
+ return -1;
+ };
+
+ if (rsp->ccode) {
+ printf("Get FRU Address Info: invalid CC(0x%02x)\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("Hardware Address : 0x%02x\n", rsp->data[1]);
+ printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
+ printf("FRU ID : 0x%02x\n", rsp->data[4]);
+ printf("Site ID : 0x%02x\n", rsp->data[5]);
+
+ printf("Site Type : (0x%02x) ", rsp->data[6]);
+ switch (rsp->data[6]) {
+ case VITA_FRONT_VPX_MODULE:
+ printf("Front Loading VPX Plug-In Module\n");
+ break;
+ case VITA_POWER_ENTRY:
+ printf("Power Entry Module\n");
+ break;
+ case VITA_CHASSIS_FRU:
+ printf("Chassic FRU Information Module\n");
+ break;
+ case VITA_DEDICATED_CHMC:
+ printf("Dedicated Chassis Manager\n");
+ break;
+ case VITA_FAN_TRAY:
+ printf("Fan Tray\n");
+ break;
+ case VITA_FAN_TRAY_FILTER:
+ printf("Fan Tray Filter\n");
+ break;
+ case VITA_ALARM_PANEL:
+ printf("Alarm Panel\n");
+ break;
+ case VITA_XMC:
+ printf("XMC\n");
+ break;
+ case VITA_VPX_RTM:
+ printf("VPX Rear Transition Module\n");
+ break;
+ case VITA_FRONT_VME_MODULE:
+ printf("Front Loading VME Plug-In Module\n");
+ break;
+ case VITA_FRONT_VXS_MODULE:
+ printf("Front Loading VXS Plug-In Module\n");
+ break;
+ case VITA_POWER_SUPPLY:
+ printf("Power Supply\n");
+ break;
+ case VITA_FRONT_VITA62_MODULE:
+ printf("Front Loading VITA 62 Module\n");
+ break;
+ case VITA_71_MODULE:
+ printf("VITA 71 Module\n");
+ break;
+ case VITA_FMC:
+ printf("FMC\n");
+ break;
+ default:
+ if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) {
+ printf("OEM\n");
+ } else {
+ printf("unknown\n");
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_vso_capabilities(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data, tmp;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+
+ msg_data = GROUP_EXT_VITA; /* VITA identifier */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("Get VSO Capabilities: no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("Get VSO Capabilities: invalid CC(0x%02x)\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("VSO Identifier : 0x%02x\n", rsp->data[0]);
+ printf("IPMC Identifier : 0x%02x\n", rsp->data[1]);
+ printf(" Tier %d\n", (rsp->data[1] & 0x03) + 1);
+ printf(" Layer %d\n", ((rsp->data[1] & 0x30) >> 4) + 1);
+
+ printf("IPMB Capabilities : 0x%02x\n", rsp->data[2]);
+
+ tmp = (rsp->data[2] & 0x30) >> 4;
+
+ printf(" Frequency %skHz\n",
+ tmp == 0 ? "100" : tmp == 1 ? "400" : "RESERVED");
+
+ tmp = rsp->data[2] & 3;
+
+ if (tmp == 1) {
+ printf(" 2 IPMB interfaces supported\n");
+ } else if (tmp == 0) {
+ printf(" 1 IPMB interface supported\n");
+ }
+
+ printf("VSO Standard : %s\n",
+ (rsp->data[3] & 0x3) == 0 ? "VITA 46.11" : "RESERVED" );
+
+ printf("VSO Spec Revision : %d.%d\n", rsp->data[4] & 0xf,
+ rsp->data[4] >> 4);
+
+ printf("Max FRU Device ID : 0x%02x\n", rsp->data[5]);
+ printf("FRU Device ID : 0x%02x\n", rsp->data[6]);
+
+ return 0;
+}
+
+int
+ipmi_vita_set_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_ACTIVATION_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+ msg_data[2] = state; /* command */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU has been successfully %s\n",
+ state ? "activated" : "deactivated");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("FRU State Policy Bits: %xh\n", rsp->data[1]);
+ printf(" Default-Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x08 ? 1 : 0);
+ printf(" Commanded-Deactivation-Ingored Policy Bit is %d\n",
+ rsp->data[1] & 0x04 ? 1 : 0);
+ printf(" Deactivation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x02 ? 1 : 0);
+ printf(" Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x01);
+
+ return 0;
+}
+
+int
+ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[4];
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 4;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* bits mask */
+ msg_data[3] = strtol(argv[2], NULL, 0); /* bits */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU state policy bits have been updated\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_PROPERTIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("General Status LED Properties: 0x%02x\n", rsp->data[1] );
+ printf("App. Specific LED Count: 0x%02x\n", rsp->data[2] );
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_color_capabilities(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+ int i;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_LED_COLOR_CAPABILITIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("LED Color Capabilities: ");
+ for (i = 0; i < 8; i++) {
+ if (rsp->data[1] & (0x01 << i)) {
+ printf("%s, ", led_color_str[i]);
+ }
+ }
+ printf("\n");
+
+ printf("Default LED Color in\n");
+ printf(" LOCAL control: %s\n", led_color_str[ rsp->data[2] ] );
+ printf(" OVERRIDE state: %s\n", led_color_str[ rsp->data[3] ] );
+
+ if (rsp->data_len == 5) {
+ printf("LED flags:\n");
+ if (rsp->data[4] & 2) {
+ printf(" [HW RESTRICT]\n");
+ }
+ if (rsp->data[4] & 1) {
+ printf(" [PAYLOAD PWR]\n");
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_state(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("LED states: %x\t", rsp->data[1] );
+ if (rsp->data[1] & 0x1) {
+ printf("[LOCAL CONTROL] ");
+ }
+ if (rsp->data[1] & 0x2) {
+ printf("[OVERRIDE] ");
+ }
+ if (rsp->data[1] & 0x4) {
+ printf("[LAMPTEST] ");
+ }
+ if (rsp->data[1] & 0x8) {
+ printf("[HW RESTRICT] ");
+ }
+
+ puts("\n");
+
+ if (rsp->data[1] & 1) {
+ printf(" Local Control function: %x\t", rsp->data[2] );
+ if (rsp->data[2] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[2] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Local Control On-Duration: %x\n", rsp->data[3] );
+ printf(" Local Control Color: %x\t[%s]\n",
+ rsp->data[4], led_color_str[rsp->data[4] & 7]);
+ }
+
+ /* override state or lamp test */
+ if (rsp->data[1] & 0x06) {
+ printf(" Override function: %x\t", rsp->data[5] );
+ if (rsp->data[5] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[5] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Override On-Duration: %x\n", rsp->data[6] );
+ printf(" Override Color: %x\t[%s]\n",
+ rsp->data[7], led_color_str[rsp->data[7] & 7]);
+ if (rsp->data[1] == 0x04) {
+ printf(" Lamp test duration: %x\n", rsp->data[8] );
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[6];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 6;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+ msg_data[3] = strtol(argv[2], NULL, 0); /* LED function */
+ msg_data[4] = strtol(argv[3], NULL, 0); /* LED on duration */
+ msg_data[5] = strtol(argv[4], NULL, 0); /* LED color */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU LED state has been updated\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_fru_control(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_FRU_CONTROL_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* control option */
+
+ printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1],
+ val2str( msg_data[2], picmg_frucontrol_vals));
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("frucontrol: no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("frucontrol: returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("frucontrol: ok\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_main (struct ipmi_intf * intf, int argc, char ** argv)
+{
+ int rc = 0;
+ int showProperties = 0;
+
+ if (argc == 0 || (!strncmp(argv[0], "help", 4))) {
+ ipmi_vita_help();
+ return 0;
+ }
+
+ /* Get VSO Properties is called to obtain version information */
+ if (!strncmp(argv[0], "properties", 10)) {
+ rc = ipmi_vita_get_vso_capabilities(intf);
+ /* Get FRU Address Info command */
+ } else if (!strncmp(argv[0], "addrinfo", 8)) {
+ rc = ipmi_vita_getaddr(intf, argc-1, &argv[1]);
+ /* FRU Control command */
+ } else if (!strncmp(argv[0], "frucontrol", 10)) {
+ if (argc > 2) {
+ rc = ipmi_vita_fru_control(intf, argc-1, &(argv[1]));
+ } else {
+ printf("usage: frucontrol <FRU-ID> <OPTION>\n");
+ printf(" OPTION:\n");
+ printf(" 0 - Cold Reset\n");
+ printf(" 1 - Warm Reset\n");
+ printf(" 2 - Graceful Reboot\n");
+ printf(" 3 - Issue Diagnostic Interrupt\n");
+ printf(" 4-255 - Reserved\n");
+ rc = -1;
+ }
+ /* Set FRU Activation (activate) command */
+ } else if (!strncmp(argv[0], "activate", 8)) {
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, argc-1, &(argv[1]), 1);
+ } else {
+ printf("specify the FRU to activate\n");
+ rc = -1;
+ }
+ /* Set FRU Activation (deactivate) command */
+ } else if (!strncmp(argv[0], "deactivate", 10)) {
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, argc-1, &(argv[1]), 0);
+ } else {
+ printf("specify the FRU to deactivate\n");
+ rc = -1;
+ }
+ /* FRU State Policy Bits commands */
+ } else if (!strncmp(argv[0], "policy", 6)) {
+ if (argc > 1) {
+ if (!strncmp(argv[1], "get", 3)) {
+ if (argc > 2) {
+ rc = ipmi_vita_get_fru_state_policy_bits(intf, argc-1, &(argv[2]));
+ } else {
+ printf("usage: get <fruid>\n");
+ }
+ } else if (!strncmp(argv[1], "set", 3)) {
+ if (argc > 4) {
+ rc = ipmi_vita_set_fru_state_policy_bits(intf, argc-1, &(argv[2]));
+ } else {
+ printf("usage: set <fruid> <mask> <value>\n");
+ printf(" mask: [3] affect the Default-Activation-Locked Policy Bit\n");
+ printf(" [2] affect the Commanded-Deactivation-Ignored Policy Bit\n");
+ printf(" [1] affect the Deactivation-Locked Policy Bit\n");
+ printf(" [0] affect the Activation-Locked Policy Bit\n");
+ printf(" value: [3] value for the Default-Activation-Locked Policy Bit\n");
+ printf(" [2] value for the Commanded-Deactivation-Ignored Policy Bit\n");
+ printf(" [1] value for the Deactivation-Locked Policy Bit\n");
+ printf(" [0] value for the Activation-Locked Policy Bit\n");
+ }
+ } else {
+ printf("usage: policy get | policy set\n");
+ rc = -1;
+ }
+ } else {
+ printf("usage: policy get | policy set\n");
+ rc = -1;
+ }
+ /* FRU LED commands */
+ } else if (!strncmp(argv[0], "led", 3)) {
+ if (argc > 1) {
+ if (!strncmp(argv[1], "prop", 4)) {
+ if (argc > 2) {
+ rc = ipmi_vita_get_led_properties(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led prop <FRU-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "cap", 3)) {
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_color_capabilities(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led cap <FRU-ID> <LED-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "get", 3)) {
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_state(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led get <FRU-ID> <LED-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "set", 3)) {
+ if (argc > 6) {
+ rc = ipmi_vita_set_led_state(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led set <FRU-ID> <LED-ID> <function> <duration> <color>\n");
+ printf(" <FRU-ID>\n");
+ printf(" <LED-ID> 0-0xFE: Specified LED\n");
+ printf(" 0xFF: All LEDs under management control\n");
+ printf(" <function> 0: LED OFF override\n");
+ printf(" 1 - 250: LED blinking override (off duration)\n");
+ printf(" 251: LED Lamp Test\n");
+ printf(" 252: LED restore to local control\n");
+ printf(" 255: LED ON override\n");
+ printf(" <duration> 1 - 127: LED Lamp Test / on duration\n");
+ printf(" <color> 0: reserved\n");
+ printf(" 1: BLUE\n");
+ printf(" 2: RED\n");
+ printf(" 3: GREEN\n");
+ printf(" 4: AMBER\n");
+ printf(" 5: ORANGE\n");
+ printf(" 6: WHITE\n");
+ printf(" 7: reserved\n");
+ printf(" 0xE: do not change\n");
+ printf(" 0xF: use default color\n");
+ }
+ } else {
+ printf("prop | cap | get | set\n");
+ }
+ }
+ } else {
+ ipmi_vita_help();
+ rc = -1;
+ }
+
+ return rc;
+}
diff --git a/src/ipmitool.c b/src/ipmitool.c
index 6230e5c..49ec8f6 100644
--- a/src/ipmitool.c
+++ b/src/ipmitool.c
@@ -65,6 +65,7 @@
#include <ipmitool/ipmi_ekanalyzer.h>
#include <ipmitool/ipmi_ime.h>
#include <ipmitool/ipmi_dcmi.h>
+#include <ipmitool/ipmi_vita.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -119,6 +120,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = {
{ ipmi_hpmfwupg_main,"hpm", "Update HPM components using PICMG HPM.1 file"},
{ ipmi_ekanalyzer_main,"ekanalyzer", "run FRU-Ekeying analyzer using FRU files"},
{ ipmi_ime_main, "ime", "Update Intel Manageability Engine Firmware"},
+ { ipmi_vita_main, "vita", "Run a VITA 46.11 extended cmd"},
{ NULL },
};
diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c
index 5f4b926..a0ac875 100644
--- a/src/plugins/serial/serial_basic.c
+++ b/src/plugins/serial/serial_basic.c
@@ -1008,13 +1008,6 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
return NULL;
}
-int
-serial_bm_set_my_addr(struct ipmi_intf * intf, uint8_t addr)
-{
- intf->my_addr = addr;
- return 0;
-}
-
/*
* Serial BM interface
*/
@@ -1025,5 +1018,4 @@ struct ipmi_intf ipmi_serial_bm_intf = {
open: serial_bm_open,
close: serial_bm_close,
sendrecv: serial_bm_send_request,
- set_my_addr:serial_bm_set_my_addr
};
diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c
index 41d3753..e4f8935 100644
--- a/src/plugins/serial/serial_terminal.c
+++ b/src/plugins/serial/serial_terminal.c
@@ -898,13 +898,7 @@ ipmi_serial_term_setup(struct ipmi_intf * intf)
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;
intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;
- return 0;
-}
-int
-ipmi_serial_term_set_my_addr(struct ipmi_intf * intf, uint8_t addr)
-{
- intf->my_addr = addr;
return 0;
}
@@ -915,5 +909,4 @@ struct ipmi_intf ipmi_serial_term_intf = {
open: ipmi_serial_term_open,
close: ipmi_serial_term_close,
sendrecv: ipmi_serial_term_send_cmd,
- set_my_addr:ipmi_serial_term_set_my_addr
};
--------------070703040500050105010503--
- msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */
+ if (bridgedRequest)
+ msg[len++] = intf->target_addr;
+ else
+ msg[len++] = IPMI_BMC_SLAVE_ADDR;
/* net Fn */
msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);
@@ -1440,7 +1428,7 @@ void getIpmiPayloadWireRep(
cs = len;
/* rqAddr */
- if (!bridgedRequest)
+ if (bridgedRequest < 2)
msg[len++] = IPMI_REMOTE_SWID;
else /* Bridged message */
msg[len++] = intf->my_addr;
@@ -1551,7 +1539,7 @@ void getSolPayloadWireRep(
* ipmi_lanplus_build_v2x_msg
*
* Encapsulates the payload data to create the IPMI v2.0 / RMCP+ packet.
- *
+ *
*
* IPMI v2.0 LAN Request Message Format
* +----------------------+
@@ -1690,7 +1678,7 @@ ipmi_lanplus_build_v2x_msg(
curr_seq);
break;
- case IPMI_PAYLOAD_TYPE_SOL:
+ case IPMI_PAYLOAD_TYPE_SOL:
getSolPayloadWireRep(intf,
msg + IPMI_LANPLUS_OFFSET_PAYLOAD,
payload);
@@ -1903,13 +1891,15 @@ ipmi_lanplus_build_v2x_ipmi_cmd(
if(entry)
{
- /* Add entry for bridge cmd */
- backup_cmd = req->msg.cmd;
- req->msg.cmd = 0x34;
- entry = ipmi_req_add_entry(intf, req, curr_seq);
- req->msg.cmd = backup_cmd;
+ entry->req.msg.target_cmd = entry->req.msg.cmd;
+ entry->req.msg.cmd = 0x34;
+
+ if(intf->transit_addr && intf->transit_addr != intf->my_addr)
+ entry->bridging_level = 2;
+ else
+ entry->bridging_level = 1;
}
- }
+ }
if (entry == NULL)
return NULL;
@@ -2091,7 +2081,7 @@ sol_response_acks_packet(
{
return (is_sol_packet(rsp) &&
payload &&
- (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) &&
+ (payload->payload_type == IPMI_PAYLOAD_TYPE_SOL) &&
(rsp->payload.sol_packet.acked_packet_number ==
payload->payload.sol_packet.packet_sequence_number));
}
@@ -2125,7 +2115,7 @@ ipmi_lanplus_send_payload(
* so it will only be valid after the open completes.
*/
saved_timeout = session->timeout;
- while (try < session->retry) {
+ while (try < intf->ssn_params.retry) {
//ltime = time(NULL);
if (xmit) {
@@ -2186,8 +2176,7 @@ ipmi_lanplus_send_payload(
else if (payload->payload_type == IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST)
{
lprintf(LOG_DEBUG, ">> SENDING AN OPEN SESSION REQUEST\n");
- assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION
- || session->v2_data.session_state == LANPLUS_STATE_OPEN_SESSION_SENT);
+ assert(session->v2_data.session_state == LANPLUS_STATE_PRESESSION);
ipmi_lanplus_build_v2x_msg(intf, /* in */
payload, /* in */
@@ -2263,16 +2252,16 @@ ipmi_lanplus_send_payload(
case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:
session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT;
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
break;
case IPMI_PAYLOAD_TYPE_RAKP_1:
session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT;
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
break;
case IPMI_PAYLOAD_TYPE_RAKP_3:
/* not retryable for timeouts, force no retry */
- try = session->retry;
+ try = intf->ssn_params.retry;
session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT;
break;
}
@@ -2419,7 +2408,7 @@ static void set_sol_packet_sequence_number(
*
* Returns a pointer to the SOL ACK we received, or
* 0 on failure
- *
+ *
*/
struct ipmi_rs *
ipmi_lanplus_send_sol(
@@ -2656,7 +2645,7 @@ ipmi_lanplus_send_ipmi_cmd(
* param auth_cap [out] will be initialized to hold the Get Channel
* Authentication Capabilities return data on success. Its
* contents will be undefined on error.
- *
+ *
* returns 0 on success
* non-zero if we were unable to contact the BMC, or we cannot
* get a successful response
@@ -2677,7 +2666,7 @@ ipmi_get_auth_capabilities_cmd(
bridgePossible = 0;
msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well
- msg_data[1] = intf->session->privlvl;
+ msg_data[1] = intf->ssn_params.privlvl;
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP; // 0x06
@@ -2809,8 +2798,8 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE);
msg[0] = 0; /* Message tag */
- if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN)
- msg[1] = session->privlvl;
+ if (ipmi_oem_active(intf, "intelplus") || intf->ssn_params.privlvl != IPMI_SESSION_PRIV_ADMIN)
+ msg[1] = intf->ssn_params.privlvl;
else
msg[1] = 0; /* Give us highest privlg level based on supported algorithms */
msg[2] = 0; /* reserved */
@@ -2824,13 +2813,13 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[7] = (session->v2_data.console_id >> 24) & 0xff;
- if (lanplus_get_requested_ciphers(session->cipher_suite_id,
+ if (lanplus_get_requested_ciphers(intf->ssn_params.cipher_suite_id,
&(session->v2_data.requested_auth_alg),
&(session->v2_data.requested_integrity_alg),
&(session->v2_data.requested_crypt_alg)))
{
lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n",
- session->cipher_suite_id);
+ intf->ssn_params.cipher_suite_id);
free(msg);
msg = NULL;
return 1;
@@ -2845,9 +2834,9 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[10] = 0; /* reserved */
msg[11] = 8; /* payload length */
msg[12] = session->v2_data.requested_auth_alg;
- msg[13] = 0; /* reserved */
+ msg[13] = 0; /* reserved */
msg[14] = 0; /* reserved */
- msg[15] = 0; /* reserved */
+ msg[15] = 0; /* reserved */
/*
* Integrity payload
@@ -2857,7 +2846,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[18] = 0; /* reserved */
msg[19] = 8; /* payload length */
msg[20] = session->v2_data.requested_integrity_alg;
- msg[21] = 0; /* reserved */
+ msg[21] = 0; /* reserved */
msg[22] = 0; /* reserved */
msg[23] = 0; /* reserved */
@@ -2869,7 +2858,7 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)
msg[26] = 0; /* reserved */
msg[27] = 8; /* payload length */
msg[28] = session->v2_data.requested_crypt_alg;
- msg[29] = 0; /* reserved */
+ msg[29] = 0; /* reserved */
msg[30] = 0; /* reserved */
msg[31] = 0; /* reserved */
@@ -3034,14 +3023,14 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
/*
* Requested maximum privilege level.
*/
- msg[24] = session->privlvl | session->v2_data.lookupbit;
+ msg[24] = intf->ssn_params.privlvl | intf->ssn_params.lookupbit;
session->v2_data.requested_role = msg[24];
msg[25] = 0; /* reserved */
msg[26] = 0; /* reserved */
/* Username specification */
- msg[27] = strlen((const char *)session->username);
+ msg[27] = strlen((const char *)intf->ssn_params.username);
if (msg[27] > IPMI_MAX_USER_NAME_LENGTH)
{
lprintf(LOG_ERR, "ERROR: user name too long. "
@@ -3051,7 +3040,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
msg = NULL;
return 1;
}
- memcpy(msg + 28, session->username, msg[27]);
+ memcpy(msg + 28, intf->ssn_params.username, msg[27]);
v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1;
v2_payload.payload_length =
@@ -3097,7 +3086,7 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)
* whether the BMC has authenticated.
*/
if (! lanplus_rakp2_hmac_matches(session,
- rsp->payload.rakp2_message.key_exchange_auth_code,
+ rsp->payload.rakp2_message.key_exchange_auth_code,
intf))
{
/* Error */
@@ -3142,7 +3131,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
struct ipmi_rs * rsp;
assert(session->v2_data.session_state == LANPLUS_STATE_RAKP_2_RECEIVED);
-
+
/*
* Build a RAKP 3 message
*/
@@ -3156,7 +3145,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
msg[0] = 0; /* Message tag */
msg[1] = session->v2_data.rakp2_return_code;
-
+
msg[2] = 0; /* reserved */
msg[3] = 0; /* reserved */
@@ -3179,7 +3168,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
if (session->v2_data.rakp2_return_code == IPMI_RAKP_STATUS_NO_ERRORS)
{
uint32_t auth_length;
-
+
if (lanplus_generate_rakp3_authcode(msg + 8, session, &auth_length, intf))
{
/* Error */
@@ -3220,7 +3209,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
return 1;
}
}
-
+
rsp = ipmi_lanplus_send_payload(intf, &v2_payload);
@@ -3248,7 +3237,7 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
*/
if (verbose)
lanplus_dump_rakp4_message(rsp, session->v2_data.auth_alg);
-
+
if (rsp->payload.open_session_response.rakp_return_code != IPMI_RAKP_STATUS_NO_ERRORS)
{
@@ -3288,34 +3277,34 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)
void
ipmi_lanplus_close(struct ipmi_intf * intf)
{
- if (!intf->abort)
- ipmi_close_session_cmd(intf);
-
- if (intf->fd >= 0)
- close(intf->fd);
-
- ipmi_req_clear_entries();
-
if (intf->session) {
+ if (!intf->abort) {
+ ipmi_close_session_cmd(intf);
+ }
free(intf->session);
intf->session = NULL;
}
- intf->session = NULL;
+ if (intf->fd >= 0) {
+ close(intf->fd);
+ intf->fd = -1;
+ }
+
+ /* clear entries after sending Close Session command */
+ ipmi_req_clear_entries();
+
intf->opened = 0;
intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL;
}
-
-
static int
ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)
{
struct ipmi_rs * rsp;
struct ipmi_rq req;
uint8_t backupBridgePossible;
- uint8_t privlvl = intf->session->privlvl;
+ uint8_t privlvl = intf->ssn_params.privlvl;
if (privlvl <= IPMI_SESSION_PRIV_USER)
return 0; /* no need to set higher */
@@ -3365,54 +3354,58 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
int rc;
int retry;
struct get_channel_auth_cap_rsp auth_cap;
- struct ipmi_session *session;
+ struct sockaddr_in addr;
+ struct ipmi_session_params *params;
+ struct ipmi_session * session;
- if (!intf || !intf->session)
+ if (!intf || !intf->session) {
return -1;
- session = intf->session;
+ }
+ params = &intf->ssn_params;
- if (!session->port)
- session->port = IPMI_LANPLUS_PORT;
- if (!session->privlvl)
- session->privlvl = IPMI_SESSION_PRIV_ADMIN;
- if (!session->timeout)
- session->timeout = IPMI_LAN_TIMEOUT;
- if (!session->retry)
- session->retry = IPMI_LAN_RETRY;
+ if (!params->port)
+ params->port = IPMI_LANPLUS_PORT;
+ if (!params->privlvl)
+ params->privlvl = IPMI_SESSION_PRIV_ADMIN;
+ if (!params->timeout)
+ params->timeout = IPMI_LAN_TIMEOUT;
+ if (!params->retry)
+ params->retry = IPMI_LAN_RETRY;
- if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) {
- lprintf(LOG_ERR, "No hostname specified!");
+ if (ipmi_intf_socket_connect(intf) == -1) {
+ lprintf(LOG_ERR, "Could not open socket!");
return -1;
}
+ /* alllocate new session */
+ session = (struct ipmi_session *)malloc(sizeof (struct ipmi_session));
+
+ if (!session) {
+ lprintf(LOG_ERR, "ipmitool: malloc failure");
+ goto fail;
+ }
+
+ /* clear session data */
+ memset(session, 0, sizeof (struct ipmi_session));
+
+ /* need no to close session */
intf->abort = 1;
+ /* save interface session pointer */
+ intf->session = session;
/* Setup our lanplus session state */
+ session->timeout = params->timeout;
+ memcpy(&session->authcode, ¶ms->authcode_set,
+ sizeof (session->authcode));
+ memcpy(&session->addr, &addr, sizeof (session->addr));
+ session->v2_data.session_state = LANPLUS_STATE_PRESESSION;
session->v2_data.auth_alg = IPMI_AUTH_RAKP_NONE;
session->v2_data.crypt_alg = IPMI_CRYPT_NONE;
session->v2_data.console_id = 0x00;
session->v2_data.bmc_id = 0x00;
session->sol_data.sequence_number = 1;
- //session->sol_data.last_received_sequence_number = 0;
- //session->sol_data.last_received_byte_count = 0;
- memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE);
-
- /* Kg is set in ipmi_intf */
- //memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
-
- if (ipmi_intf_socket_connect (intf) == -1) {
- lprintf(LOG_ERR, "Could not open socket!");
- return -1;
- }
-
- if (intf->fd < 0) {
- lperror(LOG_ERR, "Connect to %s failed",
- session->hostname);
- intf->close(intf);
- return -1;
- }
intf->opened = 1;
@@ -3440,6 +3433,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
*/
for (retry = 0; retry < IPMI_LAN_RETRY; retry++) {
session->v2_data.session_state = LANPLUS_STATE_PRESESSION;
+
/*
* Open session
*/
@@ -3451,6 +3445,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
lprintf(LOG_DEBUG, "Retry lanplus open session, %d", retry);
continue;
}
+
/*
* RAKP 1
*/
@@ -3489,10 +3484,24 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
hpm2_detect_max_payload_size(intf);
return intf->fd;
-
+ close_fail:
+ ipmi_close_session_cmd(intf);
fail:
lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session");
+ if (intf->session) {
+ free(intf->session);
+ intf->session = NULL;
+ }
+
+ ipmi_req_clear_entries();
+
+ if (intf->fd >= 0) {
+ close(intf->fd);
+ intf->fd = -1;
+ }
+
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
return -1;
}
@@ -3527,7 +3536,7 @@ void test_crypt1(void)
assert(0);
}
printbuf(encrypt_buffer, bytes_encrypted, "encrypted payload");
-
+
if (lanplus_decrypt_payload(IPMI_CRYPT_AES_CBC_128,
key,
@@ -3538,12 +3547,12 @@ void test_crypt1(void)
{
lprintf(LOG_ERR, "Decrypt test failed\n");
assert(0);
- }
+ }
printbuf(decrypt_buffer, bytes_decrypted, "decrypted payload");
-
+
lprintf(LOG_DEBUG, "\nDone testing the encrypt/decyrpt methods!\n");
exit(0);
-}
+}
@@ -3633,13 +3642,6 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)
if (lanplus_seed_prng(16))
return -1;
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;
intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE;
@@ -3649,7 +3651,7 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)
static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)
{
- if (intf->session->cipher_suite_id == 3) {
+ if (intf->ssn_params.cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
@@ -3667,7 +3669,7 @@ static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t siz
static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)
{
- if (intf->session->cipher_suite_id == 3) {
+ if (intf->ssn_params.cipher_suite_id == 3) {
/*
* encrypted payload can only be multiple of 16 bytes
*/
diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c
index 54fd5cb..1cdd050 100644
--- a/src/plugins/lanplus/lanplus_crypt.c
+++ b/src/plugins/lanplus/lanplus_crypt.c
@@ -95,7 +95,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
16 + /* GUIDc */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username); /* optional */
+ strlen((const char *)intf->ssn_params.username); /* optional */
buffer = malloc(bufferLength);
if (buffer == NULL) {
@@ -163,11 +163,11 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,
}
/* ULENGTHm */
- buffer[57] = strlen((const char *)session->username);
+ buffer[57] = strlen((const char *)intf->ssn_params.username);
/* UserName [optional] */
for (i = 0; i < buffer[57]; ++i)
- buffer[58 + i] = session->username[i];
+ buffer[58 + i] = intf->ssn_params.username[i];
if (verbose > 2)
{
@@ -375,7 +375,7 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
4 + /* SIDm */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username);
+ strlen((const char *)intf->ssn_params.username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
@@ -406,16 +406,16 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,
/* ROLEm */
if (ipmi_oem_active(intf, "intelplus") || ipmi_oem_active(intf, "i82571spt"))
- input_buffer[20] = session->privlvl;
+ input_buffer[20] = intf->ssn_params.privlvl;
else
input_buffer[20] = session->v2_data.requested_role;
/* ULENGTHm */
- input_buffer[21] = strlen((const char *)session->username);
+ input_buffer[21] = strlen((const char *)intf->ssn_params.username);
/* USERNAME */
for (i = 0; i < input_buffer[21]; ++i)
- input_buffer[22 + i] = session->username[i];
+ input_buffer[22 + i] = intf->ssn_params.username[i];
if (verbose > 2)
{
@@ -491,7 +491,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
16 + /* Rc */
1 + /* ROLEm */
1 + /* ULENGTHm */
- strlen((const char *)session->username);
+ strlen((const char *)intf->ssn_params.username);
input_buffer = malloc(input_buffer_length);
if (input_buffer == NULL) {
@@ -536,13 +536,13 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
}
/* ULENGTHm */
- input_buffer[33] = strlen((const char *)session->username);
+ input_buffer[33] = strlen((const char *)intf->ssn_params.username);
/* USERNAME */
for (i = 0; i < input_buffer[33]; ++i)
- input_buffer[34 + i] = session->username[i];
+ input_buffer[34 + i] = intf->ssn_params.username[i];
- if (session->v2_data.kg[0])
+ if (intf->ssn_params.kg[0])
{
/* We will be hashing with Kg */
/*
@@ -550,7 +550,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)
* using Kg. It specifies that Kg should not be truncated.
* Kg is set in ipmi_intf.
*/
- input_key = session->v2_data.kg;
+ input_key = intf->ssn_params.kg;
}
else
{
diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c
index 5f4b926..eb8305e 100644
--- a/src/plugins/serial/serial_basic.c
+++ b/src/plugins/serial/serial_basic.c
@@ -178,21 +178,15 @@ static const struct {
static int is_system;
/*
- * Setup serial interface
- */
+ Setup serial interface
+*/
static int
serial_bm_setup(struct ipmi_intf * intf)
{
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = SERIAL_BM_MAX_RQ_SIZE;
intf->max_response_data_size = SERIAL_BM_MAX_RS_SIZE;
+
return 0;
}
@@ -285,10 +279,10 @@ serial_bm_open(struct ipmi_intf * intf)
/* set the new options for the port with flushing */
tcsetattr(intf->fd, TCSAFLUSH, &ti);
- if (intf->session->timeout == 0)
- intf->session->timeout = SERIAL_BM_TIMEOUT;
- if (intf->session->retry == 0)
- intf->session->retry = SERIAL_BM_RETRY_COUNT;
+ if (intf->ssn_params.timeout == 0)
+ intf->ssn_params.timeout = SERIAL_BM_TIMEOUT;
+ if (intf->ssn_params.retry == 0)
+ intf->ssn_params.retry = SERIAL_BM_RETRY_COUNT;
intf->opened = 1;
@@ -306,11 +300,6 @@ serial_bm_close(struct ipmi_intf * intf)
intf->fd = -1;
}
- if (intf->session) {
- free(intf->session);
- intf->session = NULL;
- }
-
intf->opened = 0;
}
@@ -464,7 +453,7 @@ serial_bm_wait_for_data(struct ipmi_intf * intf)
pfd.events = POLLIN;
pfd.revents = 0;
- n = poll(&pfd, 1, intf->session->timeout*1000);
+ n = poll(&pfd, 1, intf->ssn_params.timeout*1000);
if (n < 0) {
lperror(LOG_ERR, "Poll for serial data failed");
return -1;
@@ -892,7 +881,7 @@ serial_bm_get_message(struct ipmi_intf * intf,
tm = clock() - start;
tm /= CLOCKS_PER_SEC;
- } while (tm < intf->session->timeout);
+ } while (tm < intf->ssn_params.timeout);
return 0;
}
@@ -915,7 +904,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
read_ctx.max_buffer_size = SERIAL_BM_MAX_BUFFER_SIZE;
/* Send the message and receive the answer */
- for (retry = 0; retry < intf->session->retry; retry++) {
+ for (retry = 0; retry < intf->ssn_params.retry; retry++) {
/* build output message */
bridging_level = serial_bm_build_msg(intf, req, msg,
sizeof (msg), req_ctx, &msg_len);
@@ -961,7 +950,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
/* check if response for inner request is not encapsulated */
} else if (rv == 1) {
/* wait for response for inner request */
- rv = serial_bm_wait_response(intf, &req_ctx[0],
+ rv = serial_bm_wait_response(intf, &req_ctx[1],
&read_ctx, msg, sizeof (msg));
/* check for IO error */
diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c
index 41d3753..0c377f1 100644
--- a/src/plugins/serial/serial_terminal.c
+++ b/src/plugins/serial/serial_terminal.c
@@ -225,10 +225,10 @@ ipmi_serial_term_open(struct ipmi_intf * intf)
/* set the new options for the port with flushing */
tcsetattr(intf->fd, TCSAFLUSH, &ti);
- if (intf->session->timeout == 0)
- intf->session->timeout = IPMI_SERIAL_TIMEOUT;
- if (intf->session->retry == 0)
- intf->session->retry = IPMI_SERIAL_RETRY;
+ if (intf->ssn_params.timeout == 0)
+ intf->ssn_params.timeout = IPMI_SERIAL_TIMEOUT;
+ if (intf->ssn_params.retry == 0)
+ intf->ssn_params.retry = IPMI_SERIAL_RETRY;
intf->opened = 1;
@@ -243,11 +243,6 @@ ipmi_serial_term_close(struct ipmi_intf * intf)
intf->fd = -1;
}
- if (intf->session) {
- free(intf->session);
- intf->session = NULL;
- }
-
intf->opened = 0;
}
@@ -264,7 +259,7 @@ serial_wait_for_data(struct ipmi_intf * intf)
pfd.events = POLLIN;
pfd.revents = 0;
- n = poll(&pfd, 1, intf->session->timeout*1000);
+ n = poll(&pfd, 1, intf->ssn_params.timeout*1000);
if (n < 0) {
lperror(LOG_ERR, "Poll for serial data failed");
return -1;
@@ -362,7 +357,7 @@ recv_response(struct ipmi_intf * intf, unsigned char *data, int len)
{
char hex_rs[IPMI_SERIAL_MAX_RESPONSE * 3];
int i, j, resp_len = 0;
- unsigned long rv;
+ long rv;
char *p, *pp;
char ch, str_hex[3];
@@ -774,7 +769,7 @@ serial_term_get_message(struct ipmi_intf * intf,
tm = clock() - start;
tm /= CLOCKS_PER_SEC;
- } while (tm < intf->session->timeout);
+ } while (tm < intf->ssn_params.timeout);
return 0;
}
@@ -792,7 +787,7 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
}
/* Send the message and receive the answer */
- for (retry = 0; retry < intf->session->retry; retry++) {
+ for (retry = 0; retry < intf->ssn_params.retry; retry++) {
/* build output message */
bridging_level = serial_term_build_msg(intf, req, msg,
sizeof (msg), req_ctx, &msg_len);
@@ -887,14 +882,6 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
static int
ipmi_serial_term_setup(struct ipmi_intf * intf)
{
- intf->session = malloc(sizeof(struct ipmi_session));
- if (intf->session == NULL) {
- lprintf(LOG_ERR, "ipmitool: malloc failure");
- return -1;
- }
-
- memset(intf->session, 0, sizeof(struct ipmi_session));
-
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;
intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;
--------------070703040500050105010503
Content-Type: text/x-patch;
name="vita-support.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="vita-support.diff"
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index 437a427..d97df3c 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -168,6 +168,7 @@ struct ipmi_intf {
int abort;
int noanswer;
int picmg_avail;
+ int vita_avail;
IPMI_OEM manufacturer_id;
struct ipmi_session * session;
diff --git a/include/ipmitool/ipmi_vita.h b/include/ipmitool/ipmi_vita.h
new file mode 100644
index 0000000..71d471a
--- /dev/null
+++ b/include/ipmitool/ipmi_vita.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) Pigeon Point Systems. All right reserved
+ */
+
+#ifndef _IPMI_VITA_H_
+#define _IPMI_VITA_H_
+
+/* VITA 46.11 commands */
+#define VITA_GET_VSO_CAPABILITIES_CMD 0x00
+#define VITA_FRU_CONTROL_CMD 0x04
+#define VITA_GET_FRU_LED_PROPERTIES_CMD 0x05
+#define VITA_GET_LED_COLOR_CAPABILITIES_CMD 0x06
+#define VITA_SET_FRU_LED_STATE_CMD 0x07
+#define VITA_GET_FRU_LED_STATE_CMD 0x08
+#define VITA_SET_FRU_STATE_POLICY_BITS_CMD 0x0A
+#define VITA_GET_FRU_STATE_POLICY_BITS_CMD 0x0B
+#define VITA_SET_FRU_ACTIVATION_CMD 0x0C
+#define VITA_GET_FRU_ADDRESS_INFO_CMD 0x40
+
+/* VITA 46.11 site types */
+#define VITA_FRONT_VPX_MODULE 0x00
+#define VITA_POWER_ENTRY 0x01
+#define VITA_CHASSIS_FRU 0x02
+#define VITA_DEDICATED_CHMC 0x03
+#define VITA_FAN_TRAY 0x04
+#define VITA_FAN_TRAY_FILTER 0x05
+#define VITA_ALARM_PANEL 0x06
+#define VITA_XMC 0x07
+#define VITA_VPX_RTM 0x09
+#define VITA_FRONT_VME_MODULE 0x0A
+#define VITA_FRONT_VXS_MODULE 0x0B
+#define VITA_POWER_SUPPLY 0x0C
+#define VITA_FRONT_VITA62_MODULE 0x0D
+#define VITA_71_MODULE 0x0E
+#define VITA_FMC 0x0F
+
+
+#define GROUP_EXT_VITA 0x03
+
+extern uint8_t
+vita_discover(struct ipmi_intf *intf);
+
+extern uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf);
+
+extern int
+ipmi_vita_main(struct ipmi_intf * intf, int argc, char ** argv);
+
+#endif /* _IPMI_VITA_H_ */
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d878b11..2a316db 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -39,7 +39,7 @@ libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_pef.c \
ipmi_oem.c ipmi_isol.c ipmi_sunoem.c ipmi_fwum.c ipmi_picmg.c \
ipmi_main.c ipmi_tsol.c ipmi_firewall.c ipmi_kontronoem.c \
ipmi_hpmfwupg.c ipmi_sdradd.c ipmi_ekanalyzer.c ipmi_gendev.c \
- ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c \
+ ipmi_ime.c ipmi_delloem.c ipmi_dcmi.c hpm2.c ipmi_vita.c \
../src/plugins/lan/md5.c ../src/plugins/lan/md5.h
libipmitool_la_LDFLAGS = -export-dynamic
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c
index 14ca183..4b723c4 100644
--- a/lib/ipmi_main.c
+++ b/lib/ipmi_main.c
@@ -338,6 +338,18 @@ ipmi_parse_hex(const char *str)
return out;
}
+static uint8_t
+ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
+{
+ if (intf->picmg_avail) {
+ return ipmi_picmg_ipmb_address(intf);
+ } else if (intf->vita_avail) {
+ return ipmi_vita_ipmb_address(intf);
+ } else {
+ return 0;
+ }
+}
+
/* ipmi_parse_options - helper function to handle parsing command line options
*
* @argc: count of options
@@ -900,15 +912,24 @@ ipmi_main(int argc, char ** argv,
goto out_free;
}
}
+
/*
- * Attempt picmg discovery of the actual interface address unless
+ * Attempt picmg/vita discovery of the actual interface address unless
* the users specified an address.
* Address specification always overrides discovery
*/
- if (picmg_discover(ipmi_main_intf) && !arg_addr) {
- lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
- addr = ipmi_picmg_ipmb_address(ipmi_main_intf);
- lprintf(LOG_INFO, "Discovered IPMB-0 address 0x%x", addr);
+ if (picmg_discover(ipmi_main_intf)) {
+ ipmi_main_intf->picmg_avail = 1;
+ } else if (vita_discover(ipmi_main_intf)) {
+ ipmi_main_intf->vita_avail = 1;
+ }
+
+ if (arg_addr) {
+ addr = arg_addr;
+ } else {
+ lprintf(LOG_DEBUG, "Acquire IPMB address");
+ addr = ipmi_acquire_ipmb_address(ipmi_main_intf);
+ lprintf(LOG_INFO, "Discovered IPMB address 0x%x", addr);
}
/*
@@ -916,41 +937,44 @@ ipmi_main(int argc, char ** argv,
* used for open, Set the discovered IPMB address as my address if the
* interface supports it.
*/
- if (addr != 0 && addr != ipmi_main_intf->my_addr &&
- ipmi_main_intf->set_my_addr) {
- /*
- * Only set the interface address on interfaces which support
- * it
- */
- (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ if (addr != 0 && addr != ipmi_main_intf->my_addr) {
+ if (ipmi_main_intf->set_my_addr) {
+ /*
+ * Some interfaces need special handling
+ * when changing local address
+ */
+ (void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
+ }
+
+ /* set local address */
+ ipmi_main_intf->my_addr = addr;
}
+ ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
+
/* If bridging addresses are specified, handle them */
- if (target_addr > 0) {
- ipmi_main_intf->target_addr = target_addr;
- ipmi_main_intf->target_lun = target_lun ;
- ipmi_main_intf->target_channel = target_channel ;
- }
- if (transit_addr > 0) {
+ if (transit_addr > 0 || target_addr > 0) {
/* sanity check, transit makes no sense without a target */
if ((transit_addr != 0 || transit_channel != 0) &&
- ipmi_main_intf->target_addr == 0) {
+ target_addr == 0) {
lprintf(LOG_ERR,
"Transit address/channel %#x/%#x ignored. "
"Target address must be specified!",
transit_addr, transit_channel);
goto out_free;
}
+ ipmi_main_intf->target_addr = target_addr;
+ ipmi_main_intf->target_channel = target_channel ;
ipmi_main_intf->transit_addr = transit_addr;
ipmi_main_intf->transit_channel = transit_channel;
- }
- if (ipmi_main_intf->target_addr > 0) {
+
+
/* must be admin level to do this over lan */
ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
/* Get the ipmb address of the targeted entity */
ipmi_main_intf->target_ipmb_addr =
- ipmi_picmg_ipmb_address(ipmi_main_intf);
+ ipmi_acquire_ipmb_address(ipmi_main_intf);
lprintf(LOG_DEBUG, "Specified addressing Target %#x:%#x Transit %#x:%#x",
ipmi_main_intf->target_addr,
ipmi_main_intf->target_channel,
@@ -962,6 +986,9 @@ ipmi_main(int argc, char ** argv,
}
}
+ /* set target LUN (for RAW command) */
+ ipmi_main_intf->target_lun = target_lun ;
+
lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
"transit %#x:%#x target %#x:%#x "
"ipmb_target %#x\n",
diff --git a/lib/ipmi_picmg.c b/lib/ipmi_picmg.c
index d1c82b2..1f3849d 100644
--- a/lib/ipmi_picmg.c
+++ b/lib/ipmi_picmg.c
@@ -2335,37 +2335,36 @@ picmg_discover(struct ipmi_intf *intf) {
struct ipmi_rq req;
struct ipmi_rs *rsp;
char msg_data;
+ uint8_t picmg_avail = 0;
- if (intf->picmg_avail == 0) {
- memset(&req, 0, sizeof(req));
- req.msg.netfn = IPMI_NETFN_PICMG;
- req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
- msg_data = 0x00;
- req.msg.data = &msg_data;
- req.msg.data_len = 1;
- msg_data = 0;
-
- lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
- intf->my_addr, intf->transit_addr, intf->target_addr);
- rsp = intf->sendrecv(intf, &req);
- if (rsp && !rsp->ccode) {
- if ( (rsp->data[0] == 0) &&
- ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
- || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
- intf->picmg_avail = 1;
- lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
- (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
- }
- } else {
- if (rsp == NULL) {
- lprintf(LOG_INFO,"No Response from Get PICMG Properties");
- } else {
- lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
- }
- }
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = PICMG_GET_PICMG_PROPERTIES_CMD;
+ msg_data = 0x00;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = 0;
+
+ lprintf(LOG_INFO, "Running Get PICMG Properties my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if ( (rsp->data[0] == 0) &&
+ ((rsp->data[1] & 0x0F) == PICMG_ATCA_MAJOR_VERSION
+ || (rsp->data[1] & 0x0F) == PICMG_AMC_MAJOR_VERSION) ) {
+ picmg_avail = 1;
+ lprintf(LOG_INFO, "Discovered PICMG Extension %d.%d",
+ (rsp->data[1] & 0x0f), (rsp->data[1] >> 4));
+ }
+ } else if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get PICMG Properties");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get PICMG Properities", rsp->ccode);
}
- if (intf->picmg_avail == 0) {
+
+ if (picmg_avail == 0) {
lprintf(LOG_INFO, "No PICMG Extenstion discovered");
}
- return intf->picmg_avail;
+
+ return picmg_avail;
}
diff --git a/lib/ipmi_vita.c b/lib/ipmi_vita.c
new file mode 100644
index 0000000..261759e
--- /dev/null
+++ b/lib/ipmi_vita.c
@@ -0,0 +1,777 @@
+/*
+ Copyright (c) Pigeon Point Systems. All right 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 Pigeon Point Systems, or the names of
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * This software is provided "AS IS," without a warranty of any kind.
+ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
+ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
+ * PIGEON POINT SYSTEMS ("PPS") AND ITS LICENSORS SHALL NOT BE LIABLE
+ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
+ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
+ * PPS OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
+ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
+ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
+ * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
+ * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ */
+
+
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_picmg.h>
+#include <ipmitool/ipmi_vita.h>
+#include <ipmitool/ipmi_fru.h> /* for access to link descriptor defines */
+#include <ipmitool/ipmi_strings.h>
+#include <ipmitool/log.h>
+
+/* check if VITA 46.11 is supported */
+uint8_t
+vita_discover(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+ int vita_avail = 0;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = GROUP_EXT_VITA;
+
+ lprintf(LOG_INFO, "Running Get VSO Capabilities my_addr %#x, transit %#x, target %#x",
+ intf->my_addr, intf->transit_addr, intf->target_addr);
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ if (rsp->data[0] == GROUP_EXT_VITA && (rsp->data[3] & 0x03) == 0) {
+ vita_avail = 1;
+ lprintf(LOG_INFO, "Discovered VITA 46.11 (Supported spec. rev. %d.%d)",
+ (rsp->data[4] & 0x0F), (rsp->data[4] >> 4));
+ }
+ } else if (rsp == NULL) {
+ lprintf(LOG_INFO,"No Response from Get VSO Capabilities");
+ } else {
+ lprintf(LOG_INFO,"Error Response %#x from Get VSO Capabilities", rsp->ccode);
+ }
+
+ if (vita_avail == 0) {
+ lprintf(LOG_INFO, "No VITA support discovered");
+ }
+
+ return vita_avail;
+}
+
+uint8_t
+ipmi_vita_ipmb_address(struct ipmi_intf *intf)
+{
+ struct ipmi_rq req;
+ struct ipmi_rs *rsp;
+ char msg_data;
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+ msg_data = GROUP_EXT_VITA;
+
+ rsp = intf->sendrecv(intf, &req);
+ if (rsp && !rsp->ccode) {
+ return rsp->data[2];
+ }
+ if (rsp) {
+ lprintf(LOG_DEBUG, "Get Address Info failed: %#x %s",
+ rsp->ccode, val2str(rsp->ccode, completion_code_vals));
+ } else {
+ lprintf(LOG_DEBUG, "Get Address Info failed: No Response");
+ }
+ return 0;
+}
+
+
+void
+ipmi_vita_help (void)
+{
+ lprintf(LOG_NOTICE, "VITA commands:");
+ lprintf(LOG_NOTICE, " properties - get VSO properties");
+ lprintf(LOG_NOTICE, " frucontrol - FRU control");
+ lprintf(LOG_NOTICE, " addrinfo - get address information");
+ lprintf(LOG_NOTICE, " activate - activate a FRU");
+ lprintf(LOG_NOTICE, " deactivate - deactivate a FRU");
+ lprintf(LOG_NOTICE, " policy get - get the FRU activation policy");
+ lprintf(LOG_NOTICE, " policy set - set the FRU activation policy");
+ lprintf(LOG_NOTICE, " led prop - get led properties");
+ lprintf(LOG_NOTICE, " led cap - get led color capabilities");
+ lprintf(LOG_NOTICE, " led get - get led state");
+ lprintf(LOG_NOTICE, " led set - set led state");
+}
+
+int
+ipmi_vita_getaddr(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_ADDRESS_INFO_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = 0; /* default fru id */
+
+ if(argc > 0) {
+ msg_data[1] = strtoul(argv[0], NULL,0); /* FRU ID */
+ }
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("Get FRU Address Info: no response\n");
+ return -1;
+ };
+
+ if (rsp->ccode) {
+ printf("Get FRU Address Info: invalid CC(0x%02x)\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("Hardware Address : 0x%02x\n", rsp->data[1]);
+ printf("IPMB-0 Address : 0x%02x\n", rsp->data[2]);
+ printf("FRU ID : 0x%02x\n", rsp->data[4]);
+ printf("Site ID : 0x%02x\n", rsp->data[5]);
+
+ printf("Site Type : (0x%02x) ", rsp->data[6]);
+ switch (rsp->data[6]) {
+ case VITA_FRONT_VPX_MODULE:
+ printf("Front Loading VPX Plug-In Module\n");
+ break;
+ case VITA_POWER_ENTRY:
+ printf("Power Entry Module\n");
+ break;
+ case VITA_CHASSIS_FRU:
+ printf("Chassic FRU Information Module\n");
+ break;
+ case VITA_DEDICATED_CHMC:
+ printf("Dedicated Chassis Manager\n");
+ break;
+ case VITA_FAN_TRAY:
+ printf("Fan Tray\n");
+ break;
+ case VITA_FAN_TRAY_FILTER:
+ printf("Fan Tray Filter\n");
+ break;
+ case VITA_ALARM_PANEL:
+ printf("Alarm Panel\n");
+ break;
+ case VITA_XMC:
+ printf("XMC\n");
+ break;
+ case VITA_VPX_RTM:
+ printf("VPX Rear Transition Module\n");
+ break;
+ case VITA_FRONT_VME_MODULE:
+ printf("Front Loading VME Plug-In Module\n");
+ break;
+ case VITA_FRONT_VXS_MODULE:
+ printf("Front Loading VXS Plug-In Module\n");
+ break;
+ case VITA_POWER_SUPPLY:
+ printf("Power Supply\n");
+ break;
+ case VITA_FRONT_VITA62_MODULE:
+ printf("Front Loading VITA 62 Module\n");
+ break;
+ case VITA_71_MODULE:
+ printf("VITA 71 Module\n");
+ break;
+ case VITA_FMC:
+ printf("FMC\n");
+ break;
+ default:
+ if (rsp->data[6] >= 0xc0 && rsp->data[6] <= 0xcf) {
+ printf("OEM\n");
+ } else {
+ printf("unknown\n");
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_vso_capabilities(struct ipmi_intf * intf)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data, tmp;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_VSO_CAPABILITIES_CMD;
+ req.msg.data = &msg_data;
+ req.msg.data_len = 1;
+
+ msg_data = GROUP_EXT_VITA; /* VITA identifier */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("Get VSO Capabilities: no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("Get VSO Capabilities: invalid CC(0x%02x)\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("VSO Identifier : 0x%02x\n", rsp->data[0]);
+ printf("IPMC Identifier : 0x%02x\n", rsp->data[1]);
+ printf(" Tier %d\n", (rsp->data[1] & 0x03) + 1);
+ printf(" Layer %d\n", ((rsp->data[1] & 0x30) >> 4) + 1);
+
+ printf("IPMB Capabilities : 0x%02x\n", rsp->data[2]);
+
+ tmp = (rsp->data[2] & 0x30) >> 4;
+
+ printf(" Frequency %skHz\n",
+ tmp == 0 ? "100" : tmp == 1 ? "400" : "RESERVED");
+
+ tmp = rsp->data[2] & 3;
+
+ if (tmp == 1) {
+ printf(" 2 IPMB interfaces supported\n");
+ } else if (tmp == 0) {
+ printf(" 1 IPMB interface supported\n");
+ }
+
+ printf("VSO Standard : %s\n",
+ (rsp->data[3] & 0x3) == 0 ? "VITA 46.11" : "RESERVED" );
+
+ printf("VSO Spec Revision : %d.%d\n", rsp->data[4] & 0xf,
+ rsp->data[4] >> 4);
+
+ printf("Max FRU Device ID : 0x%02x\n", rsp->data[5]);
+ printf("FRU Device ID : 0x%02x\n", rsp->data[6]);
+
+ return 0;
+}
+
+int
+ipmi_vita_set_fru_activation(struct ipmi_intf * intf, int argc, char ** argv, unsigned char state)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_ACTIVATION_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+ msg_data[2] = state; /* command */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU has been successfully %s\n",
+ state ? "activated" : "deactivated");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_fru_state_policy_bits(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("FRU State Policy Bits: %xh\n", rsp->data[1]);
+ printf(" Default-Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x08 ? 1 : 0);
+ printf(" Commanded-Deactivation-Ingored Policy Bit is %d\n",
+ rsp->data[1] & 0x04 ? 1 : 0);
+ printf(" Deactivation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x02 ? 1 : 0);
+ printf(" Activation-Locked Policy Bit is %d\n",
+ rsp->data[1] & 0x01);
+
+ return 0;
+}
+
+int
+ipmi_vita_set_fru_state_policy_bits(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[4];
+
+ memset(&req, 0, sizeof(req));
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_STATE_POLICY_BITS_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 4;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* bits mask */
+ msg_data[3] = strtol(argv[2], NULL, 0); /* bits */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU state policy bits have been updated\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_properties(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[2];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_PROPERTIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 2;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("General Status LED Properties: 0x%02x\n", rsp->data[1] );
+ printf("App. Specific LED Count: 0x%02x\n", rsp->data[2] );
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_color_capabilities(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+ int i;
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_LED_COLOR_CAPABILITIES_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("LED Color Capabilities: ");
+ for (i = 0; i < 8; i++) {
+ if (rsp->data[1] & (0x01 << i)) {
+ printf("%s, ", led_color_str[i]);
+ }
+ }
+ printf("\n");
+
+ printf("Default LED Color in\n");
+ printf(" LOCAL control: %s\n", led_color_str[ rsp->data[2] ] );
+ printf(" OVERRIDE state: %s\n", led_color_str[ rsp->data[3] ] );
+
+ if (rsp->data_len == 5) {
+ printf("LED flags:\n");
+ if (rsp->data[4] & 2) {
+ printf(" [HW RESTRICT]\n");
+ }
+ if (rsp->data[4] & 1) {
+ printf(" [PAYLOAD PWR]\n");
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_get_led_state(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_GET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ }
+
+ printf("LED states: %x\t", rsp->data[1] );
+ if (rsp->data[1] & 0x1) {
+ printf("[LOCAL CONTROL] ");
+ }
+ if (rsp->data[1] & 0x2) {
+ printf("[OVERRIDE] ");
+ }
+ if (rsp->data[1] & 0x4) {
+ printf("[LAMPTEST] ");
+ }
+ if (rsp->data[1] & 0x8) {
+ printf("[HW RESTRICT] ");
+ }
+
+ puts("\n");
+
+ if (rsp->data[1] & 1) {
+ printf(" Local Control function: %x\t", rsp->data[2] );
+ if (rsp->data[2] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[2] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Local Control On-Duration: %x\n", rsp->data[3] );
+ printf(" Local Control Color: %x\t[%s]\n",
+ rsp->data[4], led_color_str[rsp->data[4] & 7]);
+ }
+
+ /* override state or lamp test */
+ if (rsp->data[1] & 0x06) {
+ printf(" Override function: %x\t", rsp->data[5] );
+ if (rsp->data[5] == 0x0) {
+ printf("[OFF]\n");
+ } else if (rsp->data[5] == 0xff) {
+ printf("[ON]\n");
+ } else {
+ printf("[BLINKING]\n");
+ }
+ printf(" Override On-Duration: %x\n", rsp->data[6] );
+ printf(" Override Color: %x\t[%s]\n",
+ rsp->data[7], led_color_str[rsp->data[7] & 7]);
+ if (rsp->data[1] == 0x04) {
+ printf(" Lamp test duration: %x\n", rsp->data[8] );
+ }
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_set_led_state(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[6];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_SET_FRU_LED_STATE_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 6;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* LED-ID */
+ msg_data[3] = strtol(argv[2], NULL, 0); /* LED function */
+ msg_data[4] = strtol(argv[3], NULL, 0); /* LED on duration */
+ msg_data[5] = strtol(argv[4], NULL, 0); /* LED color */
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("FRU LED state has been updated\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_fru_control(struct ipmi_intf * intf, int argc, char ** argv)
+{
+ struct ipmi_rs * rsp;
+ struct ipmi_rq req;
+ unsigned char msg_data[3];
+
+ memset(&req, 0, sizeof(req));
+
+ req.msg.netfn = IPMI_NETFN_PICMG;
+ req.msg.cmd = VITA_FRU_CONTROL_CMD;
+ req.msg.data = msg_data;
+ req.msg.data_len = 3;
+
+ msg_data[0] = GROUP_EXT_VITA; /* VITA identifier */
+ msg_data[1] = strtol(argv[0], NULL, 0); /* FRU-ID */
+ msg_data[2] = strtol(argv[1], NULL, 0); /* control option */
+
+ printf("FRU Device Id: %d FRU Control Option: %s\n", msg_data[1],
+ val2str( msg_data[2], picmg_frucontrol_vals));
+
+ rsp = intf->sendrecv(intf, &req);
+
+ if (!rsp) {
+ printf("frucontrol: no response\n");
+ return -1;
+ }
+
+ if (rsp->ccode) {
+ printf("frucontrol: returned CC code 0x%02x\n", rsp->ccode);
+ return -1;
+ } else {
+ printf("frucontrol: ok\n");
+ }
+
+ return 0;
+}
+
+int
+ipmi_vita_main (struct ipmi_intf * intf, int argc, char ** argv)
+{
+ int rc = 0;
+ int showProperties = 0;
+
+ if (argc == 0 || (!strncmp(argv[0], "help", 4))) {
+ ipmi_vita_help();
+ return 0;
+ }
+
+ /* Get VSO Properties is called to obtain version information */
+ if (!strncmp(argv[0], "properties", 10)) {
+ rc = ipmi_vita_get_vso_capabilities(intf);
+ /* Get FRU Address Info command */
+ } else if (!strncmp(argv[0], "addrinfo", 8)) {
+ rc = ipmi_vita_getaddr(intf, argc-1, &argv[1]);
+ /* FRU Control command */
+ } else if (!strncmp(argv[0], "frucontrol", 10)) {
+ if (argc > 2) {
+ rc = ipmi_vita_fru_control(intf, argc-1, &(argv[1]));
+ } else {
+ printf("usage: frucontrol <FRU-ID> <OPTION>\n");
+ printf(" OPTION:\n");
+ printf(" 0 - Cold Reset\n");
+ printf(" 1 - Warm Reset\n");
+ printf(" 2 - Graceful Reboot\n");
+ printf(" 3 - Issue Diagnostic Interrupt\n");
+ printf(" 4-255 - Reserved\n");
+ rc = -1;
+ }
+ /* Set FRU Activation (activate) command */
+ } else if (!strncmp(argv[0], "activate", 8)) {
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, argc-1, &(argv[1]), 1);
+ } else {
+ printf("specify the FRU to activate\n");
+ rc = -1;
+ }
+ /* Set FRU Activation (deactivate) command */
+ } else if (!strncmp(argv[0], "deactivate", 10)) {
+ if (argc > 1) {
+ rc = ipmi_vita_set_fru_activation(intf, argc-1, &(argv[1]), 0);
+ } else {
+ printf("specify the FRU to deactivate\n");
+ rc = -1;
+ }
+ /* FRU State Policy Bits commands */
+ } else if (!strncmp(argv[0], "policy", 6)) {
+ if (argc > 1) {
+ if (!strncmp(argv[1], "get", 3)) {
+ if (argc > 2) {
+ rc = ipmi_vita_get_fru_state_policy_bits(intf, argc-1, &(argv[2]));
+ } else {
+ printf("usage: get <fruid>\n");
+ }
+ } else if (!strncmp(argv[1], "set", 3)) {
+ if (argc > 4) {
+ rc = ipmi_vita_set_fru_state_policy_bits(intf, argc-1, &(argv[2]));
+ } else {
+ printf("usage: set <fruid> <mask> <value>\n");
+ printf(" mask: [3] affect the Default-Activation-Locked Policy Bit\n");
+ printf(" [2] affect the Commanded-Deactivation-Ignored Policy Bit\n");
+ printf(" [1] affect the Deactivation-Locked Policy Bit\n");
+ printf(" [0] affect the Activation-Locked Policy Bit\n");
+ printf(" value: [3] value for the Default-Activation-Locked Policy Bit\n");
+ printf(" [2] value for the Commanded-Deactivation-Ignored Policy Bit\n");
+ printf(" [1] value for the Deactivation-Locked Policy Bit\n");
+ printf(" [0] value for the Activation-Locked Policy Bit\n");
+ }
+ } else {
+ printf("usage: policy get | policy set\n");
+ rc = -1;
+ }
+ } else {
+ printf("usage: policy get | policy set\n");
+ rc = -1;
+ }
+ /* FRU LED commands */
+ } else if (!strncmp(argv[0], "led", 3)) {
+ if (argc > 1) {
+ if (!strncmp(argv[1], "prop", 4)) {
+ if (argc > 2) {
+ rc = ipmi_vita_get_led_properties(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led prop <FRU-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "cap", 3)) {
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_color_capabilities(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led cap <FRU-ID> <LED-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "get", 3)) {
+ if (argc > 3) {
+ rc = ipmi_vita_get_led_state(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led get <FRU-ID> <LED-ID>\n");
+ }
+ } else if (!strncmp(argv[1], "set", 3)) {
+ if (argc > 6) {
+ rc = ipmi_vita_set_led_state(intf, argc-1, &(argv[2]));
+ } else {
+ printf("led set <FRU-ID> <LED-ID> <function> <duration> <color>\n");
+ printf(" <FRU-ID>\n");
+ printf(" <LED-ID> 0-0xFE: Specified LED\n");
+ printf(" 0xFF: All LEDs under management control\n");
+ printf(" <function> 0: LED OFF override\n");
+ printf(" 1 - 250: LED blinking override (off duration)\n");
+ printf(" 251: LED Lamp Test\n");
+ printf(" 252: LED restore to local control\n");
+ printf(" 255: LED ON override\n");
+ printf(" <duration> 1 - 127: LED Lamp Test / on duration\n");
+ printf(" <color> 0: reserved\n");
+ printf(" 1: BLUE\n");
+ printf(" 2: RED\n");
+ printf(" 3: GREEN\n");
+ printf(" 4: AMBER\n");
+ printf(" 5: ORANGE\n");
+ printf(" 6: WHITE\n");
+ printf(" 7: reserved\n");
+ printf(" 0xE: do not change\n");
+ printf(" 0xF: use default color\n");
+ }
+ } else {
+ printf("prop | cap | get | set\n");
+ }
+ }
+ } else {
+ ipmi_vita_help();
+ rc = -1;
+ }
+
+ return rc;
+}
diff --git a/src/ipmitool.c b/src/ipmitool.c
index 6230e5c..49ec8f6 100644
--- a/src/ipmitool.c
+++ b/src/ipmitool.c
@@ -65,6 +65,7 @@
#include <ipmitool/ipmi_ekanalyzer.h>
#include <ipmitool/ipmi_ime.h>
#include <ipmitool/ipmi_dcmi.h>
+#include <ipmitool/ipmi_vita.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
@@ -119,6 +120,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = {
{ ipmi_hpmfwupg_main,"hpm", "Update HPM components using PICMG HPM.1 file"},
{ ipmi_ekanalyzer_main,"ekanalyzer", "run FRU-Ekeying analyzer using FRU files"},
{ ipmi_ime_main, "ime", "Update Intel Manageability Engine Firmware"},
+ { ipmi_vita_main, "vita", "Run a VITA 46.11 extended cmd"},
{ NULL },
};
diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c
index 5f4b926..a0ac875 100644
--- a/src/plugins/serial/serial_basic.c
+++ b/src/plugins/serial/serial_basic.c
@@ -1008,13 +1008,6 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)
return NULL;
}
-int
-serial_bm_set_my_addr(struct ipmi_intf * intf, uint8_t addr)
-{
- intf->my_addr = addr;
- return 0;
-}
-
/*
* Serial BM interface
*/
@@ -1025,5 +1018,4 @@ struct ipmi_intf ipmi_serial_bm_intf = {
open: serial_bm_open,
close: serial_bm_close,
sendrecv: serial_bm_send_request,
- set_my_addr:serial_bm_set_my_addr
};
diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c
index 41d3753..e4f8935 100644
--- a/src/plugins/serial/serial_terminal.c
+++ b/src/plugins/serial/serial_terminal.c
@@ -898,13 +898,7 @@ ipmi_serial_term_setup(struct ipmi_intf * intf)
/* setup default LAN maximum request and response sizes */
intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;
intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE;
- return 0;
-}
-int
-ipmi_serial_term_set_my_addr(struct ipmi_intf * intf, uint8_t addr)
-{
- intf->my_addr = addr;
return 0;
}
@@ -915,5 +909,4 @@ struct ipmi_intf ipmi_serial_term_intf = {
open: ipmi_serial_term_open,
close: ipmi_serial_term_close,
sendrecv: ipmi_serial_term_send_cmd,
- set_my_addr:ipmi_serial_term_set_my_addr
};
--------------070703040500050105010503--