/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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(",%s", mac2str( session_info->channel_data.lan_data.console_mac)); 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 : %s\n", mac2str( session_info->channel_data.lan_data.console_mac)); 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 "); } 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; }