Blame lib/ipmi_main.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
#define _XOPEN_SOURCE 700
Packit d14fb6
#define _BSD_SOURCE || \
Packit d14fb6
	(_XOPEN_SOURCE >= 500 || \
Packit d14fb6
	_XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) && \
Packit d14fb6
	!(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
Packit d14fb6
Packit d14fb6
#include <stdlib.h>
Packit d14fb6
#include <stdio.h>
Packit d14fb6
#include <inttypes.h>
Packit d14fb6
#include <signal.h>
Packit d14fb6
#include <string.h>
Packit d14fb6
#include <strings.h>
Packit d14fb6
#include <sys/types.h>
Packit d14fb6
#include <sys/stat.h>
Packit d14fb6
#include <unistd.h>
Packit d14fb6
#include <fcntl.h>
Packit d14fb6
#include <errno.h>
Packit d14fb6
#include <ctype.h>
Packit d14fb6
Packit d14fb6
#include <ipmitool/helper.h>
Packit d14fb6
#include <ipmitool/log.h>
Packit d14fb6
#include <ipmitool/ipmi.h>
Packit d14fb6
#include <ipmitool/ipmi_intf.h>
Packit d14fb6
#include <ipmitool/ipmi_session.h>
Packit d14fb6
#include <ipmitool/ipmi_sdr.h>
Packit d14fb6
#include <ipmitool/ipmi_gendev.h>
Packit d14fb6
#include <ipmitool/ipmi_sel.h>
Packit d14fb6
#include <ipmitool/ipmi_fru.h>
Packit d14fb6
#include <ipmitool/ipmi_sol.h>
Packit d14fb6
#include <ipmitool/ipmi_isol.h>
Packit d14fb6
#include <ipmitool/ipmi_lanp.h>
Packit d14fb6
#include <ipmitool/ipmi_chassis.h>
Packit d14fb6
#include <ipmitool/ipmi_mc.h>
Packit d14fb6
#include <ipmitool/ipmi_firewall.h>
Packit d14fb6
#include <ipmitool/ipmi_sensor.h>
Packit d14fb6
#include <ipmitool/ipmi_channel.h>
Packit d14fb6
#include <ipmitool/ipmi_session.h>
Packit d14fb6
#include <ipmitool/ipmi_event.h>
Packit d14fb6
#include <ipmitool/ipmi_user.h>
Packit d14fb6
#include <ipmitool/ipmi_raw.h>
Packit d14fb6
#include <ipmitool/ipmi_pef.h>
Packit d14fb6
#include <ipmitool/ipmi_oem.h>
Packit d14fb6
#include <ipmitool/ipmi_ekanalyzer.h>
Packit d14fb6
#include <ipmitool/ipmi_picmg.h>
Packit d14fb6
#include <ipmitool/ipmi_kontronoem.h>
Packit d14fb6
#include <ipmitool/ipmi_vita.h>
Packit ac2ffc
#include <ipmitool/ipmi_quantaoem.h>
Packit d14fb6
Packit d14fb6
#ifdef HAVE_CONFIG_H
Packit d14fb6
# include <config.h>
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
#ifdef ENABLE_ALL_OPTIONS
Packit d14fb6
# define OPTION_STRING	"I:46hVvcgsEKYao:H:d:P:f:U:p:C:L:A:t:T:m:z:S:l:b:B:e:k:y:O:R:N:D:"
Packit d14fb6
#else
Packit d14fb6
# define OPTION_STRING	"I:46hVvcH:f:U:p:d:S:D:"
Packit d14fb6
#endif
Packit d14fb6
Packit d14fb6
/* From src/plugins/ipmi_intf.c: */
Packit d14fb6
void
Packit d14fb6
ipmi_intf_set_max_request_data_size(struct ipmi_intf * intf, uint16_t size);
Packit d14fb6
Packit d14fb6
extern int verbose;
Packit d14fb6
extern int csv_output;
Packit d14fb6
extern const struct valstr ipmi_privlvl_vals[];
Packit d14fb6
extern const struct valstr ipmi_authtype_session_vals[];
Packit d14fb6
Packit d14fb6
static struct ipmi_intf * ipmi_main_intf = NULL;
Packit d14fb6
Packit d14fb6
/* ipmi_password_file_read  -  Open file and read password from it
Packit d14fb6
 *
Packit d14fb6
 * @filename:	file name to read from
Packit d14fb6
 *
Packit d14fb6
 * returns pointer to allocated buffer containing password
Packit d14fb6
 *   (caller is expected to free when finished)
Packit d14fb6
 * returns NULL on error
Packit d14fb6
 */
Packit d14fb6
static char *
Packit d14fb6
ipmi_password_file_read(char * filename)
Packit d14fb6
{
Packit d14fb6
	FILE * fp;
Packit d14fb6
	char * pass = NULL;
Packit d14fb6
	int l;
Packit d14fb6
Packit d14fb6
	pass = malloc(21);
Packit d14fb6
	if (pass == NULL) {
Packit d14fb6
		lprintf(LOG_ERR, "ipmitool: malloc failure");
Packit d14fb6
		return NULL;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	memset(pass, 0, 21);
Packit d14fb6
	fp = ipmi_open_file_read((const char *)filename);
Packit d14fb6
	if (fp == NULL) {
Packit d14fb6
		lprintf(LOG_ERR, "Unable to open password file %s",
Packit d14fb6
				filename);
Packit d14fb6
		free(pass);
Packit d14fb6
		return NULL;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* read in id */
Packit d14fb6
	if (fgets(pass, 21, fp) == NULL) {
Packit d14fb6
		lprintf(LOG_ERR, "Unable to read password from file %s",
Packit d14fb6
				filename);
Packit d14fb6
		free(pass);
Packit d14fb6
		fclose(fp);
Packit d14fb6
		return NULL;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
        /* remove traling <cr><nl><tab> */
Packit d14fb6
	l = strcspn(pass, "\r\n\t");
Packit d14fb6
	if (l > 0) {
Packit d14fb6
		pass[l] = '\0';
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	fclose(fp);
Packit d14fb6
	return pass;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
Packit d14fb6
/*
Packit d14fb6
 * Print all the commands in the above table to stderr
Packit d14fb6
 * used for help text on command line and shell
Packit d14fb6
 */
Packit d14fb6
void
Packit d14fb6
ipmi_cmd_print(struct ipmi_cmd * cmdlist)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_cmd * cmd;
Packit d14fb6
	int hdr = 0;
Packit d14fb6
Packit d14fb6
	if (cmdlist == NULL)
Packit d14fb6
		return;
Packit d14fb6
	for (cmd=cmdlist; cmd->func != NULL; cmd++) {
Packit d14fb6
		if (cmd->desc == NULL)
Packit d14fb6
			continue;
Packit d14fb6
		if (hdr == 0) {
Packit d14fb6
			lprintf(LOG_NOTICE, "Commands:");
Packit d14fb6
			hdr = 1;
Packit d14fb6
		}
Packit d14fb6
		lprintf(LOG_NOTICE, "\t%-12s  %s", cmd->name, cmd->desc);
Packit d14fb6
	}
Packit d14fb6
	lprintf(LOG_NOTICE, "");
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/* ipmi_cmd_run - run a command from list based on parameters
Packit d14fb6
 *                called from main()
Packit d14fb6
 *
Packit d14fb6
 *                1. iterate through ipmi_cmd_list matching on name
Packit d14fb6
 *                2. call func() for that command
Packit d14fb6
 *
Packit d14fb6
 * @intf:	ipmi interface
Packit d14fb6
 * @name:	command name
Packit d14fb6
 * @argc:	command argument count
Packit d14fb6
 * @argv:	command argument list
Packit d14fb6
 *
Packit d14fb6
 * returns value from func() of that commnad if found
Packit d14fb6
 * returns -1 if command is not found
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_cmd * cmd = intf->cmdlist;
Packit d14fb6
Packit d14fb6
	/* hook to run a default command if nothing specified */
Packit d14fb6
	if (name == NULL) {
Packit d14fb6
		if (cmd->func == NULL || cmd->name == NULL)
Packit d14fb6
			return -1;
Packit d14fb6
		else if (strncmp(cmd->name, "default", 7) == 0)
Packit d14fb6
			return cmd->func(intf, 0, NULL);
Packit d14fb6
		else {
Packit d14fb6
			lprintf(LOG_ERR, "No command provided!");
Packit d14fb6
			ipmi_cmd_print(intf->cmdlist);
Packit d14fb6
			return -1;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) {
Packit d14fb6
		if (strncmp(name, cmd->name, __maxlen(cmd->name, name)) == 0)
Packit d14fb6
			break;
Packit d14fb6
	}
Packit d14fb6
	if (cmd->func == NULL) {
Packit d14fb6
		cmd = intf->cmdlist;
Packit d14fb6
		if (strncmp(cmd->name, "default", 7) == 0)
Packit d14fb6
			return cmd->func(intf, argc+1, argv-1);
Packit d14fb6
Packit d14fb6
		lprintf(LOG_ERR, "Invalid command: %s", name);
Packit d14fb6
		ipmi_cmd_print(intf->cmdlist);
Packit d14fb6
		return -1;
Packit d14fb6
	}
Packit d14fb6
	return cmd->func(intf, argc, argv);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static void
Packit d14fb6
ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist)
Packit d14fb6
{
Packit d14fb6
	lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION);
Packit d14fb6
	lprintf(LOG_NOTICE, "usage: %s [options...] <command>\n", progname);
Packit d14fb6
	lprintf(LOG_NOTICE, "       -h             This help");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -V             Show version information");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -v             Verbose (can use multiple times)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -c             Display output in comma separated format");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -d N           Specify a /dev/ipmiN device to use (default=0)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -I intf        Interface to use");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -H hostname    Remote host name for LAN interface");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -p port        Remote RMCP port [default=623]");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -U username    Remote session username");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -f file        Read remote session password from file");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -z size        Change Size of Communication Channel (OEM)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -S sdr         Use local file for remote SDR cache");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -D tty:b[:s]   Specify the serial device, baud rate to use");
Packit d14fb6
	lprintf(LOG_NOTICE, "                      and, optionally, specify that interface is the system one");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -4             Use only IPv4");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -6             Use only IPv6");
Packit d14fb6
#ifdef ENABLE_ALL_OPTIONS
Packit d14fb6
	lprintf(LOG_NOTICE, "       -a             Prompt for remote password");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -Y             Prompt for the Kg key for IPMIv2 authentication");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -e char        Set SOL escape character");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -C ciphersuite Cipher suite to be used by lanplus interface");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -k key         Use Kg key for IPMIv2 authentication");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -y hex_key     Use hexadecimal-encoded Kg key for IPMIv2 authentication");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -L level       Remote session privilege level [default=ADMINISTRATOR]");
Packit d14fb6
	lprintf(LOG_NOTICE, "                      Append a '+' to use name/privilege lookup in RAKP1");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -A authtype    Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -P password    Remote session password");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -E             Read password from IPMI_PASSWORD environment variable");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -K             Read kgkey from IPMI_KGKEY environment variable");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -m address     Set local IPMB address");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -b channel     Set destination channel for bridged request");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -t address     Bridge request to remote target address");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -B channel     Set transit channel for bridged request (dual bridge)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -T address     Set transit address for bridge request (dual bridge)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -l lun         Set destination lun for raw commands");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -o oemtype     Setup for OEM (use 'list' to see available OEM types)");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -O seloem      Use file for OEM SEL event descriptions");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -N seconds     Specify timeout for lan [default=2] / lanplus [default=1] interface");
Packit d14fb6
	lprintf(LOG_NOTICE, "       -R retry       Set the number of retries for lan/lanplus interface [default=4]");
Packit d14fb6
#endif
Packit d14fb6
	lprintf(LOG_NOTICE, "");
Packit d14fb6
Packit d14fb6
	ipmi_intf_print(intflist);
Packit d14fb6
Packit d14fb6
	if (cmdlist != NULL)
Packit d14fb6
		ipmi_cmd_print(cmdlist);
Packit d14fb6
}
Packit d14fb6
/* ipmi_catch_sigint  -  Handle the interrupt signal (Ctrl-C), close the
Packit d14fb6
 *                       interface, and exit ipmitool with error (-1)
Packit d14fb6
 *
Packit d14fb6
 *                       This insures that the IOL session gets freed
Packit d14fb6
 *                       for other callers.
Packit d14fb6
 *
Packit d14fb6
 * returns -1
Packit d14fb6
 */
Packit d14fb6
void ipmi_catch_sigint()
Packit d14fb6
{
Packit d14fb6
	if (ipmi_main_intf != NULL) {
Packit d14fb6
		printf("\nSIGN INT: Close Interface %s\n",ipmi_main_intf->desc);
Packit d14fb6
		/* reduce retry count to a single retry */
Packit d14fb6
		ipmi_main_intf->ssn_params.retry = 1;
Packit d14fb6
		/* close interface */
Packit d14fb6
		ipmi_main_intf->close(ipmi_main_intf);
Packit d14fb6
	}
Packit d14fb6
	exit(-1);
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
static uint8_t
Packit d14fb6
ipmi_acquire_ipmb_address(struct ipmi_intf * intf)
Packit d14fb6
{
Packit d14fb6
	if (intf->picmg_avail) {
Packit d14fb6
		return ipmi_picmg_ipmb_address(intf);
Packit d14fb6
	} else if (intf->vita_avail) {
Packit d14fb6
		return ipmi_vita_ipmb_address(intf);
Packit d14fb6
	} else {
Packit d14fb6
		return 0;
Packit d14fb6
    }
Packit d14fb6
}
Packit d14fb6
Packit d14fb6
/* ipmi_parse_options  -  helper function to handle parsing command line options
Packit d14fb6
 *
Packit d14fb6
 * @argc:	count of options
Packit d14fb6
 * @argv:	list of options
Packit d14fb6
 * @cmdlist:	list of supported commands
Packit d14fb6
 * @intflist:	list of supported interfaces
Packit d14fb6
 *
Packit d14fb6
 * returns 0 on success
Packit d14fb6
 * returns -1 on error
Packit d14fb6
 */
Packit d14fb6
int
Packit d14fb6
ipmi_main(int argc, char ** argv,
Packit d14fb6
		struct ipmi_cmd * cmdlist,
Packit d14fb6
		struct ipmi_intf_support * intflist)
Packit d14fb6
{
Packit d14fb6
	struct ipmi_intf_support * sup;
Packit d14fb6
	int privlvl = 0;
Packit d14fb6
	uint8_t target_addr = 0;
Packit d14fb6
	uint8_t target_channel = 0;
Packit d14fb6
Packit 1b63b3
	uint8_t u8tmp = 0;
Packit d14fb6
	uint8_t transit_addr = 0;
Packit d14fb6
	uint8_t transit_channel = 0;
Packit d14fb6
	uint8_t target_lun     = 0;
Packit d14fb6
	uint8_t arg_addr = 0;
Packit d14fb6
	uint8_t addr = 0;
Packit d14fb6
	uint16_t my_long_packet_size=0;
Packit d14fb6
	uint8_t my_long_packet_set=0;
Packit d14fb6
	uint8_t lookupbit = 0x10;	/* use name-only lookup by default */
Packit d14fb6
	int retry = 0;
Packit d14fb6
	uint32_t timeout = 0;
Packit d14fb6
	int authtype = -1;
Packit d14fb6
	char * tmp_pass = NULL;
Packit d14fb6
	char * tmp_env = NULL;
Packit d14fb6
	char * hostname = NULL;
Packit d14fb6
	char * username = NULL;
Packit d14fb6
	char * password = NULL;
Packit d14fb6
	char * intfname = NULL;
Packit d14fb6
	char * progname = NULL;
Packit d14fb6
	char * oemtype  = NULL;
Packit d14fb6
	char * sdrcache = NULL;
Packit d14fb6
	uint8_t kgkey[IPMI_KG_BUFFER_SIZE];
Packit d14fb6
	char * seloem   = NULL;
Packit d14fb6
	int port = 0;
Packit d14fb6
	int devnum = 0;
Packit 1b63b3
#ifdef IPMI_INTF_LANPLUS
Packit 1b63b3
	/* lookup best cipher suite available */
Packit 1b63b3
	enum cipher_suite_ids cipher_suite_id = IPMI_LANPLUS_CIPHER_SUITE_RESERVED;
Packit 1b63b3
#endif /* IPMI_INTF_LANPLUS */
Packit d14fb6
	int argflag, i, found;
Packit d14fb6
	int rc = -1;
Packit d14fb6
	int ai_family = AF_UNSPEC;
Packit d14fb6
	char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
Packit d14fb6
	char * devfile  = NULL;
Packit d14fb6
Packit d14fb6
	/* save program name */
Packit d14fb6
	progname = strrchr(argv[0], '/');
Packit d14fb6
	progname = ((progname == NULL) ? argv[0] : progname+1);
Packit d14fb6
	signal(SIGINT, ipmi_catch_sigint);
Packit d14fb6
	memset(kgkey, 0, sizeof(kgkey));
Packit d14fb6
Packit d14fb6
	while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
Packit d14fb6
	{
Packit d14fb6
		switch (argflag) {
Packit d14fb6
		case 'I':
Packit d14fb6
			if (intfname) {
Packit d14fb6
				free(intfname);
Packit d14fb6
				intfname = NULL;
Packit d14fb6
			}
Packit d14fb6
			intfname = strdup(optarg);
Packit d14fb6
			if (intfname == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			if (intflist != NULL) {
Packit d14fb6
				found = 0;
Packit d14fb6
				for (sup=intflist; sup->name != NULL; sup++) {
Packit d14fb6
					if (strncmp(sup->name, intfname, strlen(intfname)) == 0 &&
Packit d14fb6
							strncmp(sup->name, intfname, strlen(sup->name)) == 0 &&
Packit d14fb6
							sup->supported == 1)
Packit d14fb6
						found = 1;
Packit d14fb6
				}
Packit d14fb6
				if (!found) {
Packit d14fb6
					lprintf(LOG_ERR, "Interface %s not supported", intfname);
Packit d14fb6
					goto out_free;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'h':
Packit d14fb6
			ipmi_option_usage(progname, cmdlist, intflist);
Packit d14fb6
			rc = 0;
Packit d14fb6
			goto out_free;
Packit d14fb6
			break;
Packit d14fb6
		case 'V':
Packit d14fb6
			printf("%s version %s\n", progname, VERSION);
Packit d14fb6
			rc = 0;
Packit d14fb6
			goto out_free;
Packit d14fb6
			break;
Packit d14fb6
		case 'd':
Packit d14fb6
			if (str2int(optarg, &devnum) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-d'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			/* Check if device number is -gt 0; I couldn't find limit for
Packit d14fb6
			 * kernels > 2.6, thus right side is unlimited.
Packit d14fb6
			 */
Packit d14fb6
			if (devnum < 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Device number %i is out of range.", devnum);
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'p':
Packit d14fb6
			if (str2int(optarg, &port) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-p'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			/* Check if port is -gt 0 && port is -lt 65535 */
Packit d14fb6
			if (port < 0 || port > 65535) {
Packit d14fb6
				lprintf(LOG_ERR, "Port number %i is out of range.", port);
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit 1b63b3
#ifdef IPMI_INTF_LANPLUS
Packit d14fb6
		case 'C':
Packit 1b63b3
			/* Cipher Suite ID is a byte as per IPMI specification */
Packit 1b63b3
			if (str2uchar(optarg, &u8tmp) != 0) {
Packit 1b63b3
				lprintf(LOG_ERR, "Invalid parameter given or out of "
Packit 1b63b3
				                 "range [0-255] for '-C'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit 1b63b3
			cipher_suite_id = u8tmp;
Packit d14fb6
			break;
Packit 1b63b3
#endif /* IPMI_INTF_LANPLUS */
Packit d14fb6
		case 'v':
Packit d14fb6
			verbose++;
Packit d14fb6
			break;
Packit d14fb6
		case 'c':
Packit d14fb6
			csv_output = 1;
Packit d14fb6
			break;
Packit d14fb6
		case 'H':
Packit d14fb6
			if (hostname) {
Packit d14fb6
				free(hostname);
Packit d14fb6
				hostname = NULL;
Packit d14fb6
			}
Packit d14fb6
			hostname = strdup(optarg);
Packit d14fb6
			if (hostname == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'f':
Packit d14fb6
			if (password) {
Packit d14fb6
				free(password);
Packit d14fb6
				password = NULL;
Packit d14fb6
			}
Packit d14fb6
			password = ipmi_password_file_read(optarg);
Packit d14fb6
			if (password == NULL)
Packit d14fb6
				lprintf(LOG_ERR, "Unable to read password "
Packit d14fb6
						"from file %s", optarg);
Packit d14fb6
			break;
Packit d14fb6
		case 'a':
Packit d14fb6
#ifdef HAVE_GETPASSPHRASE
Packit d14fb6
			tmp_pass = getpassphrase("Password: ");
Packit d14fb6
#else
Packit d14fb6
			tmp_pass = getpass("Password: ");
Packit d14fb6
#endif
Packit d14fb6
			if (tmp_pass != NULL) {
Packit d14fb6
				if (password) {
Packit d14fb6
					free(password);
Packit d14fb6
					password = NULL;
Packit d14fb6
				}
Packit d14fb6
				password = strdup(tmp_pass);
Packit d14fb6
				tmp_pass = NULL;
Packit d14fb6
				if (password == NULL) {
Packit d14fb6
					lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
					goto out_free;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'k':
Packit d14fb6
			memset(kgkey, 0, sizeof(kgkey));
Packit d14fb6
			strncpy((char *)kgkey, optarg, sizeof(kgkey) - 1);
Packit d14fb6
			break;
Packit d14fb6
		case 'K':
Packit d14fb6
			if ((tmp_env = getenv("IPMI_KGKEY"))) {
Packit d14fb6
				memset(kgkey, 0, sizeof(kgkey));
Packit d14fb6
				strncpy((char *)kgkey, tmp_env,
Packit d14fb6
					sizeof(kgkey) - 1);
Packit d14fb6
			} else {
Packit d14fb6
				lprintf(LOG_WARN, "Unable to read kgkey from environment");
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'y':
Packit d14fb6
			memset(kgkey, 0, sizeof(kgkey));
Packit d14fb6
Packit d14fb6
			rc = ipmi_parse_hex(optarg, kgkey, sizeof(kgkey) - 1);
Packit d14fb6
			if (rc == -1) {
Packit d14fb6
				lprintf(LOG_ERR, "Number of Kg key characters is not even");
Packit d14fb6
				goto out_free;
Packit d14fb6
			} else if (rc == -3) {
Packit d14fb6
				lprintf(LOG_ERR, "Kg key is not hexadecimal number");
Packit d14fb6
				goto out_free;
Packit d14fb6
			} else if (rc > (IPMI_KG_BUFFER_SIZE-1)) {
Packit d14fb6
				lprintf(LOG_ERR, "Kg key is too long");
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'Y':
Packit d14fb6
#ifdef HAVE_GETPASSPHRASE
Packit d14fb6
			tmp_pass = getpassphrase("Key: ");
Packit d14fb6
#else
Packit d14fb6
			tmp_pass = getpass("Key: ");
Packit d14fb6
#endif
Packit d14fb6
			if (tmp_pass != NULL) {
Packit d14fb6
				memset(kgkey, 0, sizeof(kgkey));
Packit d14fb6
				strncpy((char *)kgkey, tmp_pass,
Packit d14fb6
					sizeof(kgkey) - 1);
Packit d14fb6
				tmp_pass = NULL;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'U':
Packit d14fb6
			if (username) {
Packit d14fb6
				free(username);
Packit d14fb6
				username = NULL;
Packit d14fb6
			}
Packit d14fb6
			if (strlen(optarg) > 16) {
Packit d14fb6
				lprintf(LOG_ERR, "Username is too long (> 16 bytes)");
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			username = strdup(optarg);
Packit d14fb6
			if (username == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'S':
Packit d14fb6
			if (sdrcache) {
Packit d14fb6
				free(sdrcache);
Packit d14fb6
				sdrcache = NULL;
Packit d14fb6
			}
Packit d14fb6
			sdrcache = strdup(optarg);
Packit d14fb6
			if (sdrcache == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'D':
Packit d14fb6
			/* check for subsequent instance of -D */
Packit d14fb6
			if (devfile) {
Packit d14fb6
				/* free memory for previous string */
Packit d14fb6
				free(devfile);
Packit d14fb6
			}
Packit d14fb6
			devfile = strdup(optarg);
Packit d14fb6
			if (devfile == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case '4':
Packit d14fb6
			/* IPv4 only */
Packit d14fb6
			if (ai_family == AF_UNSPEC) {
Packit d14fb6
				ai_family = AF_INET;
Packit d14fb6
			} else {
Packit d14fb6
				if (ai_family == AF_INET6) {
Packit d14fb6
					lprintf(LOG_ERR,
Packit d14fb6
						"Parameter is mutually exclusive with -6.");
Packit d14fb6
				} else {
Packit d14fb6
					lprintf(LOG_ERR,
Packit d14fb6
						"Multiple -4 parameters given.");
Packit d14fb6
				}
Packit d14fb6
				rc = (-1);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case '6':
Packit d14fb6
			/* IPv6 only */
Packit d14fb6
			if (ai_family == AF_UNSPEC) {
Packit d14fb6
				ai_family = AF_INET6;
Packit d14fb6
			} else {
Packit d14fb6
				if (ai_family == AF_INET) {
Packit d14fb6
					lprintf(LOG_ERR,
Packit d14fb6
						"Parameter is mutually exclusive with -4.");
Packit d14fb6
				} else {
Packit d14fb6
					lprintf(LOG_ERR,
Packit d14fb6
						"Multiple -6 parameters given.");
Packit d14fb6
				}
Packit d14fb6
				rc = (-1);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
#ifdef ENABLE_ALL_OPTIONS
Packit d14fb6
		case 'o':
Packit d14fb6
			if (oemtype) {
Packit d14fb6
				free(oemtype);
Packit d14fb6
				oemtype = NULL;
Packit d14fb6
			}
Packit d14fb6
			oemtype = strdup(optarg);
Packit d14fb6
			if (oemtype == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			if (strncmp(oemtype, "list", 4) == 0 ||
Packit d14fb6
					strncmp(oemtype, "help", 4) == 0) {
Packit d14fb6
				ipmi_oem_print();
Packit d14fb6
				rc = 0;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'g':
Packit d14fb6
			/* backwards compatible oem hack */
Packit d14fb6
			if (oemtype) {
Packit d14fb6
				free(oemtype);
Packit d14fb6
				oemtype = NULL;
Packit d14fb6
			}
Packit d14fb6
			oemtype = strdup("intelwv2");
Packit d14fb6
			break;
Packit d14fb6
		case 's':
Packit d14fb6
			/* backwards compatible oem hack */
Packit d14fb6
			if (oemtype) {
Packit d14fb6
				free(oemtype);
Packit d14fb6
				oemtype = NULL;
Packit d14fb6
			}
Packit d14fb6
			oemtype = strdup("supermicro");
Packit d14fb6
			break;
Packit d14fb6
		case 'P':
Packit d14fb6
			if (password) {
Packit d14fb6
				free(password);
Packit d14fb6
				password = NULL;
Packit d14fb6
			}
Packit d14fb6
			password = strdup(optarg);
Packit d14fb6
			if (password == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
Packit d14fb6
			/* Prevent password snooping with ps */
Packit d14fb6
			i = strlen(optarg);
Packit d14fb6
			memset(optarg, 'X', i);
Packit d14fb6
			break;
Packit d14fb6
		case 'E':
Packit d14fb6
			if ((tmp_env = getenv("IPMITOOL_PASSWORD"))) {
Packit d14fb6
				if (password) {
Packit d14fb6
					free(password);
Packit d14fb6
					password = NULL;
Packit d14fb6
				}
Packit d14fb6
				password = strdup(tmp_env);
Packit d14fb6
				if (password == NULL) {
Packit d14fb6
					lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
					goto out_free;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			else if ((tmp_env = getenv("IPMI_PASSWORD"))) {
Packit d14fb6
				if (password) {
Packit d14fb6
					free(password);
Packit d14fb6
					password = NULL;
Packit d14fb6
				}
Packit d14fb6
				password = strdup(tmp_env);
Packit d14fb6
				if (password == NULL) {
Packit d14fb6
					lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
					goto out_free;
Packit d14fb6
				}
Packit d14fb6
			}
Packit d14fb6
			else {
Packit d14fb6
				lprintf(LOG_WARN, "Unable to read password from environment");
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'L':
Packit d14fb6
			i = strlen(optarg);
Packit d14fb6
			if ((i > 0) && (optarg[i-1] == '+')) {
Packit d14fb6
				lookupbit = 0;
Packit d14fb6
				optarg[i-1] = 0;
Packit d14fb6
			}
Packit d14fb6
			privlvl = str2val(optarg, ipmi_privlvl_vals);
Packit d14fb6
			if (privlvl == 0xFF) {
Packit d14fb6
				lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'A':
Packit d14fb6
			authtype = str2val(optarg, ipmi_authtype_session_vals);
Packit d14fb6
			break;
Packit d14fb6
		case 't':
Packit d14fb6
			if (str2uchar(optarg, &target_addr) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-t'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'b':
Packit d14fb6
			if (str2uchar(optarg, &target_channel) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-b'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'T':
Packit d14fb6
			if (str2uchar(optarg, &transit_addr) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-T'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'B':
Packit d14fb6
			if (str2uchar(optarg, &transit_channel) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-B'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'l':
Packit d14fb6
			if (str2uchar(optarg, &target_lun) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-l'.");
Packit d14fb6
				rc = 1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'm':
Packit d14fb6
			if (str2uchar(optarg, &arg_addr) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-m'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'e':
Packit d14fb6
			sol_escape_char = optarg[0];
Packit d14fb6
			break;
Packit d14fb6
		case 'O':
Packit d14fb6
			if (seloem) {
Packit d14fb6
				free(seloem);
Packit d14fb6
				seloem = NULL;
Packit d14fb6
			}
Packit d14fb6
			seloem = strdup(optarg);
Packit d14fb6
			if (seloem == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'z':
Packit d14fb6
			if (str2ushort(optarg, &my_long_packet_size) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-z'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		/* Retry and Timeout */
Packit d14fb6
		case 'R':
Packit d14fb6
			if (str2int(optarg, &retry) != 0 || retry < 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-R'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
		case 'N':
Packit d14fb6
			if (str2uint(optarg, &timeout) != 0) {
Packit d14fb6
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-N'.");
Packit d14fb6
				rc = -1;
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
			break;
Packit d14fb6
#endif
Packit d14fb6
		default:
Packit d14fb6
			ipmi_option_usage(progname, cmdlist, intflist);
Packit d14fb6
			goto out_free;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* check for command before doing anything */
Packit d14fb6
	if (argc-optind > 0 &&
Packit d14fb6
			strncmp(argv[optind], "help", 4) == 0) {
Packit d14fb6
		ipmi_cmd_print(cmdlist);
Packit d14fb6
		rc = 0;
Packit d14fb6
		goto out_free;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * If the user has specified a hostname (-H option)
Packit d14fb6
	 * then this is a remote access session.
Packit d14fb6
	 *
Packit d14fb6
	 * If no password was specified by any other method
Packit d14fb6
	 * and the authtype was not explicitly set to NONE
Packit d14fb6
	 * then prompt the user.
Packit d14fb6
	 */
Packit d14fb6
	if (hostname != NULL && password == NULL &&
Packit d14fb6
			(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
Packit d14fb6
#ifdef HAVE_GETPASSPHRASE
Packit d14fb6
		tmp_pass = getpassphrase("Password: ");
Packit d14fb6
#else
Packit d14fb6
		tmp_pass = getpass("Password: ");
Packit d14fb6
#endif
Packit d14fb6
		if (tmp_pass != NULL) {
Packit d14fb6
			password = strdup(tmp_pass);
Packit d14fb6
			tmp_pass = NULL;
Packit d14fb6
			if (password == NULL) {
Packit d14fb6
				lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
				goto out_free;
Packit d14fb6
			}
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* if no interface was specified but a
Packit d14fb6
	 * hostname was then use LAN by default
Packit d14fb6
	 * otherwise the default is hardcoded
Packit d14fb6
	 * to use the first entry in the list
Packit d14fb6
	 */
Packit d14fb6
	if (intfname == NULL && hostname != NULL) {
Packit d14fb6
		intfname = strdup("lan");
Packit d14fb6
		if (intfname == NULL) {
Packit d14fb6
			lprintf(LOG_ERR, "%s: malloc failure", progname);
Packit d14fb6
			goto out_free;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (password != NULL && intfname != NULL) {
Packit d14fb6
		if (strcmp(intfname, "lan") == 0 && strlen(password) > 16) {
Packit d14fb6
			lprintf(LOG_ERR, "%s: password is longer than 16 bytes.", intfname);
Packit d14fb6
			rc = -1;
Packit d14fb6
			goto out_free;
Packit d14fb6
		} else if (strcmp(intfname, "lanplus") == 0 && strlen(password) > 20) {
Packit d14fb6
			lprintf(LOG_ERR, "%s: password is longer than 20 bytes.", intfname);
Packit d14fb6
			rc = -1;
Packit d14fb6
			goto out_free;
Packit d14fb6
		}
Packit d14fb6
	} /* if (password != NULL && intfname != NULL) */
Packit d14fb6
Packit d14fb6
	/* load interface */
Packit d14fb6
	ipmi_main_intf = ipmi_intf_load(intfname);
Packit d14fb6
	if (ipmi_main_intf == NULL) {
Packit d14fb6
		lprintf(LOG_ERR, "Error loading interface %s", intfname);
Packit d14fb6
		goto out_free;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* setup log */
Packit d14fb6
	log_init(progname, 0, verbose);
Packit d14fb6
Packit d14fb6
	/* run OEM setup if found */
Packit d14fb6
	if (oemtype != NULL &&
Packit d14fb6
	    ipmi_oem_setup(ipmi_main_intf, oemtype) < 0) {
Packit d14fb6
		lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
Packit d14fb6
		goto out_free;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* set session variables */
Packit d14fb6
	if (hostname != NULL)
Packit d14fb6
		ipmi_intf_session_set_hostname(ipmi_main_intf, hostname);
Packit d14fb6
	if (username != NULL)
Packit d14fb6
		ipmi_intf_session_set_username(ipmi_main_intf, username);
Packit d14fb6
	if (password != NULL)
Packit d14fb6
		ipmi_intf_session_set_password(ipmi_main_intf, password);
Packit d14fb6
	ipmi_intf_session_set_kgkey(ipmi_main_intf, kgkey);
Packit d14fb6
	if (port > 0)
Packit d14fb6
		ipmi_intf_session_set_port(ipmi_main_intf, port);
Packit d14fb6
	if (authtype >= 0)
Packit d14fb6
		ipmi_intf_session_set_authtype(ipmi_main_intf, (uint8_t)authtype);
Packit d14fb6
	if (privlvl > 0)
Packit d14fb6
		ipmi_intf_session_set_privlvl(ipmi_main_intf, (uint8_t)privlvl);
Packit d14fb6
	else
Packit d14fb6
		ipmi_intf_session_set_privlvl(ipmi_main_intf,
Packit d14fb6
				IPMI_SESSION_PRIV_ADMIN);	/* default */
Packit d14fb6
	/* Adding retry and timeout for interface that support it */
Packit d14fb6
	if (retry > 0)
Packit d14fb6
		ipmi_intf_session_set_retry(ipmi_main_intf, retry);
Packit d14fb6
	if (timeout > 0)
Packit d14fb6
		ipmi_intf_session_set_timeout(ipmi_main_intf, timeout);
Packit d14fb6
Packit d14fb6
	ipmi_intf_session_set_lookupbit(ipmi_main_intf, lookupbit);
Packit d14fb6
	ipmi_intf_session_set_sol_escape_char(ipmi_main_intf, sol_escape_char);
Packit 1b63b3
#ifdef IPMI_INTF_LANPLUS
Packit d14fb6
	ipmi_intf_session_set_cipher_suite_id(ipmi_main_intf, cipher_suite_id);
Packit 1b63b3
#endif /* IPMI_INTF_LANPLUS */
Packit d14fb6
Packit d14fb6
	ipmi_main_intf->devnum = devnum;
Packit d14fb6
Packit d14fb6
	/* setup device file if given */
Packit d14fb6
	ipmi_main_intf->devfile = devfile;
Packit d14fb6
Packit d14fb6
	ipmi_main_intf->ai_family = ai_family;
Packit d14fb6
	/* Open the interface with the specified or default IPMB address */
Packit d14fb6
	ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
Packit d14fb6
	if (ipmi_main_intf->open != NULL) {
Packit d14fb6
		if (ipmi_main_intf->open(ipmi_main_intf) < 0) {
Packit d14fb6
			goto out_free;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) {
Packit d14fb6
		/*
Packit d14fb6
		 * Attempt picmg/vita discovery of the actual interface
Packit d14fb6
		 * address, unless the users specified an address.
Packit d14fb6
		 * Address specification always overrides discovery
Packit d14fb6
		 */
Packit d14fb6
		if (picmg_discover(ipmi_main_intf)) {
Packit d14fb6
			ipmi_main_intf->picmg_avail = 1;
Packit d14fb6
		} else if (vita_discover(ipmi_main_intf)) {
Packit d14fb6
			ipmi_main_intf->vita_avail = 1;
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	if (arg_addr) {
Packit d14fb6
		addr = arg_addr;
Packit d14fb6
	} else if (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) {
Packit d14fb6
		lprintf(LOG_DEBUG, "Acquire IPMB address");
Packit d14fb6
		addr = ipmi_acquire_ipmb_address(ipmi_main_intf);
Packit d14fb6
		lprintf(LOG_INFO,  "Discovered IPMB address 0x%x", addr);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/*
Packit d14fb6
	 * If we discovered the ipmb address and it is not the same as what we
Packit d14fb6
	 * used for open, Set the discovered IPMB address as my address if the
Packit d14fb6
	 * interface supports it.
Packit d14fb6
	 */
Packit d14fb6
	if (addr != 0 && addr != ipmi_main_intf->my_addr) {
Packit d14fb6
		if (ipmi_main_intf->set_my_addr) {
Packit d14fb6
			/*
Packit d14fb6
			 * Some interfaces need special handling
Packit d14fb6
			 * when changing local address
Packit d14fb6
			 */
Packit d14fb6
			(void)ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
Packit d14fb6
		}
Packit d14fb6
Packit d14fb6
		/* set local address */
Packit d14fb6
		ipmi_main_intf->my_addr = addr;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	ipmi_main_intf->target_addr = ipmi_main_intf->my_addr;
Packit d14fb6
Packit d14fb6
	/* If bridging addresses are specified, handle them */
Packit d14fb6
	if (transit_addr > 0 || target_addr > 0) {
Packit d14fb6
		/* sanity check, transit makes no sense without a target */
Packit d14fb6
		if ((transit_addr != 0 || transit_channel != 0) &&
Packit d14fb6
			target_addr == 0) {
Packit d14fb6
			lprintf(LOG_ERR,
Packit d14fb6
				"Transit address/channel %#x/%#x ignored. "
Packit d14fb6
				"Target address must be specified!",
Packit d14fb6
				transit_addr, transit_channel);
Packit d14fb6
			goto out_free;
Packit d14fb6
		}
Packit d14fb6
		ipmi_main_intf->target_addr = target_addr;
Packit d14fb6
		ipmi_main_intf->target_channel = target_channel ;
Packit d14fb6
Packit d14fb6
		ipmi_main_intf->transit_addr    = transit_addr;
Packit d14fb6
		ipmi_main_intf->transit_channel = transit_channel;
Packit d14fb6
Packit d14fb6
Packit d14fb6
		/* must be admin level to do this over lan */
Packit d14fb6
		ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
Packit d14fb6
		/* Get the ipmb address of the targeted entity */
Packit d14fb6
		ipmi_main_intf->target_ipmb_addr =
Packit d14fb6
					ipmi_acquire_ipmb_address(ipmi_main_intf);
Packit d14fb6
		lprintf(LOG_DEBUG, "Specified addressing     Target  %#x:%#x Transit %#x:%#x",
Packit d14fb6
					   ipmi_main_intf->target_addr,
Packit d14fb6
					   ipmi_main_intf->target_channel,
Packit d14fb6
					   ipmi_main_intf->transit_addr,
Packit d14fb6
					   ipmi_main_intf->transit_channel);
Packit d14fb6
		if (ipmi_main_intf->target_ipmb_addr) {
Packit d14fb6
			lprintf(LOG_INFO, "Discovered Target IPMB-0 address %#x",
Packit d14fb6
					   ipmi_main_intf->target_ipmb_addr);
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* set target LUN (for RAW command) */
Packit d14fb6
	ipmi_main_intf->target_lun = target_lun ;
Packit d14fb6
Packit d14fb6
	lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
Packit d14fb6
			   "transit %#x:%#x target %#x:%#x "
Packit d14fb6
			   "ipmb_target %#x\n",
Packit d14fb6
			ipmi_main_intf->my_addr,
Packit d14fb6
			ipmi_main_intf->transit_addr,
Packit d14fb6
			ipmi_main_intf->transit_channel,
Packit d14fb6
			ipmi_main_intf->target_addr,
Packit d14fb6
			ipmi_main_intf->target_channel,
Packit d14fb6
			ipmi_main_intf->target_ipmb_addr);
Packit d14fb6
Packit d14fb6
	/* parse local SDR cache if given */
Packit d14fb6
	if (sdrcache != NULL) {
Packit d14fb6
		ipmi_sdr_list_cache_fromfile(ipmi_main_intf, sdrcache);
Packit d14fb6
	}
Packit d14fb6
	/* Parse SEL OEM file if given */
Packit d14fb6
	if (seloem != NULL) {
Packit d14fb6
		ipmi_sel_oem_init(seloem);
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* Enable Big Buffer when requested */
Packit d14fb6
	if ( my_long_packet_size != 0 ) {
Packit d14fb6
		/* Enable Big Buffer when requested */
Packit d14fb6
		if (!ipmi_oem_active(ipmi_main_intf, "kontron") ||
Packit d14fb6
			ipmi_kontronoem_set_large_buffer(ipmi_main_intf,
Packit d14fb6
					my_long_packet_size ) == 0) {
Packit d14fb6
			printf("Setting large buffer to %i\n", my_long_packet_size);
Packit d14fb6
			my_long_packet_set = 1;
Packit d14fb6
			ipmi_intf_set_max_request_data_size(ipmi_main_intf,
Packit d14fb6
					my_long_packet_size);
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	ipmi_main_intf->cmdlist = cmdlist;
Packit d14fb6
Packit d14fb6
	/* now we finally run the command */
Packit d14fb6
	if (argc-optind > 0)
Packit d14fb6
		rc = ipmi_cmd_run(ipmi_main_intf, argv[optind], argc-optind-1,
Packit d14fb6
				&(argv[optind+1]));
Packit d14fb6
	else
Packit d14fb6
		rc = ipmi_cmd_run(ipmi_main_intf, NULL, 0, NULL);
Packit d14fb6
Packit d14fb6
	if (my_long_packet_set == 1) {
Packit d14fb6
		if (ipmi_oem_active(ipmi_main_intf, "kontron")) {
Packit d14fb6
			/* Restore defaults */
Packit d14fb6
			ipmi_kontronoem_set_large_buffer( ipmi_main_intf, 0 );
Packit d14fb6
		}
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	/* clean repository caches */
Packit d14fb6
	ipmi_cleanup(ipmi_main_intf);
Packit d14fb6
Packit d14fb6
	/* call interface close function if available */
Packit d14fb6
	if (ipmi_main_intf->opened > 0 && ipmi_main_intf->close != NULL)
Packit d14fb6
		ipmi_main_intf->close(ipmi_main_intf);
Packit d14fb6
Packit d14fb6
	out_free:
Packit d14fb6
	log_halt();
Packit d14fb6
Packit d14fb6
	if (intfname != NULL) {
Packit d14fb6
		free(intfname);
Packit d14fb6
		intfname = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (hostname != NULL) {
Packit d14fb6
		free(hostname);
Packit d14fb6
		hostname = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (username != NULL) {
Packit d14fb6
		free(username);
Packit d14fb6
		username = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (password != NULL) {
Packit d14fb6
		free(password);
Packit d14fb6
		password = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (oemtype != NULL) {
Packit d14fb6
		free(oemtype);
Packit d14fb6
		oemtype = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (seloem != NULL) {
Packit d14fb6
		free(seloem);
Packit d14fb6
		seloem = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (sdrcache != NULL) {
Packit d14fb6
		free(sdrcache);
Packit d14fb6
		sdrcache = NULL;
Packit d14fb6
	}
Packit d14fb6
	if (devfile) {
Packit d14fb6
		free(devfile);
Packit d14fb6
		devfile = NULL;
Packit d14fb6
	}
Packit d14fb6
Packit d14fb6
	return rc;
Packit d14fb6
}
Packit d14fb6
Packit d14fb6