/*****************************************************************************\
* $Id: ipmipower_packet.c,v 1.127 2010-06-11 16:29:34 chu11 Exp $
*****************************************************************************
* Copyright (C) 2007-2015 Lawrence Livermore National Security, LLC.
* Copyright (C) 2003-2007 The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Albert Chu <chu11@llnl.gov>
* UCRL-CODE-155698
*
* This file is part of Ipmipower, a remote power control utility.
* For details, see http://www.llnl.gov/linux/.
*
* Ipmipower is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* Ipmipower is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with Ipmipower. If not, see <http://www.gnu.org/licenses/>.
\*****************************************************************************/
#if HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#if STDC_HEADERS
#include <string.h>
#endif /* STDC_HEADERS */
#if HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#include <errno.h>
#include <assert.h>
#include <stdint.h>
#include "ipmipower_packet.h"
#include "ipmipower_error.h"
#include "ipmipower_oem.h"
#include "ipmipower_util.h"
#include "freeipmi-portability.h"
#include "debug-util.h"
extern struct ipmipower_arguments cmd_args;
fiid_field_t *
ipmipower_packet_cmd_template (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
{
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
switch (pkt)
{
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
return (&tmpl_cmd_get_channel_authentication_capabilities_rq[0]);
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
return (&tmpl_cmd_get_channel_authentication_capabilities_rs[0]);
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
return (&tmpl_cmd_get_session_challenge_rq[0]);
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
return (&tmpl_cmd_get_session_challenge_rs[0]);
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
return (&tmpl_cmd_activate_session_rq[0]);
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
return (&tmpl_cmd_activate_session_rs[0]);
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
return (&tmpl_rmcpplus_open_session_request[0]);
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
return (&tmpl_rmcpplus_open_session_response[0]);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
return (&tmpl_rmcpplus_rakp_message_1[0]);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
return (&tmpl_rmcpplus_rakp_message_2[0]);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
return (&tmpl_rmcpplus_rakp_message_3[0]);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
return (&tmpl_rmcpplus_rakp_message_4[0]);
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
return (&tmpl_cmd_set_session_privilege_level_rq[0]);
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
return (&tmpl_cmd_set_session_privilege_level_rs[0]);
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
return (&tmpl_cmd_get_chassis_status_rq[0]);
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
return (&tmpl_cmd_get_chassis_status_rs[0]);
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
return (&tmpl_cmd_chassis_control_rq[0]);
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
return (&tmpl_cmd_chassis_control_rs[0]);
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
return (&tmpl_cmd_chassis_identify_rq[0]);
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
return (&tmpl_cmd_chassis_identify_rs[0]);
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
return (&tmpl_cmd_get_sensor_reading_rq[0]);
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
return (&tmpl_cmd_get_sensor_reading_rs[0]);
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
return (&tmpl_cmd_c410x_slot_power_control_rq[0]);
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
return (&tmpl_cmd_c410x_slot_power_control_rs[0]);
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
return (&tmpl_cmd_close_session_rq[0]);
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
return (&tmpl_cmd_close_session_rs[0]);
default:
IPMIPOWER_ERROR (("ipmipower_packet_cmd_template: invalid packet type: %d", pkt));
exit (EXIT_FAILURE);
}
return (NULL); /* NOT REACHED */
}
fiid_obj_t
ipmipower_packet_cmd_obj (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
{
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
switch (pkt)
{
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
return (ip->obj_authentication_capabilities_rq);
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
return (ip->obj_authentication_capabilities_rs);
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
return (ip->obj_get_session_challenge_rq);
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
return (ip->obj_get_session_challenge_rs);
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
return (ip->obj_activate_session_rq);
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
return (ip->obj_activate_session_rs);
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
return (ip->obj_open_session_rq);
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
return (ip->obj_open_session_rs);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
return (ip->obj_rakp_message_1_rq);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
return (ip->obj_rakp_message_2_rs);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
return (ip->obj_rakp_message_3_rq);
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
return (ip->obj_rakp_message_4_rs);
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
return (ip->obj_set_session_privilege_level_rq);
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
return (ip->obj_set_session_privilege_level_rs);
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
return (ip->obj_get_chassis_status_rq);
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
return (ip->obj_get_chassis_status_rs);
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
return (ip->obj_chassis_control_rq);
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
return (ip->obj_chassis_control_rs);
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
return (ip->obj_chassis_identify_rq);
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
return (ip->obj_chassis_identify_rs);
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
return (ip->obj_c410x_get_sensor_reading_rq);
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
return (ip->obj_c410x_get_sensor_reading_rs);
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
return (ip->obj_c410x_slot_power_control_rq);
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
return (ip->obj_c410x_slot_power_control_rs);
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
return (ip->obj_close_session_rq);
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
return (ip->obj_close_session_rs);
default:
IPMIPOWER_ERROR (("ipmipower_packet_cmd_obj: invalid packet type: %d", pkt));
exit (EXIT_FAILURE);
}
return (NULL); /* NOT REACHED */
}
void
ipmipower_packet_dump (ipmipower_powercmd_t ip,
ipmipower_packet_type_t pkt,
const void *buf,
unsigned int buflen)
{
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_VALID (pkt));
assert (buf);
if (cmd_args.common_args.debug)
{
fiid_field_t *tmpl_lan_msg_hdr;
char hdrbuf[DEBUG_UTIL_HDR_BUFLEN + 1];
uint8_t packet_type;
uint8_t packet_direction;
const char *str_cmd = NULL;
if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
packet_type = DEBUG_UTIL_TYPE_IPMI_1_5;
else
packet_type = DEBUG_UTIL_TYPE_IPMI_2_0;
switch (pkt)
{
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ:
case IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_CHANNEL_AUTHENTICATION_CAPABILITIES);
break;
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ:
case IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_GET_SESSION_CHALLENGE);
break;
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ:
case IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_ACTIVATE_SESSION);
break;
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST:
case IPMIPOWER_PACKET_TYPE_OPEN_SESSION_RESPONSE:
str_cmd = DEBUG_UTIL_OPEN_SESSION_STR;
break;
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1:
str_cmd = DEBUG_UTIL_RAKP_1_STR;
break;
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_2:
str_cmd = DEBUG_UTIL_RAKP_2_STR;
break;
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3:
str_cmd = DEBUG_UTIL_RAKP_3_STR;
break;
case IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_4:
str_cmd = DEBUG_UTIL_RAKP_4_STR;
break;
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ:
case IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_SET_SESSION_PRIVILEGE_LEVEL);
break;
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ:
case IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_GET_CHASSIS_STATUS);
break;
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ:
case IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_CHASSIS_CONTROL);
break;
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ:
case IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_CHASSIS_RQ, IPMI_CMD_CHASSIS_IDENTIFY);
break;
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ:
case IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_SENSOR_EVENT_RQ, IPMI_CMD_GET_SENSOR_READING);
break;
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ:
case IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RS:
str_cmd = "C410x Slot Power Control";
break;
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ:
case IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RS:
str_cmd = ipmi_cmd_str (IPMI_NET_FN_APP_RQ, IPMI_CMD_CLOSE_SESSION);
break;
default:
IPMIPOWER_ERROR (("ipmipower_packet_dump: invalid packet type: %d", pkt));
exit (EXIT_FAILURE);
}
if (IPMIPOWER_PACKET_TYPE_RQ (pkt))
packet_direction = DEBUG_UTIL_DIRECTION_REQUEST;
else
packet_direction = DEBUG_UTIL_DIRECTION_RESPONSE;
memset (hdrbuf, '\0', DEBUG_UTIL_HDR_BUFLEN + 1);
debug_hdr_str (packet_type,
packet_direction,
DEBUG_UTIL_FLAGS_DEFAULT,
str_cmd,
hdrbuf,
DEBUG_UTIL_HDR_BUFLEN);
if (IPMIPOWER_PACKET_TYPE_RQ (pkt))
tmpl_lan_msg_hdr = &tmpl_lan_msg_hdr_rq[0];
else
tmpl_lan_msg_hdr = &tmpl_lan_msg_hdr_rs[0];
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP (pkt))
{
if (ipmi_dump_rmcpplus_packet (STDERR_FILENO,
ip->ic->hostname,
hdrbuf,
NULL,
IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE,
IPMI_INTEGRITY_ALGORITHM_NONE,
IPMI_CONFIDENTIALITY_ALGORITHM_NONE,
NULL,
0,
NULL,
0,
buf,
buflen,
tmpl_lan_msg_hdr,
ipmipower_packet_cmd_template (ip, pkt)) < 0)
{
IPMIPOWER_ERROR (("ipmi_dump_rmcpplus_packet: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET (pkt))
{
if (ipmi_dump_rmcpplus_packet (STDERR_FILENO,
ip->ic->hostname,
hdrbuf,
NULL,
ip->authentication_algorithm,
ip->integrity_algorithm,
ip->confidentiality_algorithm,
ip->integrity_key_ptr,
ip->integrity_key_len,
ip->confidentiality_key_ptr,
ip->confidentiality_key_len,
buf,
buflen,
tmpl_lan_msg_hdr,
ipmipower_packet_cmd_template (ip, pkt)) < 0)
{
IPMIPOWER_ERROR (("ipmi_dump_rmcpplus_packet: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
else /* cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET (pkt))
*/
{
if (ipmi_dump_lan_packet (STDERR_FILENO,
ip->ic->hostname,
hdrbuf,
NULL,
buf,
buflen,
tmpl_lan_msg_hdr,
ipmipower_packet_cmd_template (ip, pkt)) < 0)
{
IPMIPOWER_ERROR (("ipmi_dump_lan_packet: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
}
}
int
ipmipower_packet_store (ipmipower_powercmd_t ip,
ipmipower_packet_type_t pkt,
const void *buf,
unsigned int buflen)
{
fiid_obj_t obj;
int rv = -1;
assert (ip);
assert (buf);
assert (buflen);
assert (IPMIPOWER_PACKET_TYPE_RS (pkt));
obj = ipmipower_packet_cmd_obj (ip, pkt);
if (IPMIPOWER_PACKET_TYPE_IPMI_1_5_SETUP_RS (pkt)
|| cmd_args.common_args.driver_type == IPMI_DEVICE_LAN)
{
if ((rv = unassemble_ipmi_lan_pkt (buf,
buflen,
ip->obj_rmcp_hdr_rs,
ip->obj_lan_session_hdr_rs,
ip->obj_lan_msg_hdr_rs,
obj,
ip->obj_lan_msg_trlr_rs,
IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
{
IPMIPOWER_ERROR (("unassemble_ipmi_lan_pkt: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
else
{
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RS (pkt))
{
if ((rv = unassemble_ipmi_rmcpplus_pkt (IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE,
IPMI_INTEGRITY_ALGORITHM_NONE,
IPMI_CONFIDENTIALITY_ALGORITHM_NONE,
NULL,
0,
NULL,
0,
buf,
buflen,
ip->obj_rmcp_hdr_rs,
ip->obj_rmcpplus_session_hdr_rs,
ip->obj_rmcpplus_payload_rs,
ip->obj_lan_msg_hdr_rs,
obj,
ip->obj_lan_msg_trlr_rs,
ip->obj_rmcpplus_session_trlr_rs,
IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
{
IPMIPOWER_ERROR (("unassemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
else
{
if ((rv = unassemble_ipmi_rmcpplus_pkt (ip->authentication_algorithm,
ip->integrity_algorithm,
ip->confidentiality_algorithm,
ip->integrity_key_ptr,
ip->integrity_key_len,
ip->confidentiality_key_ptr,
ip->confidentiality_key_len,
buf,
buflen,
ip->obj_rmcp_hdr_rs,
ip->obj_rmcpplus_session_hdr_rs,
ip->obj_rmcpplus_payload_rs,
ip->obj_lan_msg_hdr_rs,
obj,
ip->obj_lan_msg_trlr_rs,
ip->obj_rmcpplus_session_trlr_rs,
IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
{
IPMIPOWER_ERROR (("unassemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
}
}
return (rv);
}
static int
_ipmi_1_5_packet_create (ipmipower_powercmd_t ip,
ipmipower_packet_type_t pkt,
uint8_t authentication_type,
uint32_t inbound_sequence_number,
uint32_t session_id,
void *authentication_code_data,
unsigned int authentication_code_data_len,
uint8_t net_fn,
fiid_obj_t obj_cmd_rq,
void *buf,
unsigned int buflen)
{
int len;
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
assert (fiid_obj_valid (obj_cmd_rq));
assert (buf);
assert (buflen);
if (fill_rmcp_hdr_ipmi (ip->obj_rmcp_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_lan_session_hdr (authentication_type,
inbound_sequence_number,
session_id,
ip->obj_lan_session_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_lan_session_hdr: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC,
net_fn,
IPMI_BMC_IPMB_LUN_BMC,
(ip->ic->ipmi_requester_sequence_number_counter % (IPMI_LAN_REQUESTER_SEQUENCE_NUMBER_MAX + 1)),
ip->obj_lan_msg_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if ((len = assemble_ipmi_lan_pkt (ip->obj_rmcp_hdr_rq,
ip->obj_lan_session_hdr_rq,
ip->obj_lan_msg_hdr_rq,
obj_cmd_rq,
authentication_code_data,
authentication_code_data_len,
buf,
buflen,
IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
{
IPMIPOWER_ERROR (("assemble_ipmi_lan_pkt: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
return (len);
}
static int
_ipmi_2_0_packet_create (ipmipower_powercmd_t ip,
ipmipower_packet_type_t pkt,
uint8_t payload_type,
uint8_t payload_authenticated,
uint8_t payload_encrypted,
uint32_t session_id,
uint32_t session_sequence_number,
void *authentication_code_data,
unsigned int authentication_code_data_len,
uint8_t net_fn,
uint8_t authentication_algorithm,
uint8_t integrity_algorithm,
uint8_t confidentiality_algorithm,
void *integrity_key,
unsigned int integrity_key_len,
void *confidentiality_key,
unsigned int confidentiality_key_len,
fiid_obj_t obj_cmd_rq,
void *buf,
unsigned int buflen)
{
int len;
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
assert (fiid_obj_valid (obj_cmd_rq));
assert (buf);
assert (buflen);
if (fill_rmcp_hdr_ipmi (ip->obj_rmcp_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcp_hdr_ipmi: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_rmcpplus_session_hdr (payload_type,
payload_authenticated,
payload_encrypted,
0, /* oem_iana */
0, /* oem_payload_id */
session_id,
session_sequence_number,
ip->obj_rmcpplus_session_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcpplus_session_hdr: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_lan_msg_hdr (IPMI_SLAVE_ADDRESS_BMC,
net_fn,
IPMI_BMC_IPMB_LUN_BMC,
(ip->ic->ipmi_requester_sequence_number_counter % (IPMI_LAN_REQUESTER_SEQUENCE_NUMBER_MAX + 1)),
ip->obj_lan_msg_hdr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_lan_msg_hdr: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_rmcpplus_session_trlr (ip->obj_rmcpplus_session_trlr_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcpplus_session_trlr: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
if ((len = assemble_ipmi_rmcpplus_pkt (authentication_algorithm,
integrity_algorithm,
confidentiality_algorithm,
integrity_key,
integrity_key_len,
confidentiality_key,
confidentiality_key_len,
authentication_code_data,
authentication_code_data_len,
ip->obj_rmcp_hdr_rq,
ip->obj_rmcpplus_session_hdr_rq,
ip->obj_lan_msg_hdr_rq,
obj_cmd_rq,
ip->obj_rmcpplus_session_trlr_rq,
buf,
buflen,
IPMI_INTERFACE_FLAGS_DEFAULT)) < 0)
{
IPMIPOWER_ERROR (("assemble_ipmi_rmcpplus_pkt: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
return (len);
}
int
ipmipower_packet_create (ipmipower_powercmd_t ip,
ipmipower_packet_type_t pkt,
void *buf,
unsigned int buflen)
{
char *username = NULL;
char *password = NULL;
void *integrity_key = NULL;
void *confidentiality_key = NULL;
char username_buf[IPMI_MAX_USER_NAME_LENGTH+1];
unsigned int username_len;
uint32_t session_id, managed_system_session_id = 0;
uint32_t sequence_number = 0;
unsigned int integrity_key_len = 0;
unsigned int confidentiality_key_len = 0;
uint8_t authentication_type = 0;
uint8_t net_fn = 0;
uint8_t payload_authenticated = 0;
uint8_t payload_encrypted = 0;
uint8_t payload_type = 0;
uint8_t authentication_algorithm = 0;
uint8_t integrity_algorithm = 0;
uint8_t confidentiality_algorithm = 0;
fiid_obj_t obj_cmd_rq = NULL;
uint64_t val;
int rv = 0;
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_RQ (pkt));
assert (buf);
assert (buflen);
if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
|| pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
{
username = cmd_args.common_args.username;
/* IPMI Workaround (achu)
*
* Discovered on SE7520AF2 with Intel Server Management Module
* (Professional Edition)
*
* The username must be padded despite explicitly not being
* allowed. "No Null characters (00h) are allowed in the name".
* Table 13-11 in the IPMI 2.0 spec.
*/
if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
&& (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION))
{
memset (username_buf, '\0', IPMI_MAX_USER_NAME_LENGTH+1);
if (username)
strcpy (username_buf, username);
username = username_buf;
username_len = IPMI_MAX_USER_NAME_LENGTH;
}
else
username_len = (username) ? strlen (username) : 0;
}
else
{
username = NULL;
username_len = 0;
}
/* Calculate Password */
if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ
|| IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
|| IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
password = cmd_args.common_args.password;
else
password = NULL;
/* Calculate Session ID */
if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
{
if (FIID_OBJ_GET (ip->obj_get_session_challenge_rs,
"temp_session_id",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'temp_session_id': %s",
fiid_obj_errormsg (ip->obj_get_session_challenge_rs)));
exit (EXIT_FAILURE);
}
session_id = val;
}
else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
{
if (FIID_OBJ_GET (ip->obj_activate_session_rs,
"session_id",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'session_id': %s",
fiid_obj_errormsg (ip->obj_activate_session_rs)));
exit (EXIT_FAILURE);
}
session_id = val;
}
else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
{
if (FIID_OBJ_GET (ip->obj_open_session_rs,
"managed_system_session_id",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'managed_system_session_id': %s",
fiid_obj_errormsg (ip->obj_open_session_rs)));
exit (EXIT_FAILURE);
}
session_id = val;
}
else
session_id = 0;
/* Calculate Sequence Number */
if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
{
uint32_t initial_inbound_sequence_number;
if (FIID_OBJ_GET (ip->obj_activate_session_rs,
"initial_inbound_sequence_number",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'initial_inbound_sequence_number': %s",
fiid_obj_errormsg (ip->obj_activate_session_rs)));
exit (EXIT_FAILURE);
}
initial_inbound_sequence_number = val;
sequence_number = initial_inbound_sequence_number + ip->session_inbound_count;
}
else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
sequence_number = ip->session_sequence_number;
else
sequence_number = 0;
/* Calculate Network Function */
if (pkt == IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ)
net_fn = IPMI_NET_FN_CHASSIS_RQ;
else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ)
net_fn = IPMI_NET_FN_SENSOR_EVENT_RQ;
else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ)
net_fn = IPMI_NET_FN_OEM_DELL_GENERIC_RQ;
else /* pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ
|| pkt == IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ
*/
net_fn = IPMI_NET_FN_APP_RQ;
/* Calculate Authentication Type */
if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
authentication_type = cmd_args.common_args.authentication_type;
else if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt))
{
if (!ip->permsgauth_enabled)
authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
else
authentication_type = cmd_args.common_args.authentication_type;
if (authentication_type == IPMI_AUTHENTICATION_TYPE_NONE)
password = NULL;
}
else
authentication_type = IPMI_AUTHENTICATION_TYPE_NONE;
if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0)
{
/* Calculate Payload Type */
if (pkt == IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST)
payload_type = IPMI_PAYLOAD_TYPE_RMCPPLUS_OPEN_SESSION_REQUEST;
else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1)
payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_1;
else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
payload_type = IPMI_PAYLOAD_TYPE_RAKP_MESSAGE_3;
else
payload_type = IPMI_PAYLOAD_TYPE_IPMI;
/* achu: "session_id" above is for the session headers. This is
* for the RAKP session setup protocol. The values will be
* different.
*/
if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1
|| pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
{
if (FIID_OBJ_GET (ip->obj_open_session_rs,
"managed_system_session_id",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'managed_system_session_id': %s",
fiid_obj_errormsg (ip->obj_open_session_rs)));
exit (EXIT_FAILURE);
}
managed_system_session_id = val;
}
/* Setup authentication/integrity/confidentiality keys */
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt))
{
authentication_algorithm = IPMI_AUTHENTICATION_ALGORITHM_RAKP_NONE;
integrity_algorithm = IPMI_INTEGRITY_ALGORITHM_NONE;
confidentiality_algorithm = IPMI_CONFIDENTIALITY_ALGORITHM_NONE;
integrity_key = NULL;
integrity_key_len = 0;
confidentiality_key = NULL;
confidentiality_key_len = 0;
}
else /* IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt) */
{
authentication_algorithm = ip->authentication_algorithm;
integrity_algorithm = ip->integrity_algorithm;
confidentiality_algorithm = ip->confidentiality_algorithm;
integrity_key = ip->integrity_key_ptr;
integrity_key_len = ip->integrity_key_len;
confidentiality_key = ip->confidentiality_key_ptr;
confidentiality_key_len = ip->confidentiality_key_len;
}
/* Calculate Payload Authenticated */
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
|| integrity_algorithm == IPMI_INTEGRITY_ALGORITHM_NONE)
payload_authenticated = IPMI_PAYLOAD_FLAG_UNAUTHENTICATED;
else
payload_authenticated = IPMI_PAYLOAD_FLAG_AUTHENTICATED;
/* Calculate Payload Encrypted */
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
|| confidentiality_algorithm == IPMI_CONFIDENTIALITY_ALGORITHM_NONE)
payload_encrypted = IPMI_PAYLOAD_FLAG_UNENCRYPTED;
else
payload_encrypted = IPMI_PAYLOAD_FLAG_ENCRYPTED;
}
/* Calculate/Fill Command Object */
if (pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RQ)
{
uint8_t get_ipmi_v20_extended_data;
if (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0)
get_ipmi_v20_extended_data = IPMI_GET_IPMI_V20_EXTENDED_DATA;
else
get_ipmi_v20_extended_data = IPMI_GET_IPMI_V15_DATA;
if (fill_cmd_get_channel_authentication_capabilities (IPMI_CHANNEL_NUMBER_CURRENT_CHANNEL,
cmd_args.common_args.privilege_level,
get_ipmi_v20_extended_data,
ip->obj_authentication_capabilities_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_get_channel_authentication_capabilities: %s",
strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_authentication_capabilities_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RQ)
{
/* Note: The session_authentication_type is none, this authentication type may be different.
*/
if (fill_cmd_get_session_challenge (cmd_args.common_args.authentication_type,
username,
username_len,
ip->obj_get_session_challenge_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_get_session_challenge: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_get_session_challenge_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RQ)
{
uint8_t challenge_string[IPMI_CHALLENGE_STRING_LENGTH];
int challenge_string_len;
if ((challenge_string_len = fiid_obj_get_data (ip->obj_get_session_challenge_rs,
"challenge_string",
challenge_string,
IPMI_CHALLENGE_STRING_LENGTH)) < 0)
{
IPMIPOWER_ERROR (("fiid_obj_get_data: 'challenge_string': %s",
fiid_obj_errormsg (ip->obj_get_session_challenge_rs)));
exit (EXIT_FAILURE);
}
if (!challenge_string_len)
{
IPMIPOWER_ERROR (("host = %s; p = %d; empty challenge string",
ip->ic->hostname, ip->protocol_state));
exit (EXIT_FAILURE);
}
if (fill_cmd_activate_session (authentication_type,
cmd_args.common_args.privilege_level,
challenge_string,
challenge_string_len,
IPMIPOWER_LAN_INITIAL_OUTBOUND_SEQUENCE_NUMBER,
ip->obj_activate_session_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_activate_session: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_activate_session_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_OPEN_SESSION_REQUEST)
{
if (fill_rmcpplus_open_session (ip->initial_message_tag + ip->message_tag_count,
ip->requested_maximum_privilege_level,
ip->remote_console_session_id,
ip->authentication_algorithm,
ip->integrity_algorithm,
ip->confidentiality_algorithm,
ip->obj_open_session_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcpplus_open_session: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_open_session_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_1)
{
if (fill_rmcpplus_rakp_message_1 (ip->initial_message_tag + ip->message_tag_count,
managed_system_session_id,
ip->remote_console_random_number,
IPMI_REMOTE_CONSOLE_RANDOM_NUMBER_LENGTH,
cmd_args.common_args.privilege_level,
ip->name_only_lookup,
username,
username_len,
ip->obj_rakp_message_1_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcpplus_rakp_message_1: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_rakp_message_1_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_RAKP_MESSAGE_3)
{
uint8_t managed_system_random_number[IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH];
int managed_system_random_number_len;
uint8_t key_exchange_authentication_code[IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH];
int key_exchange_authentication_code_len;
uint8_t name_only_lookup;
unsigned int password_len;
if ((managed_system_random_number_len = fiid_obj_get_data (ip->obj_rakp_message_2_rs,
"managed_system_random_number",
managed_system_random_number,
IPMI_MANAGED_SYSTEM_RANDOM_NUMBER_LENGTH)) < 0)
{
IPMIPOWER_ERROR (("fiid_obj_get_data: 'managed_system_random_number': %s",
fiid_obj_errormsg (ip->obj_rakp_message_2_rs)));
exit (EXIT_FAILURE);
}
/* IPMI Workaround (achu)
*
* Discovered on SE7520AF2 with Intel Server Management Module
* (Professional Edition)
*
* For some reason we have to create this key with the name only
* lookup turned off. I was skeptical about this actually being
* a bug until I saw that the ipmitool folks implemented the
* same workaround.
*/
if (cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION)
name_only_lookup = IPMI_USER_NAME_PRIVILEGE_LOOKUP;
else
name_only_lookup = ip->name_only_lookup;
password_len = (password) ? strlen (password) : 0;
/* IPMI Workaround (achu)
*
* Discovered on SE7520AF2 with Intel Server Management Module
* (Professional Edition)
*
* When the authentication algorithm is HMAC-MD5-128 and the
* password is greater than 16 bytes, the Intel BMC truncates the
* password to 16 bytes when generating keys, hashes, etc. So we
* have to do the same when generating keys, hashes, etc.
*/
if ((cmd_args.common_args.workaround_flags_outofband_2_0 & IPMI_PARSE_WORKAROUND_FLAGS_OUTOFBAND_2_0_INTEL_2_0_SESSION)
&& ip->authentication_algorithm == IPMI_AUTHENTICATION_ALGORITHM_RAKP_HMAC_MD5
&& password_len > IPMI_1_5_MAX_PASSWORD_LENGTH)
password_len = IPMI_1_5_MAX_PASSWORD_LENGTH;
if ((key_exchange_authentication_code_len = ipmi_calculate_rakp_3_key_exchange_authentication_code (ip->authentication_algorithm,
password,
password_len,
managed_system_random_number,
managed_system_random_number_len,
ip->remote_console_session_id,
name_only_lookup,
cmd_args.common_args.privilege_level,
username,
username_len,
key_exchange_authentication_code,
IPMI_MAX_KEY_EXCHANGE_AUTHENTICATION_CODE_LENGTH)) < 0)
{
IPMIPOWER_ERROR (("ipmi_calculate_rakp_3_key_exchange_authentication_code: %s",
strerror (errno)));
exit (EXIT_FAILURE);
}
if (fill_rmcpplus_rakp_message_3 (ip->initial_message_tag + ip->message_tag_count,
RMCPPLUS_STATUS_NO_ERRORS,
managed_system_session_id,
key_exchange_authentication_code,
key_exchange_authentication_code_len,
ip->obj_rakp_message_3_rq) < 0)
{
IPMIPOWER_ERROR (("fill_rmcpplus_rakp_message_3: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_rakp_message_3_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RQ)
{
if (fill_cmd_set_session_privilege_level (cmd_args.common_args.privilege_level,
ip->obj_set_session_privilege_level_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_set_session_privilege_level: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_set_session_privilege_level_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_GET_CHASSIS_STATUS_RQ)
{
if (fill_cmd_get_chassis_status (ip->obj_get_chassis_status_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_get_chassis_status: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_get_chassis_status_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RQ)
{
uint8_t command = 0;
assert (ip->cmd == IPMIPOWER_POWER_CMD_POWER_OFF
|| ip->cmd == IPMIPOWER_POWER_CMD_POWER_ON
|| ip->cmd == IPMIPOWER_POWER_CMD_POWER_CYCLE
|| ip->cmd == IPMIPOWER_POWER_CMD_POWER_RESET
|| ip->cmd == IPMIPOWER_POWER_CMD_PULSE_DIAGNOSTIC_INTERRUPT
|| ip->cmd == IPMIPOWER_POWER_CMD_SOFT_SHUTDOWN_OS);
if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_OFF)
command = IPMI_CHASSIS_CONTROL_POWER_DOWN;
else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_ON)
command = IPMI_CHASSIS_CONTROL_POWER_UP;
else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_CYCLE)
command = IPMI_CHASSIS_CONTROL_POWER_CYCLE;
else if (ip->cmd == IPMIPOWER_POWER_CMD_POWER_RESET)
command = IPMI_CHASSIS_CONTROL_HARD_RESET;
else if (ip->cmd == IPMIPOWER_POWER_CMD_PULSE_DIAGNOSTIC_INTERRUPT)
command = IPMI_CHASSIS_CONTROL_PULSE_DIAGNOSTIC_INTERRUPT;
else if (ip->cmd == IPMIPOWER_POWER_CMD_SOFT_SHUTDOWN_OS)
command = IPMI_CHASSIS_CONTROL_INITIATE_SOFT_SHUTDOWN;
if (fill_cmd_chassis_control (command, ip->obj_chassis_control_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_chassis_control: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_chassis_control_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_IDENTIFY_RQ)
{
uint8_t identify_interval;
uint8_t force_identify;
uint8_t *identify_interval_ptr = NULL;
uint8_t *force_identify_ptr = NULL;
assert (ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_ON
|| ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_OFF);
if (ip->cmd == IPMIPOWER_POWER_CMD_IDENTIFY_ON)
{
/* must pass interval for force to be taken */
identify_interval = 0xFF;
identify_interval_ptr = &identify_interval;
force_identify = IPMI_CHASSIS_FORCE_IDENTIFY_ON;
force_identify_ptr = &force_identify;
}
else
{
identify_interval = 0;
identify_interval_ptr = &identify_interval;
}
if (fill_cmd_chassis_identify (identify_interval_ptr,
force_identify_ptr,
ip->obj_chassis_identify_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_chassis_identify: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_chassis_identify_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_GET_SENSOR_READING_RQ)
{
char *endptr;
unsigned int slot_number;
assert (ip->extra_arg);
errno = 0;
slot_number = strtol (ip->extra_arg, &endptr, 0);
/* tons of error checks by now, should not error out here */
assert (!errno);
assert (endptr[0] == '\0');
assert (slot_number >= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MIN
&& slot_number <= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MAX);
if (fill_cmd_get_sensor_reading (IPMI_SENSOR_NUMBER_OEM_DELL_C410X_PCIE_1_WATT + (slot_number - 1),
ip->obj_c410x_get_sensor_reading_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_get_sensor_reading: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_c410x_get_sensor_reading_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_C410X_SLOT_POWER_CONTROL_RQ)
{
char *endptr;
unsigned int slot_number;
uint16_t slot_number_bitmask;
assert (ip->extra_arg);
errno = 0;
slot_number = strtol (ip->extra_arg, &endptr, 0);
/* tons of error checks by now, should not error out here */
assert (!errno);
assert (endptr[0] == '\0');
assert (slot_number >= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MIN
&& slot_number <= IPMI_OEM_DELL_SLOT_POWER_CONTROL_SLOT_NUMBER_MAX);
if (fiid_obj_set (ip->obj_c410x_slot_power_control_rq,
"cmd",
IPMI_CMD_OEM_DELL_SLOT_POWER_CONTROL) < 0)
{
IPMIPOWER_ERROR (("fiid_obj_set: 'cmd': %s",
fiid_obj_errormsg (ip->obj_c410x_slot_power_control_rq)));
exit (EXIT_FAILURE);
}
slot_number_bitmask = (0x1 << (slot_number - 1));
if (fiid_obj_set (ip->obj_c410x_slot_power_control_rq,
"slot_number_bitmask",
slot_number_bitmask) < 0)
{
IPMIPOWER_ERROR (("fiid_obj_set: 'slot_number_bitmask': %s",
fiid_obj_errormsg (ip->obj_c410x_slot_power_control_rq)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_c410x_slot_power_control_rq;
}
else if (pkt == IPMIPOWER_PACKET_TYPE_CLOSE_SESSION_RQ)
{
if (fill_cmd_close_session (session_id,
NULL,
ip->obj_close_session_rq) < 0)
{
IPMIPOWER_ERROR (("fill_cmd_close_session: %s", strerror (errno)));
exit (EXIT_FAILURE);
}
obj_cmd_rq = ip->obj_close_session_rq;
}
/* Construct packets */
if (IPMIPOWER_PACKET_TYPE_IPMI_1_5_SETUP_RQ (pkt)
|| (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt)))
rv = _ipmi_1_5_packet_create (ip,
pkt,
authentication_type,
sequence_number,
session_id,
password,
(password) ? strlen (password) : 0,
net_fn,
obj_cmd_rq,
buf,
buflen);
else if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RQ (pkt)
|| (cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
&& IPMIPOWER_PACKET_TYPE_IPMI_SESSION_PACKET_RQ (pkt)))
rv = _ipmi_2_0_packet_create (ip,
pkt,
payload_type,
payload_authenticated,
payload_encrypted,
session_id,
sequence_number,
password,
(password) ? strlen (password) : 0,
net_fn,
authentication_algorithm,
integrity_algorithm,
confidentiality_algorithm,
integrity_key,
integrity_key_len,
confidentiality_key,
confidentiality_key_len,
obj_cmd_rq,
buf,
buflen);
else
{
IPMIPOWER_ERROR (("host = %s; p = %d; invalid logic",
ip->ic->hostname, ip->protocol_state));
exit (EXIT_FAILURE);
}
return (rv);
}
ipmipower_msg_type_t
ipmipower_packet_errmsg (ipmipower_powercmd_t ip, ipmipower_packet_type_t pkt)
{
fiid_obj_t obj_cmd;
assert (ip);
assert (IPMIPOWER_PACKET_TYPE_RS (pkt));
obj_cmd = ipmipower_packet_cmd_obj (ip, pkt);
if (IPMIPOWER_PACKET_TYPE_IPMI_2_0_SETUP_RS (pkt))
{
uint8_t rmcpplus_status_code;
uint64_t val;
if (FIID_OBJ_GET (obj_cmd,
"rmcpplus_status_code",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'rmcpplus_status_code': %s",
fiid_obj_errormsg (obj_cmd)));
exit (EXIT_FAILURE);
}
rmcpplus_status_code = val;
/* achu:
At this point in time, my belief is that the following RMCPPLUS
Status Codes:
RMCPPLUS_STATUS_INVALID_AUTHENTICATION_ALGORITHM
RMCPPLUS_STATUS_INVALID_INTEGRITY_ALGORITHM
RMCPPLUS_STATUS_INVALID_CONFIDENTIALITY_ALGORITHM
RMCPPLUS_STATUS_INVALID_ROLE
RMCPPLUS_STATUS_NO_MATCHING_AUTHENTICATION_PAYLOAD
RMCPPLUS_STATUS_NO_MATCHING_INTEGRITY_PAYLOAD
Imply that an incorrect algorithm/role/payload value was sent.
*NOT* an unsupported algorithm/role/payload. I assume unsupported algorithm/role/payloads
will get different error codes.
If my assumption is later proven incorrect, then I need to redo some of this.
*/
if (rmcpplus_status_code == RMCPPLUS_STATUS_NO_ERRORS)
{
IPMIPOWER_ERROR (("host = %s; p = %d; pkt = %d; called with good rmcpplus_status_code",
ip->ic->hostname, ip->protocol_state, pkt));
exit (EXIT_FAILURE);
}
else if (rmcpplus_status_code == RMCPPLUS_STATUS_INSUFFICIENT_RESOURCES_TO_CREATE_A_SESSION
|| rmcpplus_status_code == RMCPPLUS_STATUS_INSUFFICIENT_RESOURCES_TO_CREATE_A_SESSION_AT_THE_REQUESTED_TIME)
return (IPMIPOWER_MSG_TYPE_BMC_BUSY);
else if (rmcpplus_status_code == RMCPPLUS_STATUS_UNAUTHORIZED_ROLE_OR_PRIVILEGE_LEVEL_REQUESTED
|| rmcpplus_status_code == RMCPPLUS_STATUS_INVALID_ROLE)
return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
else if (rmcpplus_status_code == RMCPPLUS_STATUS_UNAUTHORIZED_NAME)
return (IPMIPOWER_MSG_TYPE_USERNAME_INVALID);
else if (rmcpplus_status_code == RMCPPLUS_STATUS_NO_CIPHER_SUITE_MATCH_WITH_PROPOSED_SECURITY_ALGORITHMS)
return (IPMIPOWER_MSG_TYPE_CIPHER_SUITE_ID_UNAVAILABLE);
}
else
{
uint8_t comp_code;
uint64_t val;
if (FIID_OBJ_GET (obj_cmd,
"comp_code",
&val) < 0)
{
IPMIPOWER_ERROR (("FIID_OBJ_GET: 'comp_code': %s",
fiid_obj_errormsg (obj_cmd)));
exit (EXIT_FAILURE);
}
comp_code = val;
if (comp_code == IPMI_COMP_CODE_COMMAND_SUCCESS)
{
IPMIPOWER_ERROR (("host = %s; p = %d; pkt = %d; called with good comp_code",
ip->ic->hostname, ip->protocol_state, pkt));
exit (EXIT_FAILURE);
}
else if (pkt == IPMIPOWER_PACKET_TYPE_AUTHENTICATION_CAPABILITIES_RS
&& cmd_args.common_args.driver_type == IPMI_DEVICE_LAN_2_0
&& comp_code == IPMI_COMP_CODE_INVALID_DATA_FIELD_IN_REQUEST)
return (IPMIPOWER_MSG_TYPE_IPMI_2_0_UNAVAILABLE);
else if (pkt == IPMIPOWER_PACKET_TYPE_GET_SESSION_CHALLENGE_RS
&& (comp_code == IPMI_COMP_CODE_GET_SESSION_CHALLENGE_INVALID_USERNAME
|| comp_code == IPMI_COMP_CODE_GET_SESSION_CHALLENGE_NULL_USERNAME_NOT_ENABLED))
return (IPMIPOWER_MSG_TYPE_USERNAME_INVALID);
else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
&& comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_EXCEEDS_PRIVILEGE_LEVEL)
return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
&& (comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SESSION_SLOT_AVAILABLE
|| comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SLOT_AVAILABLE_FOR_GIVEN_USER
|| comp_code == IPMI_COMP_CODE_ACTIVATE_SESSION_NO_SLOT_AVAILABLE_TO_SUPPORT_USER))
return (IPMIPOWER_MSG_TYPE_BMC_BUSY);
/*
* IPMI Workaround
*
* Discovered on Xyratex HB-F8-SRAY
*
* For some reason on this system, if you do not specify a
* privilege level of Admin, this completion code will always be
* returned. Reason unknown. This isn't the best/right error
* to return, but it will atleast point the user to a way to
* work around the problem.
*/
else if (pkt == IPMIPOWER_PACKET_TYPE_ACTIVATE_SESSION_RS
&& comp_code == IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL)
return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
else if (pkt == IPMIPOWER_PACKET_TYPE_SET_SESSION_PRIVILEGE_LEVEL_RS
&& (comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_NOT_AVAILABLE_FOR_USER
|| comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_REQUESTED_LEVEL_EXCEEDS_USER_PRIVILEGE_LIMIT
|| comp_code == IPMI_COMP_CODE_SET_SESSION_PRIVILEGE_LEVEL_CANNOT_DISABLE_USER_LEVEL_AUTHENTICATION))
return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_CANNOT_BE_OBTAINED);
#if 0
/* Should not reach this point, should be handled by other code */
else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS
&& comp_code == IPMI_COMP_CODE_INSUFFICIENT_PRIVILEGE_LEVEL)
return (IPMIPOWER_MSG_TYPE_PRIVILEGE_LEVEL_INSUFFICIENT);
#endif
else if (pkt == IPMIPOWER_PACKET_TYPE_CHASSIS_CONTROL_RS
&& comp_code == IPMI_COMP_CODE_REQUEST_PARAMETER_NOT_SUPPORTED)
return (IPMIPOWER_MSG_TYPE_OPERATION_INVALID);
}
return (IPMIPOWER_MSG_TYPE_BMC_ERROR);
}