|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
ed0f68 |
* modification, are permitted provided that the following conditions
|
|
Packit Service |
ed0f68 |
* are met:
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Redistribution of source code must retain the above copyright
|
|
Packit Service |
ed0f68 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Redistribution in binary form must reproduce the above copyright
|
|
Packit Service |
ed0f68 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit Service |
ed0f68 |
* documentation and/or other materials provided with the distribution.
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Neither the name of Sun Microsystems, Inc. or the names of
|
|
Packit Service |
ed0f68 |
* contributors may be used to endorse or promote products derived
|
|
Packit Service |
ed0f68 |
* from this software without specific prior written permission.
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* This software is provided "AS IS," without a warranty of any kind.
|
|
Packit Service |
ed0f68 |
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
|
|
Packit Service |
ed0f68 |
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
|
|
Packit Service |
ed0f68 |
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
|
|
Packit Service |
ed0f68 |
* SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
|
|
Packit Service |
ed0f68 |
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
|
|
Packit Service |
ed0f68 |
* OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
|
|
Packit Service |
ed0f68 |
* SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
|
|
Packit Service |
ed0f68 |
* OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
|
|
Packit Service |
ed0f68 |
* PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
|
|
Packit Service |
ed0f68 |
* LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
|
|
Packit Service |
ed0f68 |
* EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
#define _XOPEN_SOURCE
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
#include <stdlib.h>
|
|
Packit Service |
ed0f68 |
#include <string.h>
|
|
Packit Service |
ed0f68 |
#include <strings.h>
|
|
Packit Service |
ed0f68 |
#include <stdio.h>
|
|
Packit Service |
ed0f68 |
#include <sys/types.h>
|
|
Packit Service |
ed0f68 |
#include <sys/stat.h>
|
|
Packit Service |
ed0f68 |
#include <sys/select.h>
|
|
Packit Service |
ed0f68 |
#include <sys/time.h>
|
|
Packit Service |
ed0f68 |
#include <signal.h>
|
|
Packit Service |
ed0f68 |
#include <unistd.h>
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
#include <termios.h>
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
#include <ipmitool/helper.h>
|
|
Packit Service |
ed0f68 |
#include <ipmitool/log.h>
|
|
Packit Service |
ed0f68 |
#include <ipmitool/ipmi.h>
|
|
Packit Service |
ed0f68 |
#include <ipmitool/ipmi_strings.h>
|
|
Packit Service |
ed0f68 |
#include <ipmitool/ipmi_intf.h>
|
|
Packit Service |
ed0f68 |
#include <ipmitool/ipmi_isol.h>
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static struct termios _saved_tio;
|
|
Packit Service |
ed0f68 |
static int _in_raw_mode = 0;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
extern int verbose;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
#define ISOL_ESCAPE_CHARACTER '~'
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* ipmi_get_isol_info
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static int ipmi_get_isol_info(struct ipmi_intf * intf,
|
|
Packit Service |
ed0f68 |
struct isol_config_parameters * params)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rsp;
|
|
Packit Service |
ed0f68 |
struct ipmi_rq req;
|
|
Packit Service |
ed0f68 |
unsigned char data[6];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
ed0f68 |
req.msg.netfn = IPMI_NETFN_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.cmd = GET_ISOL_CONFIG;
|
|
Packit Service |
ed0f68 |
req.msg.data = data;
|
|
Packit Service |
ed0f68 |
req.msg.data_len = 4;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* GET ISOL ENABLED CONFIG */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
data[0] = 0x00;
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_ENABLE_PARAM;
|
|
Packit Service |
ed0f68 |
data[2] = 0x00; /* block */
|
|
Packit Service |
ed0f68 |
data[3] = 0x00; /* selector */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (rsp == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode == 0xc1) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode > 0) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s",
|
|
Packit Service |
ed0f68 |
val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
params->enabled = rsp->data[1];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* GET ISOL AUTHENTICATON CONFIG */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
data[0] = 0x00;
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_AUTHENTICATION_PARAM;
|
|
Packit Service |
ed0f68 |
data[2] = 0x00; /* block */
|
|
Packit Service |
ed0f68 |
data[3] = 0x00; /* selector */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (rsp == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode > 0) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s",
|
|
Packit Service |
ed0f68 |
val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
params->privilege_level = rsp->data[1];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* GET ISOL BAUD RATE CONFIG */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
data[0] = 0x00;
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_BAUD_RATE_PARAM;
|
|
Packit Service |
ed0f68 |
data[2] = 0x00; /* block */
|
|
Packit Service |
ed0f68 |
data[3] = 0x00; /* selector */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (rsp == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode > 0) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s",
|
|
Packit Service |
ed0f68 |
val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
params->bit_rate = rsp->data[1];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static int ipmi_print_isol_info(struct ipmi_intf * intf)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct isol_config_parameters params = {0};
|
|
Packit Service |
ed0f68 |
if (ipmi_get_isol_info(intf, ¶ms))
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (csv_output)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
printf("%s,", (params.enabled & 0x1)?"true": "false");
|
|
Packit Service |
ed0f68 |
printf("%s,",
|
|
Packit Service |
ed0f68 |
val2str((params.privilege_level & 0xf), ipmi_privlvl_vals));
|
|
Packit Service |
ed0f68 |
printf("%s,",
|
|
Packit Service |
ed0f68 |
val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals));
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
printf("Enabled : %s\n",
|
|
Packit Service |
ed0f68 |
(params.enabled & 0x1)?"true": "false");
|
|
Packit Service |
ed0f68 |
printf("Privilege Level : %s\n",
|
|
Packit Service |
ed0f68 |
val2str((params.privilege_level & 0xf), ipmi_privlvl_vals));
|
|
Packit Service |
ed0f68 |
printf("Bit Rate (kbps) : %s\n",
|
|
Packit Service |
ed0f68 |
val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals));
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static int ipmi_isol_set_param(struct ipmi_intf * intf,
|
|
Packit Service |
ed0f68 |
const char *param,
|
|
Packit Service |
ed0f68 |
const char *value)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rsp;
|
|
Packit Service |
ed0f68 |
struct ipmi_rq req;
|
|
Packit Service |
ed0f68 |
unsigned char data[6];
|
|
Packit Service |
ed0f68 |
struct isol_config_parameters params = {0};
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* We need other values to complete the request */
|
|
Packit Service |
ed0f68 |
if (ipmi_get_isol_info(intf, ¶ms))
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
ed0f68 |
req.msg.netfn = IPMI_NETFN_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.cmd = SET_ISOL_CONFIG;
|
|
Packit Service |
ed0f68 |
req.msg.data = data;
|
|
Packit Service |
ed0f68 |
req.msg.data_len = 3;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* enabled
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
if (strcmp(param, "enabled") == 0)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_ENABLE_PARAM;
|
|
Packit Service |
ed0f68 |
if (strcmp(value, "true") == 0)
|
|
Packit Service |
ed0f68 |
data[2] = 0x01;
|
|
Packit Service |
ed0f68 |
else if (strcmp(value, "false") == 0)
|
|
Packit Service |
ed0f68 |
data[2] = 0x00;
|
|
Packit Service |
ed0f68 |
else {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Invalid value %s for parameter %s",
|
|
Packit Service |
ed0f68 |
value, param);
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Valid values are true and false");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* privilege-level
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (strcmp(param, "privilege-level") == 0)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_AUTHENTICATION_PARAM;
|
|
Packit Service |
ed0f68 |
if (! strcmp(value, "user"))
|
|
Packit Service |
ed0f68 |
data[2] = 0x02;
|
|
Packit Service |
ed0f68 |
else if (! strcmp(value, "operator"))
|
|
Packit Service |
ed0f68 |
data[2] = 0x03;
|
|
Packit Service |
ed0f68 |
else if (! strcmp(value, "admin"))
|
|
Packit Service |
ed0f68 |
data[2] = 0x04;
|
|
Packit Service |
ed0f68 |
else if (! strcmp(value, "oem"))
|
|
Packit Service |
ed0f68 |
data[2] = 0x05;
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Invalid value %s for parameter %s",
|
|
Packit Service |
ed0f68 |
value, param);
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Valid values are user, operator, admin, and oem");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
/* We need to mask bit7 from the fetched value */
|
|
Packit Service |
ed0f68 |
data[2] |= (params.privilege_level & 0x80) ? 0x80 : 0x00;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* bit-rate
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (strcmp(param, "bit-rate") == 0)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
data[1] = ISOL_BAUD_RATE_PARAM;
|
|
Packit Service |
ed0f68 |
if (strncmp(value, "9.6", 3) == 0) {
|
|
Packit Service |
ed0f68 |
data[2] = 0x06;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else if (strncmp(value, "19.2", 4) == 0) {
|
|
Packit Service |
ed0f68 |
data[2] = 0x07;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else if (strncmp(value, "38.4", 4) == 0) {
|
|
Packit Service |
ed0f68 |
data[2] = 0x08;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else if (strncmp(value, "57.6", 4) == 0) {
|
|
Packit Service |
ed0f68 |
data[2] = 0x09;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else if (strncmp(value, "115.2", 5) == 0) {
|
|
Packit Service |
ed0f68 |
data[2] = 0x0A;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", value);
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Valid values are 9.6, 19.2, 38.4, 57.6 and 115.2");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error: invalid ISOL parameter %s", param);
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Execute the request
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (rsp == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error setting ISOL parameter '%s'", param);
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode > 0) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error setting ISOL parameter '%s': %s",
|
|
Packit Service |
ed0f68 |
param, val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
leave_raw_mode(void)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if (!_in_raw_mode)
|
|
Packit Service |
ed0f68 |
return;
|
|
Packit Service |
ed0f68 |
if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1)
|
|
Packit Service |
ed0f68 |
perror("tcsetattr");
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
_in_raw_mode = 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
enter_raw_mode(void)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct termios tio;
|
|
Packit Service |
ed0f68 |
if (tcgetattr(fileno(stdin), &tio) == -1) {
|
|
Packit Service |
ed0f68 |
perror("tcgetattr");
|
|
Packit Service |
ed0f68 |
return;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
_saved_tio = tio;
|
|
Packit Service |
ed0f68 |
tio.c_iflag |= IGNPAR;
|
|
Packit Service |
ed0f68 |
tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)\
|
|
Packit Service |
ed0f68 |
;
|
|
Packit Service |
ed0f68 |
tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL);
|
|
Packit Service |
ed0f68 |
// #ifdef IEXTEN
|
|
Packit Service |
ed0f68 |
tio.c_lflag &= ~IEXTEN;
|
|
Packit Service |
ed0f68 |
// #endif
|
|
Packit Service |
ed0f68 |
tio.c_oflag &= ~OPOST;
|
|
Packit Service |
ed0f68 |
tio.c_cc[VMIN] = 1;
|
|
Packit Service |
ed0f68 |
tio.c_cc[VTIME] = 0;
|
|
Packit Service |
ed0f68 |
if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1)
|
|
Packit Service |
ed0f68 |
perror("tcsetattr");
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
_in_raw_mode = 1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
sendBreak(struct ipmi_intf * intf)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_v2_payload v2_payload;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&v2_payload, 0, sizeof(v2_payload));
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.character_count = 0;
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.generate_break = 1;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
intf->send_sol(intf, &v2_payload);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* suspendSelf
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Put ourself in the background
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* param bRestoreTty specifies whether we will put our self back
|
|
Packit Service |
ed0f68 |
* in raw mode when we resume
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
suspendSelf(int bRestoreTty)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
leave_raw_mode();
|
|
Packit Service |
ed0f68 |
kill(getpid(), SIGTSTP);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (bRestoreTty)
|
|
Packit Service |
ed0f68 |
enter_raw_mode();
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* printiSolEscapeSequences
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Send some useful documentation to the user
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
printiSolEscapeSequences(void)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
printf(
|
|
Packit Service |
ed0f68 |
"%c?\n\
|
|
Packit Service |
ed0f68 |
Supported escape sequences:\n\
|
|
Packit Service |
ed0f68 |
%c. - terminate connection\n\
|
|
Packit Service |
ed0f68 |
%c^Z - suspend ipmitool\n\
|
|
Packit Service |
ed0f68 |
%c^X - suspend ipmitool, but don't restore tty on restart\n\
|
|
Packit Service |
ed0f68 |
%cB - send break\n\
|
|
Packit Service |
ed0f68 |
%c? - this message\n\
|
|
Packit Service |
ed0f68 |
%c%c - send the escape character by typing it twice\n\
|
|
Packit Service |
ed0f68 |
(Note that escapes are only recognized immediately after newline.)\n",
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER,
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* output
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Send the specified data to stdout
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static void
|
|
Packit Service |
ed0f68 |
output(struct ipmi_rs * rsp)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if (rsp)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
int i;
|
|
Packit Service |
ed0f68 |
for (i = 0; i < rsp->data_len; ++i)
|
|
Packit Service |
ed0f68 |
putc(rsp->data[i], stdout);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
fflush(stdout);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* ipmi_isol_deactivate
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static int
|
|
Packit Service |
ed0f68 |
ipmi_isol_deactivate(struct ipmi_intf * intf)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rsp;
|
|
Packit Service |
ed0f68 |
struct ipmi_rq req;
|
|
Packit Service |
ed0f68 |
uint8_t data[6];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
ed0f68 |
req.msg.netfn = IPMI_NETFN_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.cmd = ACTIVATE_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.data = data;
|
|
Packit Service |
ed0f68 |
req.msg.data_len = 5;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
data[0] = 0x00; /* Deactivate */
|
|
Packit Service |
ed0f68 |
data[1] = 0x00;
|
|
Packit Service |
ed0f68 |
data[2] = 0x00;
|
|
Packit Service |
ed0f68 |
data[3] = 0x00;
|
|
Packit Service |
ed0f68 |
data[5] = 0x00;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (rsp == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error deactivating ISOL");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
if (rsp->ccode > 0) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error deactivating ISOL: %s",
|
|
Packit Service |
ed0f68 |
val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
/* response contain 4 additional bytes : 80 00 32 ff
|
|
Packit Service |
ed0f68 |
Don't know what to use them for yet... */
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* processiSolUserInput
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* Act on user input into the ISOL session. The only reason this
|
|
Packit Service |
ed0f68 |
* is complicated is that we have to process escape sequences.
|
|
Packit Service |
ed0f68 |
*
|
|
Packit Service |
ed0f68 |
* return 0 on success
|
|
Packit Service |
ed0f68 |
* 1 if we should exit
|
|
Packit Service |
ed0f68 |
* < 0 on error (BMC probably closed the session)
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static int
|
|
Packit Service |
ed0f68 |
processiSolUserInput(struct ipmi_intf * intf,
|
|
Packit Service |
ed0f68 |
uint8_t * input,
|
|
Packit Service |
ed0f68 |
uint16_t buffer_length)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
static int escape_pending = 0;
|
|
Packit Service |
ed0f68 |
static int last_was_cr = 1;
|
|
Packit Service |
ed0f68 |
struct ipmi_v2_payload v2_payload;
|
|
Packit Service |
ed0f68 |
int length = 0;
|
|
Packit Service |
ed0f68 |
int retval = 0;
|
|
Packit Service |
ed0f68 |
char ch;
|
|
Packit Service |
ed0f68 |
int i;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&v2_payload, 0, sizeof(v2_payload));
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Our first order of business is to check the input for escape
|
|
Packit Service |
ed0f68 |
* sequences to act on.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
for (i = 0; i < buffer_length; ++i)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
ch = input[i];
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (escape_pending){
|
|
Packit Service |
ed0f68 |
escape_pending = 0;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Process a possible escape sequence.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
switch (ch) {
|
|
Packit Service |
ed0f68 |
case '.':
|
|
Packit Service |
ed0f68 |
printf("%c. [terminated ipmitool]\n", ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
retval = 1;
|
|
Packit Service |
ed0f68 |
break;
|
|
Packit Service |
ed0f68 |
case 'Z' - 64:
|
|
Packit Service |
ed0f68 |
printf("%c^Z [suspend ipmitool]\n", ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
suspendSelf(1); /* Restore tty back to raw */
|
|
Packit Service |
ed0f68 |
continue;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
case 'X' - 64:
|
|
Packit Service |
ed0f68 |
printf("%c^X [suspend ipmitool]\n", ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
suspendSelf(0); /* Don't restore to raw mode */
|
|
Packit Service |
ed0f68 |
continue;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
case 'B':
|
|
Packit Service |
ed0f68 |
printf("%cb [send break]\n", ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
sendBreak(intf);
|
|
Packit Service |
ed0f68 |
continue;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
case '?':
|
|
Packit Service |
ed0f68 |
printiSolEscapeSequences();
|
|
Packit Service |
ed0f68 |
continue;
|
|
Packit Service |
ed0f68 |
default:
|
|
Packit Service |
ed0f68 |
if (ch != ISOL_ESCAPE_CHARACTER)
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.data[length++] =
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER;
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.data[length++] = ch;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if (last_was_cr && (ch == ISOL_ESCAPE_CHARACTER)) {
|
|
Packit Service |
ed0f68 |
escape_pending = 1;
|
|
Packit Service |
ed0f68 |
continue;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.data[length++] = ch;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Normal character. Record whether it was a newline.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
last_was_cr = (ch == '\r' || ch == '\n');
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* If there is anything left to process we dispatch it to the BMC,
|
|
Packit Service |
ed0f68 |
* send intf->session->sol_data.max_outbound_payload_size bytes
|
|
Packit Service |
ed0f68 |
* at a time.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
if (length)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rsp;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.flush_outbound = 1; /* Not sure if necessary ? */
|
|
Packit Service |
ed0f68 |
v2_payload.payload.sol_packet.character_count = length;
|
|
Packit Service |
ed0f68 |
rsp = intf->send_sol(intf, &v2_payload);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (! rsp) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error sending SOL data");
|
|
Packit Service |
ed0f68 |
retval = -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* If the sequence number is set we know we have new data */
|
|
Packit Service |
ed0f68 |
else if ((rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) &&
|
|
Packit Service |
ed0f68 |
(rsp->payload.sol_packet.packet_sequence_number))
|
|
Packit Service |
ed0f68 |
output(rsp);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
return retval;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* ipmi_isol_red_pill
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static int
|
|
Packit Service |
ed0f68 |
ipmi_isol_red_pill(struct ipmi_intf * intf)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
char * buffer;
|
|
Packit Service |
ed0f68 |
int numRead;
|
|
Packit Service |
ed0f68 |
int bShouldExit = 0;
|
|
Packit Service |
ed0f68 |
int bBmcClosedSession = 0;
|
|
Packit Service |
ed0f68 |
fd_set read_fds;
|
|
Packit Service |
ed0f68 |
struct timeval tv;
|
|
Packit Service |
ed0f68 |
int retval;
|
|
Packit Service |
ed0f68 |
int buffer_size = 255;
|
|
Packit Service |
ed0f68 |
int timedout = 0;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
buffer = (char*)malloc(buffer_size);
|
|
Packit Service |
ed0f68 |
if (buffer == NULL) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "ipmitool: malloc failure");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
enter_raw_mode();
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
while (! bShouldExit)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
FD_ZERO(&read_fds);
|
|
Packit Service |
ed0f68 |
FD_SET(0, &read_fds);
|
|
Packit Service |
ed0f68 |
FD_SET(intf->fd, &read_fds);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* Wait up to half a second */
|
|
Packit Service |
ed0f68 |
tv.tv_sec = 0;
|
|
Packit Service |
ed0f68 |
tv.tv_usec = 500000;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
retval = select(intf->fd + 1, &read_fds, NULL, NULL, &tv;;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (retval)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if (retval == -1)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
/* ERROR */
|
|
Packit Service |
ed0f68 |
perror("select");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
timedout = 0;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Process input from the user
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
if (FD_ISSET(0, &read_fds))
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
memset(buffer, 0, buffer_size);
|
|
Packit Service |
ed0f68 |
numRead = read(fileno(stdin),
|
|
Packit Service |
ed0f68 |
buffer,
|
|
Packit Service |
ed0f68 |
buffer_size);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (numRead > 0)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
int rc = processiSolUserInput(intf, buffer, numRead);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (rc)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if (rc < 0)
|
|
Packit Service |
ed0f68 |
bShouldExit = bBmcClosedSession = 1;
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
bShouldExit = 1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
bShouldExit = 1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Process input from the BMC
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (FD_ISSET(intf->fd, &read_fds))
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rs = intf->recv_sol(intf);
|
|
Packit Service |
ed0f68 |
if (! rs)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
bShouldExit = bBmcClosedSession = 1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
output(rs);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* ERROR in select
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error: Select returned with nothing to read");
|
|
Packit Service |
ed0f68 |
bShouldExit = 1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
if ((++timedout) == 20) /* Every 10 seconds we send a keepalive */
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
intf->keepalive(intf);
|
|
Packit Service |
ed0f68 |
timedout = 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
leave_raw_mode();
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (bBmcClosedSession)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "SOL session closed by BMC");
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
else
|
|
Packit Service |
ed0f68 |
ipmi_isol_deactivate(intf);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* ipmi_isol_activate
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
static int
|
|
Packit Service |
ed0f68 |
ipmi_isol_activate(struct ipmi_intf * intf)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
struct ipmi_rs * rsp;
|
|
Packit Service |
ed0f68 |
struct ipmi_rq req;
|
|
Packit Service |
ed0f68 |
uint8_t data[6];
|
|
Packit Service |
ed0f68 |
struct isol_config_parameters params;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (ipmi_get_isol_info(intf, ¶ms))
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
if (!(params.enabled & 0x1)) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "ISOL is not enabled!");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Setup a callback so that the lanplus processing knows what
|
|
Packit Service |
ed0f68 |
* to do with packets that come unexpectedly (while waiting for
|
|
Packit Service |
ed0f68 |
* an ACK, perhaps.
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
intf->session->sol_data.sol_input_handler = output;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(&req, 0, sizeof(req));
|
|
Packit Service |
ed0f68 |
req.msg.netfn = IPMI_NETFN_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.cmd = ACTIVATE_ISOL;
|
|
Packit Service |
ed0f68 |
req.msg.data = data;
|
|
Packit Service |
ed0f68 |
req.msg.data_len = 5;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
memset(data, 0, 6);
|
|
Packit Service |
ed0f68 |
data[0] = 0x01;
|
|
Packit Service |
ed0f68 |
data[1] = 0x00;
|
|
Packit Service |
ed0f68 |
data[2] = 0x00;
|
|
Packit Service |
ed0f68 |
data[3] = 0x00;
|
|
Packit Service |
ed0f68 |
data[5] = 0x00;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
rsp = intf->sendrecv(intf, &req;;
|
|
Packit Service |
ed0f68 |
if (NULL != rsp) {
|
|
Packit Service |
ed0f68 |
switch (rsp->ccode) {
|
|
Packit Service |
ed0f68 |
case 0x00:
|
|
Packit Service |
ed0f68 |
if (rsp->data_len == 4) {
|
|
Packit Service |
ed0f68 |
break;
|
|
Packit Service |
ed0f68 |
} else {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error: Unexpected data length (%d) received "
|
|
Packit Service |
ed0f68 |
"in ISOL activation response",
|
|
Packit Service |
ed0f68 |
rsp->data_len);
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
break;
|
|
Packit Service |
ed0f68 |
case 0x80:
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Info: ISOL already active on another session");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
case 0x81:
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Info: ISOL disabled");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
case 0x82:
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Info: ISOL activation limit reached");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
default:
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error activating ISOL: %s",
|
|
Packit Service |
ed0f68 |
val2str(rsp->ccode, completion_code_vals));
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
} else {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error: No response activating ISOL");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/* response contain 4 additional bytes : 80 01 32 ff
|
|
Packit Service |
ed0f68 |
Don't know what to use them for yet... */
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
printf("[SOL Session operational. Use %c? for help]\n",
|
|
Packit Service |
ed0f68 |
ISOL_ESCAPE_CHARACTER);
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* At this point we are good to go with our SOL session. We
|
|
Packit Service |
ed0f68 |
* need to listen to
|
|
Packit Service |
ed0f68 |
* 1) STDIN for user input
|
|
Packit Service |
ed0f68 |
* 2) The FD for incoming SOL packets
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
if (ipmi_isol_red_pill(intf)) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_ERR, "Error in SOL session");
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return 0;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static void print_isol_set_usage(void) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, "\nISOL set parameters and values: \n");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, " enabled true | false");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, " privilege-level user | operator | admin | oem");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, " bit-rate "
|
|
Packit Service |
ed0f68 |
"9.6 | 19.2 | 38.4 | 57.6 | 115.2");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, "");
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
static void print_isol_usage(void) {
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, "ISOL Commands: info");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, " set <parameter> <setting>");
|
|
Packit Service |
ed0f68 |
lprintf(LOG_NOTICE, " activate");
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv)
|
|
Packit Service |
ed0f68 |
{
|
|
Packit Service |
ed0f68 |
int ret = 0;
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Help
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
if (!argc || !strncmp(argv[0], "help", 4))
|
|
Packit Service |
ed0f68 |
print_isol_usage();
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Info
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (!strncmp(argv[0], "info", 4)) {
|
|
Packit Service |
ed0f68 |
ret = ipmi_print_isol_info(intf);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Set a parameter value
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (!strncmp(argv[0], "set", 3)) {
|
|
Packit Service |
ed0f68 |
if (argc < 3) {
|
|
Packit Service |
ed0f68 |
print_isol_set_usage();
|
|
Packit Service |
ed0f68 |
return -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
ret = ipmi_isol_set_param(intf, argv[1], argv[2]);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
/*
|
|
Packit Service |
ed0f68 |
* Activate
|
|
Packit Service |
ed0f68 |
*/
|
|
Packit Service |
ed0f68 |
else if (!strncmp(argv[0], "activate", 8)) {
|
|
Packit Service |
ed0f68 |
ret = ipmi_isol_activate(intf);
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
else {
|
|
Packit Service |
ed0f68 |
print_isol_usage();
|
|
Packit Service |
ed0f68 |
ret = -1;
|
|
Packit Service |
ed0f68 |
}
|
|
Packit Service |
ed0f68 |
|
|
Packit Service |
ed0f68 |
return ret;
|
|
Packit Service |
ed0f68 |
}
|