From 636a785d82e3b0f49e4138b632b48cb5e0a476f8 Mon Sep 17 00:00:00 2001 From: Zdenek Styblik Date: Thu, 5 Nov 2015 17:31:54 +0100 Subject: [PATCH] ID:336 - ipmitool does not fall back to IPv4 for IPMI v2 / RMCP+ sessions Commit implements '-4' and '-6' switch in order to enforce IPv4 or IPv6 connection. In order to do so, struct ipmi_intf has been extended to carry ai_family flag. --- include/ipmitool/ipmi_intf.h | 1 + lib/ipmi_main.c | 40 ++++++++++++++++++++++++++++++++++-- src/plugins/ipmi_intf.c | 2 +- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h index efec82d..67f6019 100644 --- a/include/ipmitool/ipmi_intf.h +++ b/include/ipmitool/ipmi_intf.h @@ -176,6 +176,7 @@ struct ipmi_intf { int picmg_avail; int vita_avail; IPMI_OEM manufacturer_id; + int ai_family; struct ipmi_session_params ssn_params; struct ipmi_session * session; diff --git a/lib/ipmi_main.c b/lib/ipmi_main.c index cfb05f7..1f019ad 100644 --- a/lib/ipmi_main.c +++ b/lib/ipmi_main.c @@ -75,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; @@ -228,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"); @@ -401,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; @@ -626,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) { @@ -909,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) { diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c index 6bb7008..19ba5e3 100644 --- a/src/plugins/ipmi_intf.c +++ b/src/plugins/ipmi_intf.c @@ -350,7 +350,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf) sprintf(service, "%d", params->port); /* Obtain address(es) matching host/port */ memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ + hints.ai_family = intf->ai_family; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */ hints.ai_flags = 0; /* use AI_NUMERICSERV for no name resolution */ hints.ai_protocol = IPPROTO_UDP; /* */