diff options
Diffstat (limited to 'lib/ipmi_main.c')
-rw-r--r-- | lib/ipmi_main.c | 137 |
1 files changed, 103 insertions, 34 deletions
diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c index 2bbbe4b..a752b59 100644 --- a/lib/ipmi_main.c +++ b/lib/ipmi_main.c @@ -1,21 +1,21 @@ /* * 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 @@ -29,6 +29,7 @@ * 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. */ +#define _XOPEN_SOURCE 700 #include <stdlib.h> #include <stdio.h> @@ -74,9 +75,9 @@ #endif #ifdef ENABLE_ALL_OPTIONS -# define OPTION_STRING "I:hVvcgsEKYao:H:d:P:f:U:p:C:L:A:t:T:m:z:S:l:b:B:e:k:y:O:R:N:D:" +# 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:" #else -# define OPTION_STRING "I:hVvcH:f:U:p:d:S:D:" +# define OPTION_STRING "I:46hVvcH:f:U:p:d:S:D:" #endif extern int verbose; @@ -227,6 +228,8 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_ 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"); + lprintf(LOG_NOTICE, " -4 Use only IPv4"); + lprintf(LOG_NOTICE, " -6 Use only IPv6"); #ifdef ENABLE_ALL_OPTIONS lprintf(LOG_NOTICE, " -a Prompt for remote password"); lprintf(LOG_NOTICE, " -Y Prompt for the Kg key for IPMIv2 authentication"); @@ -263,13 +266,16 @@ ipmi_option_usage(const char * progname, struct ipmi_cmd * cmdlist, struct ipmi_ * * This insures that the IOL session gets freed * for other callers. - * + * * returns -1 */ void ipmi_catch_sigint() { if (ipmi_main_intf != NULL) { printf("\nSIGN INT: Close Interface %s\n",ipmi_main_intf->desc); + /* reduce retry count to a single retry */ + ipmi_main_intf->ssn_params.retry = 1; + /* close interface */ ipmi_main_intf->close(ipmi_main_intf); } exit(-1); @@ -338,6 +344,18 @@ ipmi_parse_hex(const char *str) return out; } +static uint8_t +ipmi_acquire_ipmb_address(struct ipmi_intf * intf) +{ + if (intf->picmg_avail) { + return ipmi_picmg_ipmb_address(intf); + } else if (intf->vita_avail) { + return ipmi_vita_ipmb_address(intf); + } else { + return 0; + } +} + /* ipmi_parse_options - helper function to handle parsing command line options * * @argc: count of options @@ -385,6 +403,7 @@ ipmi_main(int argc, char ** argv, int cipher_suite_id = 3; /* See table 22-19 of the IPMIv2 spec */ int argflag, i, found; int rc = -1; + int ai_family = AF_UNSPEC; char sol_escape_char = SOL_ESCAPE_CHARACTER_DEFAULT; char * devfile = NULL; @@ -610,6 +629,38 @@ ipmi_main(int argc, char ** argv, goto out_free; } break; + case '4': + /* IPv4 only */ + if (ai_family == AF_UNSPEC) { + ai_family = AF_INET; + } else { + if (ai_family == AF_INET6) { + lprintf(LOG_ERR, + "Parameter is mutually exclusive with -6."); + } else { + lprintf(LOG_ERR, + "Multiple -4 parameters given."); + } + rc = (-1); + goto out_free; + } + break; + case '6': + /* IPv6 only */ + if (ai_family == AF_UNSPEC) { + ai_family = AF_INET6; + } else { + if (ai_family == AF_INET) { + lprintf(LOG_ERR, + "Parameter is mutually exclusive with -4."); + } else { + lprintf(LOG_ERR, + "Multiple -6 parameters given."); + } + rc = (-1); + goto out_free; + } + break; #ifdef ENABLE_ALL_OPTIONS case 'o': if (oemtype) { @@ -893,6 +944,7 @@ ipmi_main(int argc, char ** argv, /* setup device file if given */ ipmi_main_intf->devfile = devfile; + ipmi_main_intf->ai_family = ai_family; /* 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) { @@ -900,15 +952,26 @@ ipmi_main(int argc, char ** argv, goto out_free; } } - /* - * 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 (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) { + /* + * Attempt picmg/vita discovery of the actual interface + * address, unless the users specified an address. + * Address specification always overrides discovery + */ + if (picmg_discover(ipmi_main_intf)) { + ipmi_main_intf->picmg_avail = 1; + } else if (vita_discover(ipmi_main_intf)) { + ipmi_main_intf->vita_avail = 1; + } + } + + if (arg_addr) { + addr = arg_addr; + } else if (!ipmi_oem_active(ipmi_main_intf, "i82571spt")) { + lprintf(LOG_DEBUG, "Acquire IPMB address"); + addr = ipmi_acquire_ipmb_address(ipmi_main_intf); + lprintf(LOG_INFO, "Discovered IPMB address 0x%x", addr); } /* @@ -916,41 +979,44 @@ ipmi_main(int argc, char ** argv, * 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 (addr != 0 && addr != ipmi_main_intf->my_addr) { + if (ipmi_main_intf->set_my_addr) { + /* + * Some interfaces need special handling + * when changing local address + */ + (void)ipmi_main_intf->set_my_addr(ipmi_main_intf, addr); + } + + /* set local address */ + ipmi_main_intf->my_addr = addr; } + ipmi_main_intf->target_addr = ipmi_main_intf->my_addr; + /* If bridging addresses are specified, handle them */ - if (target_addr > 0) { - ipmi_main_intf->target_addr = target_addr; - ipmi_main_intf->target_lun = target_lun ; - ipmi_main_intf->target_channel = target_channel ; - } - if (transit_addr > 0) { + if (transit_addr > 0 || target_addr > 0) { /* sanity check, transit makes no sense without a target */ if ((transit_addr != 0 || transit_channel != 0) && - ipmi_main_intf->target_addr == 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_channel = target_channel ; ipmi_main_intf->transit_addr = transit_addr; ipmi_main_intf->transit_channel = transit_channel; - } - if (ipmi_main_intf->target_addr > 0) { + + /* 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); + ipmi_acquire_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, @@ -962,6 +1028,9 @@ ipmi_main(int argc, char ** argv, } } + /* set target LUN (for RAW command) */ + ipmi_main_intf->target_lun = target_lun ; + lprintf(LOG_DEBUG, "Interface address: my_addr %#x " "transit %#x:%#x target %#x:%#x " "ipmb_target %#x\n", |