Blame lib/ipmi_session.c

Packit d14fb6
/*
Packit d14fb6
 * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved.
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution and use in source and binary forms, with or without
Packit d14fb6
 * modification, are permitted provided that the following conditions
Packit d14fb6
 * are met:
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution of source code must retain the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer.
Packit d14fb6
 * 
Packit d14fb6
 * Redistribution in binary form must reproduce the above copyright
Packit d14fb6
 * notice, this list of conditions and the following disclaimer in the
Packit d14fb6
 * documentation and/or other materials provided with the distribution.
Packit d14fb6
 * 
Packit d14fb6
 * Neither the name of Sun Microsystems, Inc. or the names of
Packit d14fb6
 * contributors may be used to endorse or promote products derived
Packit d14fb6
 * from this software without specific prior written permission.
Packit d14fb6
 * 
Packit d14fb6
 * This software is provided "AS IS," without a warranty of any kind.
Packit d14fb6
 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
Packit d14fb6
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
Packit d14fb6
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
Packit d14fb6
 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE
Packit d14fb6
 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
Packit d14fb6
 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL
Packit d14fb6
 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
Packit d14fb6
 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
Packit d14fb6
 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
Packit d14fb6
 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
Packit d14fb6
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
Packit d14fb6
 */
Packit d14fb6
Packit d14fb6
#include <stdlib.h>
Packit d14fb6
#include <stdio.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <sys/types.h>
Packit d14fb6
#include <sys/socket.h>
Packit d14fb6
#include <netinet/in.h>
Packit d14fb6
#include <arpa/inet.h>
Packit d14fb6
#include <errno.h>
Packit d14fb6
#include <unistd.h>
Packit d14fb6
#include <signal.h>
Packit d14fb6
Packit d14fb6
#include <ipmitool/ipmi.h>
Packit d14fb6
#include <ipmitool/ipmi_intf.h>
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
#include <ipmitool/ipmi_lanp.h>
Packit d14fb6
#include <ipmitool/ipmi_session.h>
Packit d14fb6
#include <ipmitool/ipmi_strings.h>
Packit d14fb6
#include <ipmitool/bswap.h>
Packit d14fb6
Packit d14fb6
Packit d14fb6
typedef enum {
Packit d14fb6
	IPMI_SESSION_REQUEST_CURRENT = 0,
Packit d14fb6
	IPMI_SESSION_REQUEST_ALL,
Packit d14fb6
	IPMI_SESSION_REQUEST_BY_ID,
Packit d14fb6
	IPMI_SESSION_REQUEST_BY_HANDLE
Packit d14fb6
} Ipmi_Session_Request_Type;
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * print_session_info_csv
Packit d14fb6
 */
Packit d14fb6
static void
Packit d14fb6
print_session_info_csv(const struct  get_session_info_rsp * session_info,
Packit d14fb6
					   int data_len)
Packit d14fb6
{
Packit d14fb6
	char     buffer[18];
Packit d14fb6
	uint16_t console_port_tmp;
Packit d14fb6
	
Packit d14fb6
	printf("%d", session_info->session_handle);
Packit d14fb6
	printf(",%d", session_info->session_slot_count);
Packit d14fb6
	printf(",%d", session_info->active_session_count);
Packit d14fb6
Packit d14fb6
	if (data_len == 3)
Packit d14fb6
	{
Packit d14fb6
		/* There is no session data here*/
Packit d14fb6
		printf("\n");
Packit d14fb6
		return;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	printf(",%d", session_info->user_id);
Packit d14fb6
	printf(",%s", val2str(session_info->privilege_level, ipmi_privlvl_vals));
Packit d14fb6
Packit d14fb6
	printf(",%s", session_info->auxiliary_data?
Packit d14fb6
		   "IPMIv2/RMCP+" : "IPMIv1.5");
Packit d14fb6
Packit d14fb6
	printf(",0x%02x", session_info->channel_number);
Packit d14fb6
Packit d14fb6
	if (data_len == 18)
Packit d14fb6
	{
Packit d14fb6
		/* We have 802.3 LAN data */
Packit d14fb6
		printf(",%s",
Packit d14fb6
			   inet_ntop(AF_INET,
Packit d14fb6
						 &(session_info->channel_data.lan_data.console_ip),
Packit d14fb6
						 buffer,
Packit d14fb6
						 16));
Packit d14fb6
Packit d14fb6
		printf(",%s", mac2str(
Packit d14fb6
			session_info->channel_data.lan_data.console_mac));
Packit d14fb6
Packit d14fb6
		console_port_tmp = session_info->channel_data.lan_data.console_port;
Packit d14fb6
		#if WORDS_BIGENDIAN
Packit d14fb6
		console_port_tmp = BSWAP_16(console_port_tmp);
Packit d14fb6
		#endif
Packit d14fb6
		printf(",%d", console_port_tmp);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
Packit d14fb6
	else if ((data_len == 12) || (data_len == 14))
Packit d14fb6
	{
Packit d14fb6
		/* Channel async serial/modem */
Packit d14fb6
		printf(",%s",
Packit d14fb6
			   val2str(session_info->channel_data.modem_data.session_channel_activity_type,
Packit d14fb6
					   ipmi_channel_activity_type_vals));
Packit d14fb6
Packit d14fb6
		printf(",%d",
Packit d14fb6
			   session_info->channel_data.modem_data.destination_selector);
Packit d14fb6
Packit d14fb6
		printf(",%s",
Packit d14fb6
			   inet_ntop(AF_INET,
Packit d14fb6
						 &(session_info->channel_data.modem_data.console_ip),
Packit d14fb6
						 buffer,
Packit d14fb6
						 16));
Packit d14fb6
Packit d14fb6
		if (data_len == 14)
Packit d14fb6
		{
Packit d14fb6
			/* Connection is PPP */
Packit d14fb6
			console_port_tmp = session_info->channel_data.lan_data.console_port;
Packit d14fb6
			#if WORDS_BIGENDIAN
Packit d14fb6
			console_port_tmp = BSWAP_16(console_port_tmp);
Packit d14fb6
			#endif
Packit d14fb6
			printf(",%d", console_port_tmp);
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	printf("\n");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * print_session_info_verbose
Packit d14fb6
 */
Packit d14fb6
static void
Packit d14fb6
print_session_info_verbose(const struct  get_session_info_rsp * session_info,
Packit d14fb6
						   int data_len)
Packit d14fb6
{
Packit d14fb6
	char     buffer[18];
Packit d14fb6
	uint16_t console_port_tmp;
Packit d14fb6
	
Packit d14fb6
	printf("session handle                : %d\n", session_info->session_handle);
Packit d14fb6
	printf("slot count                    : %d\n", session_info->session_slot_count);
Packit d14fb6
	printf("active sessions               : %d\n", session_info->active_session_count);
Packit d14fb6
Packit d14fb6
	if (data_len == 3)
Packit d14fb6
	{
Packit d14fb6
		/* There is no session data here */
Packit d14fb6
		printf("\n");
Packit d14fb6
		return;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	printf("user id                       : %d\n", session_info->user_id);
Packit d14fb6
	printf("privilege level               : %s\n",
Packit d14fb6
		   val2str(session_info->privilege_level, ipmi_privlvl_vals));
Packit d14fb6
	
Packit d14fb6
	printf("session type                  : %s\n", session_info->auxiliary_data?
Packit d14fb6
		   "IPMIv2/RMCP+" : "IPMIv1.5");
Packit d14fb6
Packit d14fb6
	printf("channel number                : 0x%02x\n", session_info->channel_number);
Packit d14fb6
Packit d14fb6
	
Packit d14fb6
	if (data_len == 18)
Packit d14fb6
	{
Packit d14fb6
		/* We have 802.3 LAN data */
Packit d14fb6
		printf("console ip                    : %s\n",
Packit d14fb6
			   inet_ntop(AF_INET,
Packit d14fb6
						 &(session_info->channel_data.lan_data.console_ip),
Packit d14fb6
						 buffer,
Packit d14fb6
						 16));
Packit d14fb6
Packit d14fb6
		printf("console mac                   : %s\n", mac2str(
Packit d14fb6
			session_info->channel_data.lan_data.console_mac));
Packit d14fb6
Packit d14fb6
		console_port_tmp = session_info->channel_data.lan_data.console_port;
Packit d14fb6
		#if WORDS_BIGENDIAN
Packit d14fb6
		console_port_tmp = BSWAP_16(console_port_tmp);
Packit d14fb6
		#endif
Packit d14fb6
		printf("console port                  : %d\n", console_port_tmp);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
Packit d14fb6
	else if ((data_len == 12) || (data_len == 14))
Packit d14fb6
	{
Packit d14fb6
		/* Channel async serial/modem */
Packit d14fb6
		printf("Session/Channel Activity Type : %s\n",
Packit d14fb6
			   val2str(session_info->channel_data.modem_data.session_channel_activity_type,
Packit d14fb6
					   ipmi_channel_activity_type_vals));
Packit d14fb6
Packit d14fb6
		printf("Destination selector          : %d\n",
Packit d14fb6
			   session_info->channel_data.modem_data.destination_selector);
Packit d14fb6
Packit d14fb6
		printf("console ip                    : %s\n",
Packit d14fb6
			   inet_ntop(AF_INET,
Packit d14fb6
						 &(session_info->channel_data.modem_data.console_ip),
Packit d14fb6
						 buffer,
Packit d14fb6
						 16));
Packit d14fb6
Packit d14fb6
		if (data_len == 14)
Packit d14fb6
		{
Packit d14fb6
			/* Connection is PPP */
Packit d14fb6
			console_port_tmp = session_info->channel_data.lan_data.console_port;
Packit d14fb6
			#if WORDS_BIGENDIAN
Packit d14fb6
			console_port_tmp = BSWAP_16(console_port_tmp);
Packit d14fb6
			#endif
Packit d14fb6
			printf("console port                  : %d\n", console_port_tmp);
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	printf("\n");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
static void print_session_info(const struct  get_session_info_rsp * session_info,
Packit d14fb6
							   int data_len)
Packit d14fb6
{
Packit d14fb6
	if (csv_output)
Packit d14fb6
		print_session_info_csv(session_info, data_len);
Packit d14fb6
	else
Packit d14fb6
		print_session_info_verbose(session_info, data_len);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * ipmi_get_session_info
Packit d14fb6
 *
Packit d14fb6
 * returns 0 on success
Packit d14fb6
 *         -1 on error
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_get_session_info(struct ipmi_intf         * intf,
Packit d14fb6
					  Ipmi_Session_Request_Type  session_request_type,
Packit d14fb6
					  uint32_t                   id_or_handle)
Packit d14fb6
{
Packit d14fb6
	int i, retval = 0;
Packit d14fb6
Packit d14fb6
	struct ipmi_rs * rsp;
Packit d14fb6
	struct ipmi_rq req;
Packit d14fb6
	uint8_t rqdata[5]; //  max length of the variable length request
Packit d14fb6
	struct get_session_info_rsp   session_info;
Packit d14fb6
Packit d14fb6
	memset(&req, 0, sizeof(req));
Packit d14fb6
	memset(&session_info, 0, sizeof(session_info));
Packit d14fb6
	req.msg.netfn = IPMI_NETFN_APP;        // 0x06
Packit d14fb6
	req.msg.cmd   = IPMI_GET_SESSION_INFO; // 0x3D
Packit d14fb6
	req.msg.data = rqdata;
Packit d14fb6
Packit d14fb6
	switch (session_request_type)
Packit d14fb6
	{
Packit d14fb6
		
Packit d14fb6
	case IPMI_SESSION_REQUEST_CURRENT:
Packit d14fb6
	case IPMI_SESSION_REQUEST_BY_ID:	
Packit d14fb6
	case IPMI_SESSION_REQUEST_BY_HANDLE:
Packit d14fb6
		switch (session_request_type)
Packit d14fb6
		{
Packit d14fb6
		case IPMI_SESSION_REQUEST_CURRENT:
Packit d14fb6
			rqdata[0]        = 0x00;
Packit d14fb6
			req.msg.data_len = 1;
Packit d14fb6
			break;
Packit d14fb6
		case IPMI_SESSION_REQUEST_BY_ID:	
Packit d14fb6
			rqdata[0]        = 0xFF;
Packit d14fb6
			rqdata[1]        = id_or_handle         & 0x000000FF;
Packit d14fb6
			rqdata[2]        = (id_or_handle >> 8)  & 0x000000FF;
Packit d14fb6
			rqdata[3]        = (id_or_handle >> 16) & 0x000000FF;
Packit d14fb6
			rqdata[4]        = (id_or_handle >> 24) & 0x000000FF;
Packit d14fb6
			req.msg.data_len = 5;
Packit d14fb6
			break;
Packit d14fb6
		case IPMI_SESSION_REQUEST_BY_HANDLE:
Packit d14fb6
			rqdata[0]        = 0xFE;
Packit d14fb6
			rqdata[1]        = (uint8_t)id_or_handle;
Packit d14fb6
			req.msg.data_len = 2;
Packit d14fb6
			break;
Packit d14fb6
		case IPMI_SESSION_REQUEST_ALL:
Packit d14fb6
			break;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
		if (rsp == NULL)
Packit d14fb6
		{
Packit d14fb6
			lprintf(LOG_ERR, "Get Session Info command failed");
Packit d14fb6
			retval = -1;
Packit d14fb6
		}
Packit d14fb6
		else if (rsp->ccode > 0)
Packit d14fb6
		{
Packit d14fb6
			lprintf(LOG_ERR, "Get Session Info command failed: %s",
Packit d14fb6
				val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
			retval = -1;
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		if (retval < 0)
Packit d14fb6
		{
Packit d14fb6
			if ((session_request_type == IPMI_SESSION_REQUEST_CURRENT) &&
Packit d14fb6
			    (strncmp(intf->name, "lan", 3) != 0))
Packit d14fb6
				lprintf(LOG_ERR, "It is likely that the channel in use "
Packit d14fb6
					"does not support sessions");
Packit d14fb6
		}
Packit d14fb6
		else
Packit d14fb6
		{
Packit Service 48cd9d
			memcpy(&session_info,  rsp->data,
Packit Service 48cd9d
			       __min(rsp->data_len, sizeof(session_info)));
Packit Service 48cd9d
			print_session_info(&session_info,
Packit Service 48cd9d
			                   __min(rsp->data_len, sizeof(session_info)));
Packit d14fb6
		}
Packit d14fb6
		break;
Packit d14fb6
		
Packit d14fb6
	case IPMI_SESSION_REQUEST_ALL:
Packit d14fb6
		req.msg.data_len = 1;
Packit d14fb6
		i = 1;
Packit d14fb6
		do
Packit d14fb6
		{
Packit d14fb6
			rqdata[0] = i++;
Packit d14fb6
			rsp = intf->sendrecv(intf, &req;;
Packit d14fb6
			
Packit d14fb6
			if (rsp == NULL)
Packit d14fb6
			{
Packit d14fb6
				lprintf(LOG_ERR, "Get Session Info command failed");
Packit d14fb6
				retval = -1;
Packit d14fb6
				break;
Packit d14fb6
			}
Packit d14fb6
			else if (rsp->ccode > 0 && rsp->ccode != 0xCC && rsp->ccode != 0xCB)
Packit d14fb6
			{
Packit d14fb6
				lprintf(LOG_ERR, "Get Session Info command failed: %s",
Packit d14fb6
					val2str(rsp->ccode, completion_code_vals));
Packit d14fb6
				retval = -1;
Packit d14fb6
				break;
Packit d14fb6
			}
Packit d14fb6
			else if (rsp->data_len < 3)
Packit d14fb6
			{
Packit d14fb6
				retval = -1;
Packit d14fb6
				break;
Packit d14fb6
			}
Packit d14fb6
Packit Service 48cd9d
			memcpy(&session_info,  rsp->data,
Packit Service 48cd9d
			       __min(rsp->data_len, sizeof(session_info)));
Packit Service 48cd9d
			print_session_info(&session_info,
Packit Service 48cd9d
			                   __min(rsp->data_len, sizeof(session_info)));
Packit d14fb6
			
Packit d14fb6
		} while (i <= session_info.session_slot_count);
Packit d14fb6
		break;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return retval;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
Packit d14fb6
static void
Packit d14fb6
printf_session_usage(void)
Packit d14fb6
{
Packit d14fb6
	lprintf(LOG_NOTICE, "Session Commands: info <active | all | id 0xnnnnnnnn | handle 0xnn>");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
int
Packit d14fb6
ipmi_session_main(struct ipmi_intf * intf, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	int retval = 0;
Packit d14fb6
Packit d14fb6
	if (argc == 0 || strncmp(argv[0], "help", 4) == 0)
Packit d14fb6
	{
Packit d14fb6
		printf_session_usage();
Packit d14fb6
	}
Packit d14fb6
	else if (strncmp(argv[0], "info", 4) == 0)
Packit d14fb6
	{
Packit d14fb6
Packit d14fb6
		if ((argc < 2) || strncmp(argv[1], "help", 4) == 0)
Packit d14fb6
		{
Packit d14fb6
				printf_session_usage();
Packit d14fb6
		}
Packit d14fb6
		else
Packit d14fb6
		{
Packit d14fb6
			Ipmi_Session_Request_Type session_request_type = 0;
Packit d14fb6
			uint32_t                  id_or_handle = 0;
Packit d14fb6
Packit d14fb6
			if (strncmp(argv[1], "active", 6) == 0)
Packit d14fb6
				session_request_type = IPMI_SESSION_REQUEST_CURRENT;
Packit d14fb6
			else if (strncmp(argv[1], "all", 3) == 0)
Packit d14fb6
				session_request_type = IPMI_SESSION_REQUEST_ALL;
Packit d14fb6
			else if (strncmp(argv[1], "id", 2) == 0)
Packit d14fb6
			{
Packit d14fb6
				if (argc >= 3)
Packit d14fb6
				{
Packit d14fb6
					session_request_type = IPMI_SESSION_REQUEST_BY_ID;
Packit d14fb6
					if (str2uint(argv[2], &id_or_handle) != 0) {
Packit d14fb6
						lprintf(LOG_ERR, "HEX number expected, but '%s' given.",
Packit d14fb6
								argv[2]);
Packit d14fb6
						printf_session_usage();
Packit d14fb6
						retval = -1;
Packit d14fb6
					}
Packit d14fb6
				}
Packit d14fb6
				else
Packit d14fb6
				{
Packit d14fb6
					lprintf(LOG_ERR, "Missing id argument");
Packit d14fb6
					printf_session_usage();
Packit d14fb6
					retval = -1;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			else if (strncmp(argv[1], "handle", 6) == 0)
Packit d14fb6
			{
Packit d14fb6
				if (argc >= 3)
Packit d14fb6
				{
Packit d14fb6
					session_request_type = IPMI_SESSION_REQUEST_BY_HANDLE;
Packit d14fb6
					if (str2uint(argv[2], &id_or_handle) != 0) {
Packit d14fb6
						lprintf(LOG_ERR, "HEX number expected, but '%s' given.",
Packit d14fb6
								argv[2]);
Packit d14fb6
						printf_session_usage();
Packit d14fb6
						retval = -1;
Packit d14fb6
					}
Packit d14fb6
				}
Packit d14fb6
				else
Packit d14fb6
				{
Packit d14fb6
					lprintf(LOG_ERR, "Missing handle argument");
Packit d14fb6
					printf_session_usage();
Packit d14fb6
					retval = -1;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			else
Packit d14fb6
			{
Packit d14fb6
				lprintf(LOG_ERR, "Invalid SESSION info parameter: %s", argv[1]);
Packit d14fb6
				printf_session_usage();
Packit d14fb6
				retval = -1;
Packit d14fb6
			}
Packit d14fb6
			
Packit d14fb6
Packit d14fb6
			if (retval == 0)
Packit d14fb6
				retval = ipmi_get_session_info(intf,
Packit d14fb6
											   session_request_type,
Packit d14fb6
											   id_or_handle);
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
	else
Packit d14fb6
	{
Packit d14fb6
		lprintf(LOG_ERR, "Invalid SESSION command: %s", argv[0]);
Packit d14fb6
		printf_session_usage();
Packit d14fb6
		retval = -1;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return retval;
Packit d14fb6
}
Packit d14fb6