diff --git a/ipmitool/lib/Makefile.am b/ipmitool/lib/Makefile.am index 60149ec..20ee620 100644 --- a/ipmitool/lib/Makefile.am +++ b/ipmitool/lib/Makefile.am @@ -36,7 +36,7 @@ INCLUDES = -I$(top_srcdir)/include MAINTAINERCLEANFILES = Makefile.in noinst_LTLIBRARIES = libipmitool.la -libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_lanp.c \ +libipmitool_la_SOURCES = helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_isol.c ipmi_lanp.c \ ipmi_fru.c ipmi_chassis.c ipmi_bmc.c dimm_spd.c ipmi_sensor.c \ ipmi_channel.c ipmi_event.c ipmi_session.c ipmi_strings.c libipmitool_la_LDFLAGS = -export-dynamic diff --git a/ipmitool/lib/ipmi_isol.c b/ipmitool/lib/ipmi_isol.c new file mode 100644 index 0000000..cf3c255 --- /dev/null +++ b/ipmitool/lib/ipmi_isol.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistribution of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistribution in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Neither the name of Sun Microsystems, Inc. or the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * This software is provided "AS IS," without a warranty of any kind. + * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, + * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. + * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE + * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL + * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, + * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR + * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF + * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, + * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + * + * You acknowledge that this software is not designed or intended for use + * in the design, construction, operation or maintenance of any nuclear + * facility. + */ + +#include +#include +#include + +#include +#include +#include +#include + +extern int verbose; + +static int ipmi_isol_setup(struct ipmi_intf * intf) +{ + struct ipmi_rs * rsp; + struct ipmi_rq req; + unsigned char data[6]; + + /* TEST FOR AVAILABILITY */ + + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_ENABLE_PARAM; + data[2] = ISOL_ENABLE_FLAG; + + memset(&req, 0, sizeof(req)); + req.msg.netfn = IPMI_NETFN_ISOL; + req.msg.cmd = SET_ISOL_CONFIG; + req.msg.data = data; + req.msg.data_len = 3; + + rsp = intf->sendrecv(intf, &req); + if (!rsp) { + printf("Error in Set ISOL Config Command\n"); + return -1; + } + + if (rsp->ccode == 0xc1) { + printf("Serial Over Lan not supported!\n"); + return -1; + } + if (rsp->ccode) { + printf("Set Serial Over Lan Config returned %x\n", rsp->ccode); + return -1; + } + + /* GET ISOL CONFIG */ + + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_AUTHENTICATION_PARAM; + data[2] = 0x00; /* block */ + data[3] = 0x00; /* selector */ + req.msg.cmd = GET_ISOL_CONFIG; + req.msg.data_len = 4; + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x in Get ISOL Config command\n", rsp?rsp->ccode:0); + return -1; + } + + if (verbose > 1) + printbuf(rsp->data, rsp->data_len, "ISOL Config"); + + /* SET ISOL CONFIG - AUTHENTICATION */ + + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_AUTHENTICATION_PARAM; + data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); + req.msg.cmd = SET_ISOL_CONFIG; + req.msg.data_len = 3; + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x in Set ISOL Config (Authentication) command\n", rsp?rsp->ccode:0); + return -1; + } + + /* SET ISOL CONFIG - BAUD RATE */ + + memset(data, 0, 6); + data[0] = 0x00; + data[1] = ISOL_BAUD_RATE_PARAM; + data[2] = ISOL_PREFERRED_BAUD_RATE; + req.msg.cmd = SET_ISOL_CONFIG; + req.msg.data_len = 3; + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x in Set ISOL Config (Baud Rate) command\n", rsp?rsp->ccode:0); + return -1; + } + + return 0; +} + +int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) +{ + if (!argc || !strncmp(argv[0], "help", 4)) { + printf("ISOL Commands: setup\n"); + return 0; + } + else if (!strncmp(argv[0], "setup", 5)) { + ipmi_isol_setup(intf); + } + return 0; +} diff --git a/ipmitool/lib/ipmi_sol.c b/ipmitool/lib/ipmi_sol.c index e7caeec..412a0f7 100644 --- a/ipmitool/lib/ipmi_sol.c +++ b/ipmitool/lib/ipmi_sol.c @@ -42,103 +42,369 @@ #include #include #include +#include + + +#define SOL_PARAMETER_SET_IN_PROGRESS 0x00 +#define SOL_PARAMETER_SOL_ENABLE 0x01 +#define SOL_PARAMETER_SOL_AUTHENTICATION 0x02 +#define SOL_PARAMETER_CHARACTER_INTERVAL 0x03 +#define SOL_PARAMETER_SOL_RETRY 0x04 +#define SOL_PARAMETER_SOL_NON_VOLATILE_BIT_RATE 0x05 +#define SOL_PARAMETER_SOL_VOLATILE_BIT_RATE 0x06 +#define SOL_PARAMETER_SOL_PAYLOAD_CHANNEL 0x07 +#define SOL_PARAMETER_SOL_PAYLOAD_PORT 0x08 + extern int verbose; -static int ipmi_sol_setup(struct ipmi_intf * intf) + +/* + * ipmi_get_sol_info + */ +int ipmi_get_sol_info(struct ipmi_intf * intf, + unsigned char channel, + struct sol_config_parameters * params) { struct ipmi_rs * rsp; struct ipmi_rq req; - unsigned char data[6]; + unsigned char data[4]; - /* TEST FOR AVAILABILITY */ - - memset(data, 0, 6); - data[0] = 0x00; - data[1] = SOL_ENABLE_PARAM; - data[2] = SOL_ENABLE_FLAG; - - memset(&req, 0, sizeof(req)); - req.msg.netfn = IPMI_NETFN_SOL; - req.msg.cmd = SET_SOL_CONFIG; - req.msg.data = data; - req.msg.data_len = 3; - - rsp = intf->sendrecv(intf, &req); - if (!rsp) { - printf("Error in Set SOL Config Command\n"); - return -1; - } - - if (rsp->ccode == 0xc1) { - printf("Serial Over Lan not supported!\n"); - return -1; - } - if (rsp->ccode) { - printf("Set Serial Over Lan Config returned %x\n", rsp->ccode); - return -1; - } - - /* GET SOL CONFIG */ - - memset(data, 0, 6); - data[0] = 0x00; - data[1] = SOL_AUTHENTICATION_PARAM; - data[2] = 0x00; /* block */ - data[3] = 0x00; /* selector */ - req.msg.cmd = GET_SOL_CONFIG; + req.msg.netfn = IPMI_NETFN_TRANSPORT; + req.msg.cmd = IMPI_GET_SOL_CONFIG_PARAMETERS; req.msg.data_len = 4; + req.msg.data = data; + + /* + * set in progress + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SET_IN_PROGRESS; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + rsp = intf->sendrecv(intf, &req); if (!rsp || rsp->ccode) { - printf("Error:%x in Get SOL Config command\n", rsp?rsp->ccode:0); + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); return -1; } - - if (verbose > 1) - printbuf(rsp->data, rsp->data_len, "SOL Config"); - - /* SET SOL CONFIG - AUTHENTICATION */ - - memset(data, 0, 6); - data[0] = 0x00; - data[1] = SOL_AUTHENTICATION_PARAM; - data[2] = SOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); - req.msg.cmd = SET_SOL_CONFIG; - req.msg.data_len = 3; - - rsp = intf->sendrecv(intf, &req); - if (!rsp || rsp->ccode) { - printf("Error:%x in Set SOL Config (Authentication) command\n", rsp?rsp->ccode:0); + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); return -1; } + params->set_in_progress = rsp->data[1]; - /* SET SOL CONFIG - BAUD RATE */ - - memset(data, 0, 6); - data[0] = 0x00; - data[1] = SOL_BAUD_RATE_PARAM; - data[2] = SOL_PREFERRED_BAUD_RATE; - req.msg.cmd = SET_SOL_CONFIG; - req.msg.data_len = 3; + /* + * SOL enable + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_ENABLE; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + rsp = intf->sendrecv(intf, &req); if (!rsp || rsp->ccode) { - printf("Error:%x in Set SOL Config (Baud Rate) command\n", rsp?rsp->ccode:0); + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); return -1; } + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->enabled = rsp->data[1]; + + + /* + * SOL authentication + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_AUTHENTICATION; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->force_encryption = ((rsp->data[1] & 0x80)? 1 : 0); + params->force_authentication = ((rsp->data[1] & 0x40)? 1 : 0); + params->privilege_level = rsp->data[1] & 0x0F; + + + /* + * Character accumulate interval and character send interval + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_CHARACTER_INTERVAL; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 3) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->character_accumulate_level = rsp->data[1]; + params->character_send_threshold = rsp->data[2]; + + + /* + * SOL retry + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_RETRY; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 3) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->retry_count = rsp->data[1]; + params->retry_interval = rsp->data[2]; + + + /* + * SOL non-volatile bit rate + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_NON_VOLATILE_BIT_RATE; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->non_volatile_bit_rate = rsp->data[1] & 0x0F; + + + /* + * SOL volatile bit rate + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_VOLATILE_BIT_RATE; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->volatile_bit_rate = rsp->data[1] & 0x0F; + + + /* + * SOL payload channel + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_PAYLOAD_CHANNEL; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 2) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->payload_channel = rsp->data[1]; + + + /* + * SOL payload port + */ + memset(data, 0, sizeof(data)); + data[0] = channel; /* channel number */ + data[1] = SOL_PARAMETER_SOL_PAYLOAD_PORT; /* parameter selector */ + data[2] = 0x00; /* set selector */ + data[3] = 0x00; /* block selector */ + + rsp = intf->sendrecv(intf, &req); + if (!rsp || rsp->ccode) { + printf("Error:%x Error requesting SOL parameter %d\n", + rsp ? rsp->ccode : 0, + data[1]); + return -1; + } + if (rsp->data_len != 3) + { + printf("Error: Unexpected data length (%d) received for SOL paraemeter %d\n", + rsp->data_len, + data[1]); + return -1; + } + params->payload_port = (rsp->data[1]) | (rsp->data[2] << 8); + + return 0; +} + + + +/* + * ipmi_print_sol_info + */ +static int ipmi_print_sol_info(struct ipmi_intf * intf, unsigned char channel) +{ + struct sol_config_parameters params; + ipmi_get_sol_info(intf, channel, ¶ms); + + if (csv_output) + { + printf("%s,", params.set_in_progress?"true": "false"); + printf("%s,", params.enabled?"true": "false"); + printf("%s,", params.force_encryption?"true":"false"); + printf("%s,", params.force_encryption?"true":"false"); + printf("%s,", + val2str(params.privilege_level, ipmi_privlvl_vals)); + printf("%d,", params.character_accumulate_level * 5); + printf("%d,", params.character_send_threshold); + printf("%d,", params.retry_count); + printf("%d,", params.retry_interval * 10); + + printf("%s,", + val2str(params.volatile_bit_rate, impi_bit_rate_vals)); + + printf("%s,", + val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); + + printf("%d,", params.payload_channel); + printf("%d\n", params.payload_port); + } + else + { + printf("Set in progress : %s\n", params.set_in_progress?"true": "false"); + printf("Enabled : %s\n", params.enabled?"true": "false"); + printf("Force Encryption : %s\n", params.force_encryption?"true":"false"); + printf("Force Authentication : %s\n", params.force_encryption?"true":"false"); + printf("Privilege Level : %s\n", + val2str(params.privilege_level, ipmi_privlvl_vals)); + printf("Character Accumulate Level (ms) : %d\n", params.character_accumulate_level * 5); + printf("Character Send Threshold : %d\n", params.character_send_threshold); + printf("Retry Count : %d\n", params.retry_count); + printf("Retry Interval (ms) : %d\n", params.retry_interval * 10); + + printf("Volatile Bit Rate (kbps) : %s\n", + val2str(params.volatile_bit_rate, impi_bit_rate_vals)); + + printf("Non-Volatile Bit Rate (kbps) : %s\n", + val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); + + printf("Payload Channel : %d\n", params.payload_channel); + printf("Payload Port : %d\n", params.payload_port); + } return 0; } + + +void +print_sol_usage() +{ + printf("SOL Commands: info []\n"); +} + + + int ipmi_sol_main(struct ipmi_intf * intf, int argc, char ** argv) { if (!argc || !strncmp(argv[0], "help", 4)) { - printf("SOL Commands: setup\n"); + print_sol_usage(); return 0; } - else if (!strncmp(argv[0], "setup", 5)) { - ipmi_sol_setup(intf); + else if (!strncmp(argv[0], "info", 4)) { + unsigned char channel; + + if (argc == 1) + channel = 0x0E; /* Ask about the current channel */ + else if (argc == 2) + channel = (unsigned char)strtol(argv[1], NULL, 0); + else + { + print_sol_usage(); + return -1; + } + + ipmi_print_sol_info(intf, channel); } + return 0; } diff --git a/ipmitool/lib/ipmi_strings.c b/ipmitool/lib/ipmi_strings.c index fc410e5..106ebe7 100644 --- a/ipmitool/lib/ipmi_strings.c +++ b/ipmitool/lib/ipmi_strings.c @@ -48,6 +48,20 @@ const struct valstr ipmi_channel_activity_type_vals[] = { }; +/* + * From table 26-4 of the IPMI v2 specification + */ +const struct valstr impi_bit_rate_vals[] = { + { 0x00, "IPMI-Over-Serial-Setting"}, /* Using the value in the IPMI Over Serial Config */ + { 0x06, "9.6" }, + { 0x07, "19.2" }, + { 0x08, "38.4" }, + { 0x09, "57.6" }, + { 0x0A, "115.2" }, + { 0x00, NULL }, +}; + + const struct valstr ipmi_privlvl_vals[] = { { IPMI_SESSION_PRIV_CALLBACK, "CALLBACK" }, { IPMI_SESSION_PRIV_USER, "USER" },