summaryrefslogtreecommitdiff
path: root/lib/ipmi_session.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ipmi_session.c')
-rw-r--r--lib/ipmi_session.c459
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;
+}
+