updates from sourceforge,

changes to support settable SOL escape char
This commit is contained in:
Duncan Laurie 2006-01-15 06:41:08 +00:00
parent ed8a467f6d
commit d6e85b8427
8 changed files with 112 additions and 46 deletions

View File

@ -68,7 +68,7 @@ enum LANPLUS_SESSION_STATE {
struct ipmi_session {
uint8_t hostname[64];
uint8_t username[16];
uint8_t username[17];
uint8_t authcode[IPMI_AUTHCODE_BUFFER_SIZE + 1];
uint8_t challenge[16];
uint8_t authtype;
@ -82,6 +82,7 @@ struct ipmi_session {
uint8_t authextra;
uint8_t privlvl;
uint8_t cipher_suite_id;
char sol_escape_char;
int password;
int port;
int active;
@ -194,6 +195,8 @@ void ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username);
void ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password);
void ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t privlvl);
void ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id);
void ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char);
void ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey);
void ipmi_intf_session_set_port(struct ipmi_intf * intf, int port);
void ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype);
void ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout);

View File

@ -39,6 +39,7 @@
#include <ipmitool/ipmi.h>
#define SOL_ESCAPE_CHARACTER_DEFAULT '~'
#define IPMI_SOL_SERIAL_ALERT_MASK_SUCCEED 0x08
#define IPMI_SOL_SERIAL_ALERT_MASK_DEFERRED 0x04

View File

@ -48,6 +48,17 @@
# include <config.h>
#endif
/*
* Apparently some systems have problems with FRU access greater than 16 bytes
* at a time, even when using byte (not word) access. In order to ensure we
* work with the widest variety of hardware request size is capped at 16 bytes.
* Since this may result in slowdowns on some systems with lots of FRU data you
* can undefine this to enable larger (up to 32 bytes at a time) access.
*
* TODO: make this a command line option
*/
#define LIMIT_ALL_REQUEST_SIZE 1
extern int verbose;
extern int ipmi_spd_print(struct ipmi_intf * intf, uint8_t id);
static void ipmi_fru_read_to_bin(struct ipmi_intf * intf,unsigned char * pFileName, unsigned char fruId);
@ -216,9 +227,13 @@ write_fru_area(struct ipmi_intf * intf, struct fru_info *fru, unsigned char id,
req.msg.netfn = IPMI_NETFN_STORAGE;
req.msg.cmd = SET_FRU_DATA;
req.msg.data = msg_data;
#ifdef LIMIT_ALL_REQUEST_SIZE
if (fru_data_rqst_size > 16)
#else
if (fru->access && fru_data_rqst_size > 16)
fru_data_rqst_size = 16;
#endif
fru_data_rqst_size = 16;
do
{
/* real destination offset */
@ -301,7 +316,11 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
req.msg.data = msg_data;
req.msg.data_len = 4;
#ifdef LIMIT_ALL_REQUEST_SIZE
if (fru_data_rqst_size > 16)
#else
if (fru->access && fru_data_rqst_size > 16)
#endif
fru_data_rqst_size = 16;
do {
tmp = fru->access ? off >> 1 : off;
@ -320,8 +339,6 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
break;
}
if (rsp->ccode > 0) {
lprintf(LOG_NOTICE, "FRU Read failed: %s",
val2str(rsp->ccode, completion_code_vals));
/* if we get C7 or C8 or CA return code then we requested too
* many bytes at once so try again with smaller size */
if ((rsp->ccode == 0xc7 || rsp->ccode == 0xc8 || rsp->ccode == 0xca) &&
@ -330,6 +347,8 @@ read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
fru_data_rqst_size);
continue;
}
lprintf(LOG_NOTICE, "FRU Read failed: %s",
val2str(rsp->ccode, completion_code_vals));
break;
}
@ -1159,15 +1178,15 @@ __ipmi_fru_print(struct ipmi_intf * intf, uint8_t id)
lprintf(LOG_DEBUG, "fru.header.version: 0x%x",
header.version);
lprintf(LOG_DEBUG, "fru.header.offset.internal: 0x%x",
header.offset.internal);
header.offset.internal * 8);
lprintf(LOG_DEBUG, "fru.header.offset.chassis: 0x%x",
header.offset.chassis);
header.offset.chassis * 8);
lprintf(LOG_DEBUG, "fru.header.offset.board: 0x%x",
header.offset.board);
header.offset.board * 8);
lprintf(LOG_DEBUG, "fru.header.offset.product: 0x%x",
header.offset.product);
header.offset.product * 8);
lprintf(LOG_DEBUG, "fru.header.offset.multi: 0x%x",
header.offset.multi);
header.offset.multi * 8);
/*
* rather than reading the entire part

View File

@ -74,7 +74,7 @@
#endif
#ifdef ENABLE_ALL_OPTIONS
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:l:b:"
# define OPTION_STRING "I:hVvcgsEao:H:P:f:U:p:C:L:A:t:m:S:l:b:e:k:"
#else
# define OPTION_STRING "I:hVvcH:f:U:p:S:"
#endif
@ -227,7 +227,9 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
lprintf(LOG_NOTICE, " -S sdr Use local file for remote SDR cache");
#ifdef ENABLE_ALL_OPTIONS
lprintf(LOG_NOTICE, " -a Prompt for remote password");
lprintf(LOG_NOTICE, " -e char Set SOL escape character");
lprintf(LOG_NOTICE, " -C ciphersuite Cipher suite to be used by lanplus interface");
lprintf(LOG_NOTICE, " -k key Use Kg key for IPMIv2 authentication");
lprintf(LOG_NOTICE, " -L level Remote session privilege level [default=ADMINISTRATOR]");
lprintf(LOG_NOTICE, " -A authtype Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
lprintf(LOG_NOTICE, " -P password Remote session password");
@ -235,7 +237,6 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_
lprintf(LOG_NOTICE, " -m address Set local IPMB address");
lprintf(LOG_NOTICE, " -b channel Set destination channel for bridged request");
lprintf(LOG_NOTICE, " -l lun Set destination lun for raw commands");
lprintf(LOG_NOTICE, " -t address Bridge request to remote target address");
lprintf(LOG_NOTICE, " -o oemtype Setup for OEM (use 'list' to see available OEM types)");
#endif
@ -279,10 +280,12 @@ ipmi_main(int argc, char ** argv,
char * progname = NULL;
char * oemtype = NULL;
char * sdrcache = NULL;
char * kgkey = NULL;
int port = 0;
int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
int argflag, i, found;
int rc = -1;
char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
/* save program name */
progname = strrchr(argv[0], '/');
@ -364,6 +367,13 @@ ipmi_main(int argc, char ** argv,
}
}
break;
case 'k':
kgkey = strdup(optarg);
if (kgkey == NULL) {
lprintf(LOG_ERR, "%s: malloc failure", progname);
goto out_free;
}
break;
case 'U':
username = strdup(optarg);
if (username == NULL) {
@ -457,6 +467,9 @@ ipmi_main(int argc, char ** argv,
case 'm':
my_addr = (uint8_t)strtol(optarg, NULL, 0);
break;
case 'e':
sol_escape_char = optarg[0];
break;
#endif
default:
ipmi_option_usage(progname, cmdlist, intflist);
@ -533,6 +546,8 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_username(intf, username);
if (password != NULL)
ipmi_intf_session_set_password(intf, password);
if (kgkey != NULL)
ipmi_intf_session_set_kgkey(intf, kgkey);
if (port > 0)
ipmi_intf_session_set_port(intf, port);
if (authtype >= 0)
@ -543,13 +558,14 @@ ipmi_main(int argc, char ** argv,
ipmi_intf_session_set_privlvl(intf,
IPMI_SESSION_PRIV_ADMIN); /* default */
ipmi_intf_session_set_sol_escape_char(intf, sol_escape_char);
ipmi_intf_session_set_cipher_suite_id(intf, cipher_suite_id);
/* setup destination lun if given */
intf->target_lun = target_lun ;
/* setup destination lun if given */
intf->target_lun = target_lun ;
/* setup destination channel if given */
intf->target_channel = target_channel ;
/* setup destination channel if given */
intf->target_channel = target_channel ;
/* setup IPMB local and target address if given */
intf->my_addr = my_addr ? : IPMI_BMC_SLAVE_ADDR;

View File

@ -67,8 +67,6 @@
#define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07
#define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08
#define SOL_ESCAPE_CHARACTER '~'
const struct valstr sol_parameter_vals[] = {
{ SOL_PARAMETER_SET_IN_PROGRESS, "Set In Progress (0)" },
{ SOL_PARAMETER_SOL_ENABLE, "Enable (1)" },
@ -1048,7 +1046,7 @@ suspendSelf(int bRestoreTty)
* Send some useful documentation to the user
*/
static void
printSolEscapeSequences(void)
printSolEscapeSequences(struct ipmi_intf * intf)
{
printf(
"%c?\r\n\
@ -1060,14 +1058,14 @@ printSolEscapeSequences(void)
%c? - this message\r\n\
%c%c - send the escape character by typing it twice\r\n\
(Note that escapes are only recognized immediately after newline.)\r\n",
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER,
SOL_ESCAPE_CHARACTER);
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char,
intf->session->sol_escape_char);
}
@ -1158,7 +1156,7 @@ static int
processSolUserInput(
struct ipmi_intf * intf,
uint8_t * input,
uint16_t buffer_length)
uint16_t buffer_length)
{
static int escape_pending = 0;
static int last_was_cr = 1;
@ -1186,38 +1184,44 @@ processSolUserInput(
*/
switch (ch) {
case '.':
printf("%c. [terminated ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
printf("%c. [terminated ipmitool]\r\n",
intf->session->sol_escape_char);
retval = 1;
break;
case 'Z' - 64:
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
printf("%c^Z [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspendSelf(1); /* Restore tty back to raw */
continue;
case 'X' - 64:
printf("%c^Z [suspend ipmitool]\r\n", SOL_ESCAPE_CHARACTER);
printf("%c^Z [suspend ipmitool]\r\n",
intf->session->sol_escape_char);
suspendSelf(0); /* Don't restore to raw mode */
continue;
case 'B':
printf("%cb [send break]\r\n", SOL_ESCAPE_CHARACTER);
printf("%cb [send break]\r\n",
intf->session->sol_escape_char);
sendBreak(intf);
continue;
case '?':
printSolEscapeSequences();
printSolEscapeSequences(intf);
continue;
default:
if (ch != SOL_ESCAPE_CHARACTER)
if (ch != intf->session->sol_escape_char)
v2_payload.payload.sol_packet.data[length++] =
SOL_ESCAPE_CHARACTER;
intf->session->sol_escape_char;
v2_payload.payload.sol_packet.data[length++] = ch;
}
}
else
{
if (last_was_cr && (ch == SOL_ESCAPE_CHARACTER)) {
if (last_was_cr && (ch == intf->session->sol_escape_char)) {
escape_pending = 1;
continue;
}
@ -1413,7 +1417,7 @@ ipmi_sol_activate(struct ipmi_intf * intf)
intf->session->sol_data.sol_input_handler = output;
memset(&req, 0, sizeof(req));
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = IPMI_ACTIVATE_PAYLOAD;
req.msg.data_len = 6;
@ -1519,7 +1523,7 @@ ipmi_sol_activate(struct ipmi_intf * intf)
printf("[SOL Session operational. Use %c? for help]\r\n",
SOL_ESCAPE_CHARACTER);
intf->session->sol_escape_char);
/*

View File

@ -180,7 +180,7 @@ ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)
if (intf->session == NULL)
return;
memset(intf->session->username, 0, 16);
memset(intf->session->username, 0, 17);
if (username == NULL)
return;
@ -224,6 +224,30 @@ ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_su
intf->session->cipher_suite_id = cipher_suite_id;
}
void
ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)
{
if (intf->session == NULL)
return;
intf->session->sol_escape_char = sol_escape_char;
}
void
ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)
{
if (intf->session == NULL)
return;
memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
if (kgkey == NULL)
return;
memcpy(intf->session->v2_data.kg, kgkey,
__min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));
}
void
ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)
{

View File

@ -3238,7 +3238,9 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
//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);
memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
/* Kg is set in ipmi_intf */
//memset(session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE);
/* open port to BMC */

View File

@ -528,13 +528,10 @@ int lanplus_generate_sik(struct ipmi_session * session)
{
/* We will be hashing with Kg */
/*
* TODO: Section 13.31 of the IPMI v2 spec describes the SIK creation
* using Kg. It specifies that Kg should not be truncated, but I
* do not know what is meant by that.
* Section 13.31 of the IPMI v2 spec describes the SIK creation
* using Kg. It specifies that Kg should not be truncated.
* Kg is set in ipmi_intf.
*/
lprintf(LOG_ERR, "lanplus_generate_sik: We dont yet support hashing with Kg");
assert(0);
input_key = session->v2_data.kg;
}
else