Exemple #1
0
/* ipmi_cmd_run - run a command from list based on parameters
 *                called from main()
 *
 *                1. iterate through ipmi_cmd_list matching on name
 *                2. call func() for that command
 *
 * @intf:	ipmi interface
 * @name:	command name
 * @argc:	command argument count
 * @argv:	command argument list
 *
 * returns value from func() of that commnad if found
 * returns -1 if command is not found
 */
int
ipmi_cmd_run(struct ipmi_intf * intf, char * name, int argc, char ** argv)
{
	struct ipmi_cmd * cmd = intf->cmdlist;

	/* hook to run a default command if nothing specified */
	if (name == NULL) {
		if (cmd->func == NULL || cmd->name == NULL)
			return -1;
		else if (strncmp(cmd->name, "default", 7) == 0)
			return cmd->func(intf, 0, NULL);
		else {
			lprintf(LOG_ERR, "No command provided!");
			ipmi_cmd_print(intf->cmdlist);
			return -1;
		}
	}

	for (cmd=intf->cmdlist; cmd->func != NULL; cmd++) {
		if (strncmp(name, cmd->name, __maxlen(cmd->name, name)) == 0)
			break;
	}
	if (cmd->func == NULL) {
		cmd = intf->cmdlist;
		if (strncmp(cmd->name, "default", 7) == 0)
			return cmd->func(intf, argc+1, argv-1);

		lprintf(LOG_ERR, "Invalid command: %s", name);
		ipmi_cmd_print(intf->cmdlist);
		return -1;
	}
	return cmd->func(intf, argc, argv);
}
Exemple #2
0
static void
ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_intf_support * intflist)
{
	lprintf(LOG_NOTICE, "%s version %s\n", progname, VERSION);
	lprintf(LOG_NOTICE, "usage: %s [options...] <command>\n", progname);
	lprintf(LOG_NOTICE, "       -h             This help");
	lprintf(LOG_NOTICE, "       -V             Show version information");
	lprintf(LOG_NOTICE, "       -v             Verbose (can use multiple times)");
	lprintf(LOG_NOTICE, "       -c             Display output in comma separated format");
	lprintf(LOG_NOTICE, "       -d N           Specify a /dev/ipmiN device to use (default=0)");
	lprintf(LOG_NOTICE, "       -I intf        Interface to use");
	lprintf(LOG_NOTICE, "       -H hostname    Remote host name for LAN interface");
	lprintf(LOG_NOTICE, "       -p port        Remote RMCP port [default=623]");
	lprintf(LOG_NOTICE, "       -U username    Remote session username");
	lprintf(LOG_NOTICE, "       -f file        Read remote session password from file");
	lprintf(LOG_NOTICE, "       -z size        Change Size of Communication Channel (OEM)");
	lprintf(LOG_NOTICE, "       -S sdr         Use local file for remote SDR cache");
	lprintf(LOG_NOTICE, "       -D tty:b[:s]   Specify the serial device, baud rate to use");
	lprintf(LOG_NOTICE, "                      and, optionally, specify that interface is the system one");
#ifdef ENABLE_ALL_OPTIONS
	lprintf(LOG_NOTICE, "       -a             Prompt for remote password");
	lprintf(LOG_NOTICE, "       -Y             Prompt for the Kg key for IPMIv2 authentication");
	lprintf(LOG_NOTICE, "       -e char        Set SOL escape character");
	lprintf(LOG_NOTICE, "       -C ciphersuite Cipher suite to be used by lanplus interface");
	lprintf(LOG_NOTICE, "       -k key         Use Kg key for IPMIv2 authentication");
	lprintf(LOG_NOTICE, "       -y hex_key     Use hexadecimal-encoded Kg key for IPMIv2 authentication");
	lprintf(LOG_NOTICE, "       -L level       Remote session privilege level [default=ADMINISTRATOR]");
	lprintf(LOG_NOTICE, "                      Append a '+' to use name/privilege lookup in RAKP1");
	lprintf(LOG_NOTICE, "       -A authtype    Force use of auth type NONE, PASSWORD, MD2, MD5 or OEM");
	lprintf(LOG_NOTICE, "       -P password    Remote session password");
	lprintf(LOG_NOTICE, "       -E             Read password from IPMI_PASSWORD environment variable");
	lprintf(LOG_NOTICE, "       -K             Read kgkey from IPMI_KGKEY environment variable");
	lprintf(LOG_NOTICE, "       -m address     Set local IPMB address");
	lprintf(LOG_NOTICE, "       -b channel     Set destination channel for bridged request");
	lprintf(LOG_NOTICE, "       -t address     Bridge request to remote target address");
	lprintf(LOG_NOTICE, "       -B channel     Set transit channel for bridged request (dual bridge)");
	lprintf(LOG_NOTICE, "       -T address     Set transit address for bridge request (dual bridge)");
	lprintf(LOG_NOTICE, "       -l lun         Set destination lun for raw commands");
	lprintf(LOG_NOTICE, "       -o oemtype     Setup for OEM (use 'list' to see available OEM types)");
	lprintf(LOG_NOTICE, "       -O seloem      Use file for OEM SEL event descriptions");
	lprintf(LOG_NOTICE, "       -N seconds     Specify timeout for lan [default=2] / lanplus [default=1] interface");
	lprintf(LOG_NOTICE, "       -R retry       Set the number of retries for lan/lanplus interface [default=4]");
#endif
	lprintf(LOG_NOTICE, "");

	ipmi_intf_print(intflist);

	if (cmdlist != NULL)
		ipmi_cmd_print(cmdlist);
}
Exemple #3
0
int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv)
{
    char *ptr, *pbuf, **ap, *__argv[EXEC_ARG_SIZE];
    int __argc, rc=0;

    rl_readline_name = "ipmitool";

    /* this essentially disables command completion
     * until its implemented right, otherwise we get
     * the current directory contents... */
    rl_bind_key('\t', rl_insert);

    if (intf->keepalive) {
        /* hook to keep lan sessions active */
        shell_intf = intf;
        rl_event_hook = rl_event_keepalive;
#if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION >= 0x0402
        /* There is a bug in readline 4.2 and later (at least on FreeBSD and NetBSD):
         * timeout equal or greater than 1 second causes an infinite loop. */
        rl_set_keyboard_input_timeout(1000 * 1000 - 1);
#endif
    }

    while ((pbuf = (char *)readline(RL_PROMPT)) != NULL) {
        if (strlen(pbuf) == 0) {
            free(pbuf);
            continue;
        }
        if (strncmp(pbuf, "quit", 4) == 0 ||
                strncmp(pbuf, "exit", 4) == 0) {
            free(pbuf);
            return 0;
        }
        if (strncmp(pbuf, "help", 4) == 0 ||
                strncmp(pbuf, "?", 1) == 0) {
            ipmi_cmd_print(intf->cmdlist);
            free(pbuf);
            continue;
        }

        /* for the all-important up arrow :) */
        add_history(pbuf);

        /* change "" and '' with spaces in the middle to ~ */
        ptr = pbuf;
        while (*ptr != '\0') {
            if (*ptr == '"') {
                ptr++;
                while (*ptr != '"') {
                    if (isspace((int)*ptr))
                        *ptr = '~';
                    ptr++;
                }
            }
            if (*ptr == '\'') {
                ptr++;
                while (*ptr != '\'') {
                    if (isspace((int)*ptr))
                        *ptr = '~';
                    ptr++;
                }
            }
            ptr++;
        }

        __argc = 0;
        ap = __argv;

        for (*ap = strtok(pbuf, " \t");
                *ap != NULL;
                *ap = strtok(NULL, " \t")) {
            __argc++;

            ptr = *ap;
            if (*ptr == '\'') {
                memmove(ptr, ptr+1, strlen(ptr));
                while (*ptr != '\'') {
                    if (*ptr == '~')
                        *ptr = ' ';
                    ptr++;
                }
                *ptr = '\0';
            }
            if (*ptr == '"') {
                memmove(ptr, ptr+1, strlen(ptr));
                while (*ptr != '"') {
                    if (*ptr == '~')
                        *ptr = ' ';
                    ptr++;
                }
                *ptr = '\0';
            }

            if (**ap != '\0') {
                if (++ap >= &__argv[EXEC_ARG_SIZE])
                    break;
            }
        }

        if (__argc && __argv[0])
            rc = ipmi_cmd_run(intf,
                              __argv[0],
                              __argc-1,
                              &(__argv[1]));

        free(pbuf);
    }
    printf("\n");
    return rc;
}
Exemple #4
0
/* ipmi_parse_options  -  helper function to handle parsing command line options
 *
 * @argc:	count of options
 * @argv:	list of options
 * @cmdlist:	list of supported commands
 * @intflist:	list of supported interfaces
 *
 * returns 0 on success
 * returns -1 on error
 */
int
ipmi_main(int argc, char ** argv,
		struct ipmi_cmd * cmdlist,
		struct ipmi_intf_support * intflist)
{
	struct ipmi_intf_support * sup;
	int privlvl = 0;
	uint8_t target_addr = 0;
	uint8_t target_channel = 0;

	uint8_t transit_addr = 0;
	uint8_t transit_channel = 0;
	uint8_t target_lun     = 0;
	uint8_t arg_addr = 0, addr;
	uint16_t my_long_packet_size=0;
	uint8_t my_long_packet_set=0;
	uint8_t lookupbit = 0x10;	/* use name-only lookup by default */
	int retry = 0;
	uint32_t timeout = 0;
	int authtype = -1;
	char * tmp_pass = NULL;
	char * tmp_env = NULL;
	char * hostname = NULL;
	char * username = NULL;
	char * password = NULL;
	char * intfname = NULL;
	char * progname = NULL;
	char * oemtype  = NULL;
	char * sdrcache = NULL;
	unsigned char * kgkey = NULL;
	char * seloem   = NULL;
	int port = 0;
	int devnum = 0;
	int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */
	int argflag, i, found;
	int rc = -1;
	char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT;
	char * devfile  = NULL;

	/* save program name */
	progname = strrchr(argv[0], '/');
	progname = ((progname == NULL) ? argv[0] : progname+1);
	signal(SIGINT, ipmi_catch_sigint);

	while ((argflag = getopt(argc, (char **)argv, OPTION_STRING)) != -1)
	{
		switch (argflag) {
		case 'I':
			if (intfname) {
				free(intfname);
				intfname = NULL;
			}
			intfname = strdup(optarg);
			if (intfname == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			if (intflist != NULL) {
				found = 0;
				for (sup=intflist; sup->name != NULL; sup++) {
					if (strncmp(sup->name, intfname, strlen(intfname)) == 0 &&
							strncmp(sup->name, intfname, strlen(sup->name)) == 0 &&
							sup->supported == 1)
						found = 1;
				}
				if (!found) {
					lprintf(LOG_ERR, "Interface %s not supported", intfname);
					goto out_free;
				}
			}
			break;
		case 'h':
			ipmi_option_usage(progname, cmdlist, intflist);
			rc = 0;
			goto out_free;
			break;
		case 'V':
			printf("%s version %s\n", progname, VERSION);
			rc = 0;
			goto out_free;
			break;
		case 'd':
			if (str2int(optarg, &devnum) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-d'.");
				rc = -1;
				goto out_free;
			}
			/* Check if device number is -gt 0; I couldn't find limit for
			 * kernels > 2.6, thus right side is unlimited.
			 */
			if (devnum < 0) {
				lprintf(LOG_ERR, "Device number %i is out of range.", devnum);
				rc = -1;
				goto out_free;
			}
			break;
		case 'p':
			if (str2int(optarg, &port) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-p'.");
				rc = -1;
				goto out_free;
			}
			/* Check if port is -gt 0 && port is -lt 65535 */
			if (port < 0 || port > 65535) {
				lprintf(LOG_ERR, "Port number %i is out of range.", port);
				rc = -1;
				goto out_free;
			}
			break;
		case 'C':
			if (str2int(optarg, &cipher_suite_id) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-C'.");
				rc = -1;
				goto out_free;
			}
			/* add check Cipher is -gt 0 */
			if (cipher_suite_id < 0) {
				lprintf(LOG_ERR, "Cipher suite ID %i is invalid.", cipher_suite_id);
				rc = -1;
				goto out_free;
			}
			break;
		case 'v':
			verbose++;
			break;
		case 'c':
			csv_output = 1;
			break;
		case 'H':
			if (hostname) {
				free(hostname);
				hostname = NULL;
			}
			hostname = strdup(optarg);
			if (hostname == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
		case 'f':
			if (password) {
				free(password);
				password = NULL;
			}
			password = ipmi_password_file_read(optarg);
			if (password == NULL)
				lprintf(LOG_ERR, "Unable to read password "
						"from file %s", optarg);
			break;
		case 'a':
#ifdef HAVE_GETPASSPHRASE
			tmp_pass = getpassphrase("Password: "******"Password: "******"%s: malloc failure", progname);
					goto out_free;
				}
			}
			break;
		case 'k':
			if (kgkey) {
				free(kgkey);
				kgkey = NULL;
			}
			kgkey = strdup(optarg);
			if (kgkey == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
		case 'K':
			if ((tmp_env = getenv("IPMI_KGKEY"))) {
				if (kgkey) {
					free(kgkey);
					kgkey = NULL;
				}
				kgkey = strdup(tmp_env);
				if (kgkey == NULL) {
					lprintf(LOG_ERR, "%s: malloc failure", progname);
					goto out_free;
				}
			} else {
				lprintf(LOG_WARN, "Unable to read kgkey from environment");
			}
			break;
		case 'y':
			if (kgkey) {
				free(kgkey);
				kgkey = NULL;
			}
			kgkey = ipmi_parse_hex(optarg);
			if (kgkey == NULL) {
				goto out_free;
			}
			break;
		case 'Y':
#ifdef HAVE_GETPASSPHRASE
			tmp_pass = getpassphrase("Key: ");
#else
			tmp_pass = getpass("Key: ");
#endif
			if (tmp_pass != NULL) {
				if (kgkey) {
					free(kgkey);
					kgkey = NULL;
				}
				kgkey = strdup(tmp_pass);
				tmp_pass = NULL;
				if (kgkey == NULL) {
					lprintf(LOG_ERR, "%s: malloc failure", progname);
					goto out_free;
				}
			}
			break;
		case 'U':
			if (username) {
				free(username);
				username = NULL;
			}
			if (strlen(optarg) > 16) {
				lprintf(LOG_ERR, "Username is too long (> 16 bytes)");
				goto out_free;
			}
			username = strdup(optarg);
			if (username == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
		case 'S':
			if (sdrcache) {
				free(sdrcache);
				sdrcache = NULL;
			}
			sdrcache = strdup(optarg);
			if (sdrcache == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
		case 'D':
			/* check for subsequent instance of -D */
			if (devfile) {
				/* free memory for previous string */
				free(devfile);
			}
			devfile = strdup(optarg);
			if (devfile == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
#ifdef ENABLE_ALL_OPTIONS
		case 'o':
			if (oemtype) {
				free(oemtype);
				oemtype = NULL;
			}
			oemtype = strdup(optarg);
			if (oemtype == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			if (strncmp(oemtype, "list", 4) == 0 ||
					strncmp(oemtype, "help", 4) == 0) {
				ipmi_oem_print();
				rc = 0;
				goto out_free;
			}
			break;
		case 'g':
			/* backwards compatible oem hack */
			if (oemtype) {
				free(oemtype);
				oemtype = NULL;
			}
			oemtype = strdup("intelwv2");
			break;
		case 's':
			/* backwards compatible oem hack */
			if (oemtype) {
				free(oemtype);
				oemtype = NULL;
			}
			oemtype = strdup("supermicro");
			break;
		case 'P':
			if (password) {
				free(password);
				password = NULL;
			}
			password = strdup(optarg);
			if (password == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}

			/* Prevent password snooping with ps */
			i = strlen(optarg);
			memset(optarg, 'X', i);
			break;
		case 'E':
			if ((tmp_env = getenv("IPMITOOL_PASSWORD"))) {
				if (password) {
					free(password);
					password = NULL;
				}
				password = strdup(tmp_env);
				if (password == NULL) {
					lprintf(LOG_ERR, "%s: malloc failure", progname);
					goto out_free;
				}
			}
			else if ((tmp_env = getenv("IPMI_PASSWORD"))) {
				if (password) {
					free(password);
					password = NULL;
				}
				password = strdup(tmp_env);
				if (password == NULL) {
					lprintf(LOG_ERR, "%s: malloc failure", progname);
					goto out_free;
				}
			}
			else {
				lprintf(LOG_WARN, "Unable to read password from environment");
			}
			break;
		case 'L':
			i = strlen(optarg);
			if ((i > 0) && (optarg[i-1] == '+')) {
				lookupbit = 0;
				optarg[i-1] = 0;
			}
			privlvl = str2val(optarg, ipmi_privlvl_vals);
			if (privlvl == 0xFF) {
				lprintf(LOG_WARN, "Invalid privilege level %s", optarg);
			}
			break;
		case 'A':
			authtype = str2val(optarg, ipmi_authtype_session_vals);
			break;
		case 't':
			if (str2uchar(optarg, &target_addr) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-t'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'b':
			if (str2uchar(optarg, &target_channel) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-b'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'T':
			if (str2uchar(optarg, &transit_addr) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-T'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'B':
			if (str2uchar(optarg, &transit_channel) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-B'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'l':
			if (str2uchar(optarg, &target_lun) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-l'.");
				rc = 1;
				goto out_free;
			}
			break;
		case 'm':
			if (str2uchar(optarg, &arg_addr) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-m'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'e':
			sol_escape_char = optarg[0];
			break;
		case 'O':
			if (seloem) {
				free(seloem);
				seloem = NULL;
			}
			seloem = strdup(optarg);
			if (seloem == NULL) {
				lprintf(LOG_ERR, "%s: malloc failure", progname);
				goto out_free;
			}
			break;
		case 'z':
			if (str2ushort(optarg, &my_long_packet_size) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-z'.");
				rc = -1;
				goto out_free;
			}
			break;
		/* Retry and Timeout */
		case 'R':
			if (str2int(optarg, &retry) != 0 || retry < 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-R'.");
				rc = -1;
				goto out_free;
			}
			break;
		case 'N':
			if (str2uint(optarg, &timeout) != 0) {
				lprintf(LOG_ERR, "Invalid parameter given or out of range for '-N'.");
				rc = -1;
				goto out_free;
			}
			break;
#endif
		default:
			ipmi_option_usage(progname, cmdlist, intflist);
			goto out_free;
		}
	}

	/* check for command before doing anything */
	if (argc-optind > 0 &&
			strncmp(argv[optind], "help", 4) == 0) {
		ipmi_cmd_print(cmdlist);
		rc = 0;
		goto out_free;
	}

	/*
	 * If the user has specified a hostname (-H option)
	 * then this is a remote access session.
	 *
	 * If no password was specified by any other method
	 * and the authtype was not explicitly set to NONE
	 * then prompt the user.
	 */
	if (hostname != NULL && password == NULL &&
			(authtype != IPMI_SESSION_AUTHTYPE_NONE || authtype < 0)) {
#ifdef HAVE_GETPASSPHRASE
		tmp_pass = getpassphrase("Password: "******"Password: "******"%s: malloc failure", progname);
				goto out_free;
			}
		}
	}

	/* if no interface was specified but a
	 * hostname was then use LAN by default
	 * otherwise the default is hardcoded
	 * to use the first entry in the list
	 */
	if (intfname == NULL && hostname != NULL) {
		intfname = strdup("lan");
		if (intfname == NULL) {
			lprintf(LOG_ERR, "%s: malloc failure", progname);
			goto out_free;
		}
	}

	if (password != NULL && intfname != NULL) {
		if (strcmp(intfname, "lan") == 0 && strlen(password) > 16) {
			lprintf(LOG_ERR, "%s: password is longer than 16 bytes.", intfname);
			rc = -1;
			goto out_free;
		} else if (strcmp(intfname, "lanplus") == 0 && strlen(password) > 20) {
			lprintf(LOG_ERR, "%s: password is longer than 20 bytes.", intfname);
			rc = -1;
			goto out_free;
		}
	} /* if (password != NULL && intfname != NULL) */

	/* load interface */
	ipmi_main_intf = ipmi_intf_load(intfname);
	if (ipmi_main_intf == NULL) {
		lprintf(LOG_ERR, "Error loading interface %s", intfname);
		goto out_free;
	}

	/* setup log */
	log_init(progname, 0, verbose);

	/* run OEM setup if found */
	if (oemtype != NULL &&
	    ipmi_oem_setup(ipmi_main_intf, oemtype) < 0) {
		lprintf(LOG_ERR, "OEM setup for \"%s\" failed", oemtype);
		goto out_free;
	}

	/* set session variables */
	if (hostname != NULL)
		ipmi_intf_session_set_hostname(ipmi_main_intf, hostname);
	if (username != NULL)
		ipmi_intf_session_set_username(ipmi_main_intf, username);
	if (password != NULL)
		ipmi_intf_session_set_password(ipmi_main_intf, password);
	if (kgkey != NULL)
		ipmi_intf_session_set_kgkey(ipmi_main_intf, kgkey);
	if (port > 0)
		ipmi_intf_session_set_port(ipmi_main_intf, port);
	if (authtype >= 0)
		ipmi_intf_session_set_authtype(ipmi_main_intf, (uint8_t)authtype);
	if (privlvl > 0)
		ipmi_intf_session_set_privlvl(ipmi_main_intf, (uint8_t)privlvl);
	else
		ipmi_intf_session_set_privlvl(ipmi_main_intf,
				IPMI_SESSION_PRIV_ADMIN);	/* default */
	/* Adding retry and timeout for interface that support it */
	if (retry > 0)
		ipmi_intf_session_set_retry(ipmi_main_intf, retry);
	if (timeout > 0)
		ipmi_intf_session_set_timeout(ipmi_main_intf, timeout);

	ipmi_intf_session_set_lookupbit(ipmi_main_intf, lookupbit);
	ipmi_intf_session_set_sol_escape_char(ipmi_main_intf, sol_escape_char);
	ipmi_intf_session_set_cipher_suite_id(ipmi_main_intf, cipher_suite_id);

	ipmi_main_intf->devnum = devnum;

	/* setup device file if given */
	ipmi_main_intf->devfile = devfile;

	/* Open the interface with the specified or default IPMB address */
	ipmi_main_intf->my_addr = arg_addr ? arg_addr : IPMI_BMC_SLAVE_ADDR;
	if (ipmi_main_intf->open != NULL)
		ipmi_main_intf->open(ipmi_main_intf);

	/*
	 * Attempt picmg discovery of the actual interface address unless
	 * the users specified an address.
	 *	Address specification always overrides discovery
	 */
	if (picmg_discover(ipmi_main_intf) && !arg_addr) {
		lprintf(LOG_DEBUG, "Running PICMG Get Address Info");
		addr = ipmi_picmg_ipmb_address(ipmi_main_intf);
		lprintf(LOG_INFO,  "Discovered IPMB-0 address 0x%x", addr);
	}

	/*
	 * If we discovered the ipmb address and it is not the same as what we
	 * used for open, Set the discovered IPMB address as my address if the
	 * interface supports it.
	 */
	if (addr != 0 && addr != ipmi_main_intf->my_addr &&
						ipmi_main_intf->set_my_addr) {
		/*
		 * Only set the interface address on interfaces which support
		 * it
		 */
		(void) ipmi_main_intf->set_my_addr(ipmi_main_intf, addr);
	}

	/* If bridging addresses are specified, handle them */
	if (transit_addr > 0 || target_addr > 0) {
		/* sanity check, transit makes no sense without a target */
		if ((transit_addr != 0 || transit_channel != 0) &&
			target_addr == 0) {
			lprintf(LOG_ERR,
				"Transit address/channel %#x/%#x ignored. "
				"Target address must be specified!",
				transit_addr, transit_channel);
			goto out_free;
		}
		ipmi_main_intf->target_addr = target_addr;
		ipmi_main_intf->target_lun = target_lun ;
		ipmi_main_intf->target_channel = target_channel ;

		ipmi_main_intf->transit_addr    = transit_addr;
		ipmi_main_intf->transit_channel = transit_channel;


		/* must be admin level to do this over lan */
		ipmi_intf_session_set_privlvl(ipmi_main_intf, IPMI_SESSION_PRIV_ADMIN);
		/* Get the ipmb address of the targeted entity */
		ipmi_main_intf->target_ipmb_addr =
					ipmi_picmg_ipmb_address(ipmi_main_intf);
		lprintf(LOG_DEBUG, "Specified addressing     Target  %#x:%#x Transit %#x:%#x",
					   ipmi_main_intf->target_addr,
					   ipmi_main_intf->target_channel,
					   ipmi_main_intf->transit_addr,
					   ipmi_main_intf->transit_channel);
		if (ipmi_main_intf->target_ipmb_addr) {
			lprintf(LOG_INFO, "Discovered Target IPMB-0 address %#x",
					   ipmi_main_intf->target_ipmb_addr);
		}
	}

	lprintf(LOG_DEBUG, "Interface address: my_addr %#x "
			   "transit %#x:%#x target %#x:%#x "
			   "ipmb_target %#x\n",
			ipmi_main_intf->my_addr,
			ipmi_main_intf->transit_addr,
			ipmi_main_intf->transit_channel,
			ipmi_main_intf->target_addr,
			ipmi_main_intf->target_channel,
			ipmi_main_intf->target_ipmb_addr);

	/* parse local SDR cache if given */
	if (sdrcache != NULL) {
		ipmi_sdr_list_cache_fromfile(ipmi_main_intf, sdrcache);
	}
	/* Parse SEL OEM file if given */
	if (seloem != NULL) {
		ipmi_sel_oem_init(seloem);
	}

	/* Enable Big Buffer when requested */
	ipmi_main_intf->channel_buf_size = 0;
	if ( my_long_packet_size != 0 ) {
		printf("Setting large buffer to %i\n", my_long_packet_size);
		if (ipmi_kontronoem_set_large_buffer( ipmi_main_intf, my_long_packet_size ) == 0)
		{
			my_long_packet_set = 1;
			ipmi_main_intf->channel_buf_size = my_long_packet_size;
		}
	}

	ipmi_main_intf->cmdlist = cmdlist;

	/* now we finally run the command */
	if (argc-optind > 0)
		rc = ipmi_cmd_run(ipmi_main_intf, argv[optind], argc-optind-1,
				&(argv[optind+1]));
	else
		rc = ipmi_cmd_run(ipmi_main_intf, NULL, 0, NULL);

	if (my_long_packet_set == 1) {
		/* Restore defaults */
		ipmi_kontronoem_set_large_buffer( ipmi_main_intf, 0 );
	}

	/* clean repository caches */
	ipmi_cleanup(ipmi_main_intf);

	/* call interface close function if available */
	if (ipmi_main_intf->opened > 0 && ipmi_main_intf->close != NULL)
		ipmi_main_intf->close(ipmi_main_intf);

	out_free:
	log_halt();

	if (intfname != NULL) {
		free(intfname);
		intfname = NULL;
	}
	if (hostname != NULL) {
		free(hostname);
		hostname = NULL;
	}
	if (username != NULL) {
		free(username);
		username = NULL;
	}
	if (password != NULL) {
		free(password);
		password = NULL;
	}
	if (oemtype != NULL) {
		free(oemtype);
		oemtype = NULL;
	}
	if (seloem != NULL) {
		free(seloem);
		seloem = NULL;
	}
	if (kgkey != NULL) {
		free(kgkey);
		kgkey = NULL;
	}
	if (sdrcache != NULL) {
		free(sdrcache);
		sdrcache = NULL;
	}
	if (devfile) {
		free(devfile);
		devfile = NULL;
	}

	return rc;
}