diff options
Diffstat (limited to 'lib/ipmi_session.c')
-rw-r--r-- | lib/ipmi_session.c | 459 |
1 files changed, 459 insertions, 0 deletions
diff --git a/lib/ipmi_session.c b/lib/ipmi_session.c new file mode 100644 index 0000000..4855bc4 --- /dev/null +++ b/lib/ipmi_session.c @@ -0,0 +1,459 @@ +/* + * 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. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> + +#include <ipmitool/ipmi.h> +#include <ipmitool/ipmi_intf.h> +#include <ipmitool/helper.h> +#include <ipmitool/log.h> +#include <ipmitool/ipmi_lanp.h> +#include <ipmitool/ipmi_session.h> +#include <ipmitool/ipmi_strings.h> +#include <ipmitool/bswap.h> + + +typedef enum { + IPMI_SESSION_REQUEST_CURRENT = 0, + IPMI_SESSION_REQUEST_ALL, + IPMI_SESSION_REQUEST_BY_ID, + IPMI_SESSION_REQUEST_BY_HANDLE +} Ipmi_Session_Request_Type; + + + + +/* + * print_session_info_csv + */ +static void +print_session_info_csv(const struct get_session_info_rsp * session_info, + int data_len) +{ + char buffer[18]; + uint16_t console_port_tmp; + + printf("%d", session_info->session_handle); + printf(",%d", session_info->session_slot_count); + printf(",%d", session_info->active_session_count); + + if (data_len == 3) + { + /* There is no session data here*/ + printf("\n"); + return; + } + + printf(",%d", session_info->user_id); + printf(",%s", val2str(session_info->privilege_level, ipmi_privlvl_vals)); + + printf(",%s", session_info->auxiliary_data? + "IPMIv2/RMCP+" : "IPMIv1.5"); + + printf(",0x%02x", session_info->channel_number); + + if (data_len == 18) + { + /* We have 802.3 LAN data */ + printf(",%s", + inet_ntop(AF_INET, + &(session_info->channel_data.lan_data.console_ip), + buffer, + 16)); + + printf(",%02x:%02x:%02x:%02x:%02x:%02x", + session_info->channel_data.lan_data.console_mac[0], + session_info->channel_data.lan_data.console_mac[1], + session_info->channel_data.lan_data.console_mac[2], + session_info->channel_data.lan_data.console_mac[3], + session_info->channel_data.lan_data.console_mac[4], + session_info->channel_data.lan_data.console_mac[5]); + + console_port_tmp = session_info->channel_data.lan_data.console_port; + #if WORDS_BIGENDIAN + console_port_tmp = BSWAP_16(console_port_tmp); + #endif + printf(",%d", console_port_tmp); + } + + + else if ((data_len == 12) || (data_len == 14)) + { + /* Channel async serial/modem */ + printf(",%s", + val2str(session_info->channel_data.modem_data.session_channel_activity_type, + ipmi_channel_activity_type_vals)); + + printf(",%d", + session_info->channel_data.modem_data.destination_selector); + + printf(",%s", + inet_ntop(AF_INET, + &(session_info->channel_data.modem_data.console_ip), + buffer, + 16)); + + if (data_len == 14) + { + /* Connection is PPP */ + console_port_tmp = session_info->channel_data.lan_data.console_port; + #if WORDS_BIGENDIAN + console_port_tmp = BSWAP_16(console_port_tmp); + #endif + printf(",%d", console_port_tmp); + } + } + + printf("\n"); +} + + + +/* + * print_session_info_verbose + */ +static void +print_session_info_verbose(const struct get_session_info_rsp * session_info, + int data_len) +{ + char buffer[18]; + uint16_t console_port_tmp; + + printf("session handle : %d\n", session_info->session_handle); + printf("slot count : %d\n", session_info->session_slot_count); + printf("active sessions : %d\n", session_info->active_session_count); + + if (data_len == 3) + { + /* There is no session data here */ + printf("\n"); + return; + } + + printf("user id : %d\n", session_info->user_id); + printf("privilege level : %s\n", + val2str(session_info->privilege_level, ipmi_privlvl_vals)); + + printf("session type : %s\n", session_info->auxiliary_data? + "IPMIv2/RMCP+" : "IPMIv1.5"); + + printf("channel number : 0x%02x\n", session_info->channel_number); + + + if (data_len == 18) + { + /* We have 802.3 LAN data */ + printf("console ip : %s\n", + inet_ntop(AF_INET, + &(session_info->channel_data.lan_data.console_ip), + buffer, + 16)); + + printf("console mac : %02x:%02x:%02x:%02x:%02x:%02x\n", + session_info->channel_data.lan_data.console_mac[0], + session_info->channel_data.lan_data.console_mac[1], + session_info->channel_data.lan_data.console_mac[2], + session_info->channel_data.lan_data.console_mac[3], + session_info->channel_data.lan_data.console_mac[4], + session_info->channel_data.lan_data.console_mac[5]); + + console_port_tmp = session_info->channel_data.lan_data.console_port; + #if WORDS_BIGENDIAN + console_port_tmp = BSWAP_16(console_port_tmp); + #endif + printf("console port : %d\n", console_port_tmp); + } + + + else if ((data_len == 12) || (data_len == 14)) + { + /* Channel async serial/modem */ + printf("Session/Channel Activity Type : %s\n", + val2str(session_info->channel_data.modem_data.session_channel_activity_type, + ipmi_channel_activity_type_vals)); + + printf("Destination selector : %d\n", + session_info->channel_data.modem_data.destination_selector); + + printf("console ip : %s\n", + inet_ntop(AF_INET, + &(session_info->channel_data.modem_data.console_ip), + buffer, + 16)); + + if (data_len == 14) + { + /* Connection is PPP */ + console_port_tmp = session_info->channel_data.lan_data.console_port; + #if WORDS_BIGENDIAN + console_port_tmp = BSWAP_16(console_port_tmp); + #endif + printf("console port : %d\n", console_port_tmp); + } + } + + printf("\n"); +} + + +static void print_session_info(const struct get_session_info_rsp * session_info, + int data_len) +{ + if (csv_output) + print_session_info_csv(session_info, data_len); + else + print_session_info_verbose(session_info, data_len); +} + + +/* + * ipmi_get_session_info + * + * returns 0 on success + * -1 on error + */ +int +ipmi_get_session_info(struct ipmi_intf * intf, + Ipmi_Session_Request_Type session_request_type, + uint32_t id_or_handle) +{ + int i, retval = 0; + + struct ipmi_rs * rsp; + struct ipmi_rq req; + uint8_t rqdata[5]; // max length of the variable length request + struct get_session_info_rsp session_info; + + memset(&req, 0, sizeof(req)); + memset(&session_info, 0, sizeof(session_info)); + req.msg.netfn = IPMI_NETFN_APP; // 0x06 + req.msg.cmd = IPMI_GET_SESSION_INFO; // 0x3D + req.msg.data = rqdata; + + switch (session_request_type) + { + + case IPMI_SESSION_REQUEST_CURRENT: + case IPMI_SESSION_REQUEST_BY_ID: + case IPMI_SESSION_REQUEST_BY_HANDLE: + switch (session_request_type) + { + case IPMI_SESSION_REQUEST_CURRENT: + rqdata[0] = 0x00; + req.msg.data_len = 1; + break; + case IPMI_SESSION_REQUEST_BY_ID: + rqdata[0] = 0xFF; + rqdata[1] = id_or_handle & 0x000000FF; + rqdata[2] = (id_or_handle >> 8) & 0x000000FF; + rqdata[3] = (id_or_handle >> 16) & 0x000000FF; + rqdata[4] = (id_or_handle >> 24) & 0x000000FF; + req.msg.data_len = 5; + break; + case IPMI_SESSION_REQUEST_BY_HANDLE: + rqdata[0] = 0xFE; + rqdata[1] = (uint8_t)id_or_handle; + req.msg.data_len = 2; + break; + case IPMI_SESSION_REQUEST_ALL: + break; + } + + rsp = intf->sendrecv(intf, &req); + if (rsp == NULL) + { + lprintf(LOG_ERR, "Get Session Info command failed"); + retval = -1; + } + else if (rsp->ccode > 0) + { + lprintf(LOG_ERR, "Get Session Info command failed: %s", + val2str(rsp->ccode, completion_code_vals)); + retval = -1; + } + + if (retval < 0) + { + if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) && + (strncmp(intf->name, "lan", 3) != 0)) + lprintf(LOG_ERR, "It is likely that the channel in use " + "does not support sessions"); + } + else + { + memcpy(&session_info, rsp->data, rsp->data_len); + print_session_info(&session_info, rsp->data_len); + } + break; + + case IPMI_SESSION_REQUEST_ALL: + req.msg.data_len = 1; + i = 1; + do + { + rqdata[0] = i++; + rsp = intf->sendrecv(intf, &req); + + if (rsp == NULL) + { + lprintf(LOG_ERR, "Get Session Info command failed"); + retval = -1; + break; + } + else if (rsp->ccode > 0 && rsp->ccode != 0xCC && rsp->ccode != 0xCB) + { + lprintf(LOG_ERR, "Get Session Info command failed: %s", + val2str(rsp->ccode, completion_code_vals)); + retval = -1; + break; + } + else if (rsp->data_len < 3) + { + retval = -1; + break; + } + + memcpy(&session_info, rsp->data, rsp->data_len); + print_session_info(&session_info, rsp->data_len); + + } while (i <= session_info.session_slot_count); + break; + } + + return retval; +} + + + +static void +printf_session_usage(void) +{ + lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>"); +} + + +int +ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv) +{ + int retval = 0; + + if (argc == 0 || strncmp(argv[0], "help", 4) == 0) + { + printf_session_usage(); + } + else if (strncmp(argv[0], "info", 4) == 0) + { + + if ((argc < 2) || strncmp(argv[1], "help", 4) == 0) + { + printf_session_usage(); + } + else + { + Ipmi_Session_Request_Type session_request_type = 0; + uint32_t id_or_handle = 0; + + if (strncmp(argv[1], "active", 6) == 0) + session_request_type = IPMI_SESSION_REQUEST_CURRENT; + else if (strncmp(argv[1], "all", 3) == 0) + session_request_type = IPMI_SESSION_REQUEST_ALL; + else if (strncmp(argv[1], "id", 2) == 0) + { + if (argc >= 3) + { + session_request_type = IPMI_SESSION_REQUEST_BY_ID; + if (str2uint(argv[2], &id_or_handle) != 0) { + lprintf(LOG_ERR, "HEX number expected, but '%s' given.", + argv[2]); + printf_session_usage(); + retval = -1; + } + } + else + { + lprintf(LOG_ERR, "Missing id argument"); + printf_session_usage(); + retval = -1; + } + } + else if (strncmp(argv[1], "handle", 6) == 0) + { + if (argc >= 3) + { + session_request_type = IPMI_SESSION_REQUEST_BY_HANDLE; + if (str2uint(argv[2], &id_or_handle) != 0) { + lprintf(LOG_ERR, "HEX number expected, but '%s' given.", + argv[2]); + printf_session_usage(); + retval = -1; + } + } + else + { + lprintf(LOG_ERR, "Missing handle argument"); + printf_session_usage(); + retval = -1; + } + } + else + { + lprintf(LOG_ERR, "Invalid SESSION info parameter: %s", argv[1]); + printf_session_usage(); + retval = -1; + } + + + if (retval == 0) + retval = ipmi_get_session_info(intf, + session_request_type, + id_or_handle); + } + } + else + { + lprintf(LOG_ERR, "Invalid SESSION command: %s", argv[0]); + printf_session_usage(); + retval = -1; + } + + return retval; +} + |