diff options
Diffstat (limited to 'src')
29 files changed, 1936 insertions, 642 deletions
| diff --git a/src/Makefile.in b/src/Makefile.in index 5da68bb..06b33a8 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -291,6 +291,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/ipmievd.c b/src/ipmievd.c index f940579..cc1ca0f 100644 --- a/src/ipmievd.c +++ b/src/ipmievd.c @@ -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 <stdio.h>  #include <fcntl.h> @@ -122,13 +123,13 @@ static int openipmi_setup(struct ipmi_event_intf * eintf);  static int openipmi_wait(struct ipmi_event_intf * eintf);  static int openipmi_read(struct ipmi_event_intf * eintf);  static struct ipmi_event_intf openipmi_event_intf = { -	name:	"open", -	desc:	"OpenIPMI asyncronous notification of events", -	prefix: "", -	setup:	openipmi_setup, -	wait:	openipmi_wait, -	read:	openipmi_read, -	log:	log_event, +	.name = "open", +	.desc = "OpenIPMI asyncronous notification of events", +	.prefix = "", +	.setup = openipmi_setup, +	.wait = openipmi_wait, +	.read = openipmi_read, +	.log = log_event,  };  #endif  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -139,13 +140,13 @@ static int selwatch_wait(struct ipmi_event_intf * eintf);  static int selwatch_read(struct ipmi_event_intf * eintf);  static int selwatch_check(struct ipmi_event_intf * eintf);  static struct ipmi_event_intf selwatch_event_intf = { -	name:	"sel", -	desc:	"Poll SEL for notification of events", -	setup:	selwatch_setup, -	wait:	selwatch_wait, -	read:	selwatch_read, -	check:	selwatch_check, -	log:	log_event, +	.name = "sel", +	.desc = "Poll SEL for notification of events", +	.setup = selwatch_setup, +	.wait = selwatch_wait, +	.read = selwatch_read, +	.check = selwatch_check, +	.log = log_event,  };  /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -283,7 +284,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)  				eintf->prefix,  				type,  				sdr->record.full->id_string, -				desc ? : "", +				desc ? desc : "",  				(evt->sel_type.standard_type.event_dir  				 ? "Deasserted" : "Asserted"),  				(trigger_reading==(int)trigger_reading) ? 0 : 2, @@ -303,7 +304,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)  			 */  			lprintf(LOG_NOTICE, "%s%s sensor %s %s %s",  				eintf->prefix, type, -				sdr->record.full->id_string, desc ? : "", +				sdr->record.full->id_string, desc ? desc : "",  				(evt->sel_type.standard_type.event_dir  				 ? "Deasserted" : "Asserted"));  			if (((evt->sel_type.standard_type.event_data[0] >> 6) & 3) == 1) { @@ -316,7 +317,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)  			 */  			lprintf(LOG_NOTICE, "%s%s sensor %s %s %s",  				eintf->prefix, type, -				sdr->record.full->id_string, desc ? : "", +				sdr->record.full->id_string, desc ? desc : "",  				(evt->sel_type.standard_type.event_dir  				 ? "Deasserted" : "Asserted"));  		} @@ -325,7 +326,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)  	case SDR_RECORD_TYPE_COMPACT_SENSOR:  		lprintf(LOG_NOTICE, "%s%s sensor %s - %s %s",  			eintf->prefix, type, -			sdr->record.compact->id_string, desc ? : "", +			sdr->record.compact->id_string, desc ? desc : "",  			(evt->sel_type.standard_type.event_dir  			 ? "Deasserted" : "Asserted"));  		break; @@ -333,7 +334,7 @@ log_event(struct ipmi_event_intf * eintf, struct sel_event_record * evt)  	default:  		lprintf(LOG_NOTICE, "%s%s sensor - %s",  			eintf->prefix, type, -			evt->sel_type.standard_type.sensor_num, desc ? : ""); +			evt->sel_type.standard_type.sensor_num, desc ? desc : "");  		break;  	} @@ -703,7 +704,6 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)  	memset(pidfile, 0, 64);  	sprintf(pidfile, "%s%d", DEFAULT_PIDFILE, eintf->intf->devnum); -	lprintf(LOG_NOTICE, "ipmievd: using pidfile %s", pidfile);  	for (i = 0; i < argc; i++) {  		if (strncasecmp(argv[i], "help", 4) == 0) { @@ -738,6 +738,8 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv)  		}  	} +	lprintf(LOG_DEBUG, "ipmievd: using pidfile %s", pidfile); +  	/*  	 * We need to open interface before forking daemon  	 * so error messages are not lost to syslog and @@ -831,8 +833,8 @@ ipmievd_sel_main(struct ipmi_intf * intf, int argc, char ** argv)  	if (intf->session != NULL) {  		snprintf(eintf->prefix, -			 strlen((const char *)intf->session->hostname) + 3, -			 "%s: ", intf->session->hostname); +			 strlen((const char *)intf->ssn_params.hostname) + 3, +			 "%s: ", intf->ssn_params.hostname);  	}  	return ipmievd_main(eintf, argc, argv); diff --git a/src/ipmishell.c b/src/ipmishell.c index 4eebcd8..6cfcbe8 100644 --- a/src/ipmishell.c +++ b/src/ipmishell.c @@ -301,7 +301,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)  			return (-1);  		}  		printf("Set session hostname to %s\n", -				intf->session->hostname); +				intf->ssn_params.hostname);  	}  	else if (strncmp(argv[0], "user", 4) == 0 ||  		 strncmp(argv[0], "username", 8) == 0) { @@ -311,7 +311,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)  			return (-1);  		}  		printf("Set session username to %s\n", -				intf->session->username); +				intf->ssn_params.username);  	}  	else if (strncmp(argv[0], "pass", 4) == 0 ||  		 strncmp(argv[0], "password", 8) == 0) { @@ -336,7 +336,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)  			return (-1);  		}  		printf("Set session authtype to %s\n", -		       val2str(intf->session->authtype_set, +		       val2str(intf->ssn_params.authtype_set,  				   ipmi_authtype_session_vals));  	}  	else if (strncmp(argv[0], "privlvl", 7) == 0) { @@ -354,7 +354,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)  			return (-1);  		}  		printf("Set session privilege level to %s\n", -		       val2str(intf->session->privlvl, +		       val2str(intf->ssn_params.privlvl,  				   ipmi_privlvl_vals));  	}  	else if (strncmp(argv[0], "port", 4) == 0) { @@ -369,7 +369,7 @@ int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv)  			lprintf(LOG_ERR, "Failed to set session port.");  			return (-1);  		} -		printf("Set session port to %d\n", intf->session->port); +		printf("Set session port to %d\n", intf->ssn_params.port);  	}  	else if (strncmp(argv[0], "localaddr", 9) == 0) {  		uint8_t my_addr = 0; @@ -467,6 +467,10 @@ int ipmi_exec_main(struct ipmi_intf * intf, int argc, char ** argv)  				__argv[__argc++] = strdup(tok);  				if (__argv[__argc-1] == NULL) {  					lprintf(LOG_ERR, "ipmitool: malloc failure"); +					if (fp) { +						fclose(fp); +						fp = NULL; +					}  					return -1;  				}  				tmp = __argv[__argc-1]; diff --git a/src/ipmitool.c b/src/ipmitool.c index 6230e5c..164fd44 100644 --- a/src/ipmitool.c +++ b/src/ipmitool.c @@ -65,6 +65,7 @@  #include <ipmitool/ipmi_ekanalyzer.h>  #include <ipmitool/ipmi_ime.h>  #include <ipmitool/ipmi_dcmi.h> +#include <ipmitool/ipmi_vita.h>  #ifdef HAVE_CONFIG_H  # include <config.h> @@ -103,7 +104,8 @@ struct ipmi_cmd ipmitool_cmd_list[] = {  	{ ipmi_user_main,    "user",    "Configure Management Controller users" },  	{ ipmi_channel_main, "channel", "Configure Management Controller channels" },  	{ ipmi_session_main, "session", "Print session information" }, -    { ipmi_dcmi_main,    "dcmi",    "Data Center Management Interface"}, +	{ ipmi_dcmi_main,    "dcmi",    "Data Center Management Interface"}, +	{ ipmi_nm_main,      "nm",      "Node Manager Interface"},  	{ ipmi_sunoem_main,  "sunoem",  "OEM Commands for Sun servers" },  	{ ipmi_kontronoem_main, "kontronoem", "OEM Commands for Kontron devices"},  	{ ipmi_picmg_main,   "picmg",   "Run a PICMG/ATCA extended cmd"}, @@ -119,6 +121,7 @@ struct ipmi_cmd ipmitool_cmd_list[] = {  	{ ipmi_hpmfwupg_main,"hpm", "Update HPM components using PICMG HPM.1 file"},  	{ ipmi_ekanalyzer_main,"ekanalyzer", "run FRU-Ekeying analyzer using FRU files"},  	{ ipmi_ime_main,          "ime", "Update Intel Manageability Engine Firmware"}, +	{ ipmi_vita_main,   "vita",   "Run a VITA 46.11 extended cmd"},  	{ NULL },  }; diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 19b5f11..a2c48ff 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -32,8 +32,8 @@ MAINTAINERCLEANFILES		= Makefile.in  INCLUDES			= -I$(top_srcdir)/include -SUBDIRS				= @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ -DIST_SUBDIRS			= lan lanplus open lipmi imb bmc free serial dummy +SUBDIRS				= @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@ +DIST_SUBDIRS			= lan lanplus open lipmi imb bmc free serial dummy usb  noinst_LTLIBRARIES		= libintf.la  libintf_la_SOURCES		= ipmi_intf.c diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in index daa57d1..f38697a 100644 --- a/src/plugins/Makefile.in +++ b/src/plugins/Makefile.in @@ -284,6 +284,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ @@ -380,8 +382,8 @@ top_builddir = @top_builddir@  top_srcdir = @top_srcdir@  MAINTAINERCLEANFILES = Makefile.in  INCLUDES = -I$(top_srcdir)/include -SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ -DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy +SUBDIRS = @INTF_LAN@ @INTF_LANPLUS@ @INTF_OPEN@ @INTF_LIPMI@ @INTF_IMB@ @INTF_BMC@ @INTF_FREE@ @INTF_SERIAL@ @INTF_DUMMY@ @INTF_USB@ +DIST_SUBDIRS = lan lanplus open lipmi imb bmc free serial dummy usb  noinst_LTLIBRARIES = libintf.la  libintf_la_SOURCES = ipmi_intf.c  libintf_la_LDFLAGS = -export-dynamic diff --git a/src/plugins/bmc/Makefile.in b/src/plugins/bmc/Makefile.in index 8c98861..6ed1ee7 100644 --- a/src/plugins/bmc/Makefile.in +++ b/src/plugins/bmc/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/dummy/Makefile.in b/src/plugins/dummy/Makefile.in index 1cd85a5..86475ba 100644 --- a/src/plugins/dummy/Makefile.in +++ b/src/plugins/dummy/Makefile.in @@ -211,6 +211,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/dummy/dummy.c b/src/plugins/dummy/dummy.c index eb2d086..8bfc4cf 100644 --- a/src/plugins/dummy/dummy.c +++ b/src/plugins/dummy/dummy.c @@ -117,7 +117,7 @@ data_write(int fd, void *data_ptr, int data_len)  		/* TODO - add poll() */  		data_written = write(fd, data_ptr, data_len);  		errno_save = errno; -		if (data_read > 0) { +		if (data_written > 0) {  			data_total+= data_written;  		}  		if (errno_save != 0) { @@ -149,9 +149,6 @@ static void  ipmi_dummyipmi_close(struct ipmi_intf *intf)  {  	struct dummy_rq req; -	int data_total = 0; -	int data_written = 0; -	int try = 0;  	if (intf->fd < 0) {  		return;  	} @@ -245,7 +242,7 @@ ipmi_dummyipmi_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)  			return NULL;  		}  	} -	 +  	memset(&rsp_dummy, 0, sizeof(rsp_dummy));  	if (data_read(intf->fd, &rsp_dummy, sizeof(struct dummy_rs)) != 0) {  		return NULL; @@ -276,11 +273,11 @@ ipmi_dummyipmi_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req)  }  struct ipmi_intf ipmi_dummy_intf = { -	name:	"dummy", -	desc:	"Linux DummyIPMI Interface", -	open:	ipmi_dummyipmi_open, -	close:	ipmi_dummyipmi_close, -	sendrecv:	ipmi_dummyipmi_send_cmd, -	my_addr:	IPMI_BMC_SLAVE_ADDR, -	target_addr:	IPMI_BMC_SLAVE_ADDR, +	.name = "dummy", +	.desc = "Linux DummyIPMI Interface", +	.open = ipmi_dummyipmi_open, +	.close = ipmi_dummyipmi_close, +	.sendrecv = ipmi_dummyipmi_send_cmd, +	.my_addr = IPMI_BMC_SLAVE_ADDR, +	.target_addr = IPMI_BMC_SLAVE_ADDR,  }; diff --git a/src/plugins/free/Makefile.in b/src/plugins/free/Makefile.in index 9b2eda0..d8eb9e6 100644 --- a/src/plugins/free/Makefile.in +++ b/src/plugins/free/Makefile.in @@ -215,6 +215,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/free/free.c b/src/plugins/free/free.c index f89925d..56c8157 100644 --- a/src/plugins/free/free.c +++ b/src/plugins/free/free.c @@ -203,12 +203,12 @@ static void ipmi_free_close(struct ipmi_intf * intf)  static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  { -        u_int8_t lun = req->msg.lun; -        u_int8_t cmd = req->msg.cmd; -        u_int8_t netfn = req->msg.netfn; -        u_int8_t rq_buf[IPMI_BUF_SIZE]; -        u_int8_t rs_buf[IPMI_BUF_SIZE]; -        u_int32_t rs_buf_len = IPMI_BUF_SIZE; +        uint8_t lun = req->msg.lun; +        uint8_t cmd = req->msg.cmd; +        uint8_t netfn = req->msg.netfn; +        uint8_t rq_buf[IPMI_BUF_SIZE]; +        uint8_t rs_buf[IPMI_BUF_SIZE]; +        uint32_t rs_buf_len = IPMI_BUF_SIZE;          int32_t rs_len;  	static struct ipmi_rs rsp;	 diff --git a/src/plugins/imb/Makefile.in b/src/plugins/imb/Makefile.in index a65eca7..d1ded78 100644 --- a/src/plugins/imb/Makefile.in +++ b/src/plugins/imb/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/imb/imb.c b/src/plugins/imb/imb.c index cb97e81..0044159 100644 --- a/src/plugins/imb/imb.c +++ b/src/plugins/imb/imb.c @@ -121,11 +121,11 @@ static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_r  }  struct ipmi_intf ipmi_imb_intf = { -	name:		"imb", -	desc:		"Intel IMB Interface", -	open:		ipmi_imb_open, -	close:		ipmi_imb_close, -	sendrecv:	ipmi_imb_send_cmd, -	target_addr:	IPMI_BMC_SLAVE_ADDR, +	.name = "imb", +	.desc = "Intel IMB Interface", +	.open = ipmi_imb_open, +	.close = ipmi_imb_close, +	.sendrecv = ipmi_imb_send_cmd, +	.target_addr = IPMI_BMC_SLAVE_ADDR,  }; diff --git a/src/plugins/imb/imbapi.c b/src/plugins/imb/imbapi.c index 37d3abe..899c47a 100644 --- a/src/plugins/imb/imbapi.c +++ b/src/plugins/imb/imbapi.c @@ -97,6 +97,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  #include <string.h>  #endif  #include "imbapi.h" +#include <asm/socket.h>  #ifdef SCO_UW  #define NO_MACRO_ARGS  1 @@ -104,7 +105,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  #define IMB_DEVICE "/dev/instru/mismic"  #else  #define IMB_DEVICE "/dev/imb" -#define PAGESIZE EXEC_PAGESIZE +#ifndef PAGESIZE +# define PAGESIZE EXEC_PAGESIZE +#endif  #endif  /*Just to make the DEBUG code cleaner.*/ @@ -1981,7 +1984,7 @@ MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress )  	unsigned int 		length = addressLength;  	off_t 				startpAddress = (off_t)startAddress;  	unsigned int 		diff; -	caddr_t 			startvAddress; +	char 				*startvAddress;  	if ((startAddress == 0) || (addressLength <= 0))  		return ACCESN_ERROR; @@ -2000,13 +2003,13 @@ MapPhysicalMemory(int startAddress,int addressLength, int *virtualAddress )  	startpAddress -= diff;  	length += diff; -	if ( (startvAddress = mmap(	(caddr_t)0,  +	if ( (startvAddress = mmap(0,   								length,   								PROT_READ,   								MAP_SHARED,   								fd,   								startpAddress -								) ) == (caddr_t)-1) +								) ) == MAP_FAILED)  	{  		char buf[128]; diff --git a/src/plugins/ipmi_intf.c b/src/plugins/ipmi_intf.c index a84237e..19ba5e3 100644 --- a/src/plugins/ipmi_intf.c +++ b/src/plugins/ipmi_intf.c @@ -29,6 +29,8 @@   * 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 +#define _GNU_SOURCE 1  #include <stdio.h>  #include <stdlib.h> @@ -83,6 +85,9 @@ extern struct ipmi_intf ipmi_serial_bm_intf;  #ifdef IPMI_INTF_DUMMY  extern struct ipmi_intf ipmi_dummy_intf;  #endif +#ifdef IPMI_INTF_USB +extern struct ipmi_intf ipmi_usb_intf; +#endif  struct ipmi_intf * ipmi_intf_table[] = {  #ifdef IPMI_INTF_OPEN @@ -113,6 +118,9 @@ struct ipmi_intf * ipmi_intf_table[] = {  #ifdef IPMI_INTF_DUMMY  	&ipmi_dummy_intf,  #endif +#ifdef IPMI_INTF_USB +	&ipmi_usb_intf, +#endif  	NULL  }; @@ -194,139 +202,106 @@ struct ipmi_intf * ipmi_intf_load(char * name)  void  ipmi_intf_session_set_hostname(struct ipmi_intf * intf, char * hostname)  { -	if (intf->session == NULL || hostname == NULL) { -		return; +	if (intf->ssn_params.hostname != NULL) { +		free(intf->ssn_params.hostname); +		intf->ssn_params.hostname = NULL;  	} -	if (intf->session->hostname != NULL) { -		free(intf->session->hostname); -		intf->session->hostname = NULL; +	if (hostname == NULL) { +		return;  	} -	intf->session->hostname = strdup(hostname); +	intf->ssn_params.hostname = strdup(hostname);  }  void  ipmi_intf_session_set_username(struct ipmi_intf * intf, char * username)  { -	if (intf->session == NULL) -		return; - -	memset(intf->session->username, 0, 17); +	memset(intf->ssn_params.username, 0, 17);  	if (username == NULL)  		return; -	memcpy(intf->session->username, username, __min(strlen(username), 16)); +	memcpy(intf->ssn_params.username, username, __min(strlen(username), 16));  }  void  ipmi_intf_session_set_password(struct ipmi_intf * intf, char * password)  { -	if (intf->session == NULL) -		return; - -	memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE); +	memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE);  	if (password == NULL) { -		intf->session->password = 0; +		intf->ssn_params.password = 0;  		return;  	} -	intf->session->password = 1; -	memcpy(intf->session->authcode, password, +	intf->ssn_params.password = 1; +	memcpy(intf->ssn_params.authcode_set, password,  	       __min(strlen(password), IPMI_AUTHCODE_BUFFER_SIZE));  }  void  ipmi_intf_session_set_privlvl(struct ipmi_intf * intf, uint8_t level)  { -	if (intf->session == NULL) -		return; - -	intf->session->privlvl = level; +	intf->ssn_params.privlvl = level;  }  void  ipmi_intf_session_set_lookupbit(struct ipmi_intf * intf, uint8_t lookupbit)  { -	if (intf->session == NULL) -		return; - -	intf->session->v2_data.lookupbit = lookupbit; +	intf->ssn_params.lookupbit = lookupbit;  }  void  ipmi_intf_session_set_cipher_suite_id(struct ipmi_intf * intf, uint8_t cipher_suite_id)  { -	if (intf->session == NULL) -		return; - -	intf->session->cipher_suite_id = cipher_suite_id; +	intf->ssn_params.cipher_suite_id = cipher_suite_id;  }  void  ipmi_intf_session_set_sol_escape_char(struct ipmi_intf * intf, char sol_escape_char)  { -	if (intf->session == NULL) -		return; - -	intf->session->sol_escape_char = sol_escape_char; +	intf->ssn_params.sol_escape_char = sol_escape_char;  }  void  ipmi_intf_session_set_kgkey(struct ipmi_intf * intf, char * kgkey)  { -	if (intf->session == NULL) -		return; - -	memset(intf->session->v2_data.kg, 0, IPMI_KG_BUFFER_SIZE); +	memset(intf->ssn_params.kg, 0, IPMI_KG_BUFFER_SIZE);  	if (kgkey == NULL)  		return; -	memcpy(intf->session->v2_data.kg, kgkey,  +	memcpy(intf->ssn_params.kg, kgkey,  	       __min(strlen(kgkey), IPMI_KG_BUFFER_SIZE));  }  void  ipmi_intf_session_set_port(struct ipmi_intf * intf, int port)  { -	if (intf->session == NULL) -		return; - -	intf->session->port = port; +	intf->ssn_params.port = port;  }  void  ipmi_intf_session_set_authtype(struct ipmi_intf * intf, uint8_t authtype)  { -	if (intf->session == NULL) -		return; -  	/* clear password field if authtype NONE specified */  	if (authtype == IPMI_SESSION_AUTHTYPE_NONE) { -		memset(intf->session->authcode, 0, IPMI_AUTHCODE_BUFFER_SIZE); -		intf->session->password = 0; +		memset(intf->ssn_params.authcode_set, 0, IPMI_AUTHCODE_BUFFER_SIZE); +		intf->ssn_params.password = 0;  	} -	intf->session->authtype_set = authtype; +	intf->ssn_params.authtype_set = authtype;  }  void  ipmi_intf_session_set_timeout(struct ipmi_intf * intf, uint32_t timeout)  { -	if (intf->session == NULL) -		return; - -	intf->session->timeout = timeout; +	intf->ssn_params.timeout = timeout;  }  void  ipmi_intf_session_set_retry(struct ipmi_intf * intf, int retry)  { -	if (intf->session == NULL) -		return; - -	intf->session->retry = retry; +	intf->ssn_params.retry = retry;  }  void @@ -335,10 +310,7 @@ ipmi_intf_session_cleanup(struct ipmi_intf *intf)  	if (intf->session == NULL) {  		return;  	} -	if (intf->session->hostname != NULL) { -		free(intf->session->hostname); -		intf->session->hostname = NULL; -	} +  	free(intf->session);  	intf->session = NULL;  } @@ -347,27 +319,27 @@ void  ipmi_cleanup(struct ipmi_intf * intf)  {  	ipmi_sdr_list_empty(intf); +	ipmi_intf_session_set_hostname(intf, NULL);  }  #if defined(IPMI_INTF_LAN) || defined (IPMI_INTF_LANPLUS)  int  ipmi_intf_socket_connect(struct ipmi_intf * intf)  { -	struct ipmi_session *session; +	struct ipmi_session_params *params;  	struct sockaddr_storage addr;  	struct addrinfo hints;  	struct addrinfo *rp0 = NULL, *rp;  	char service[NI_MAXSERV]; -	int rc; -	if (!intf || intf->session == NULL) { +	if (!intf) {  		return -1;  	} -	session = intf->session; +	params = &intf->ssn_params; -	if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) { +	if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) {  		lprintf(LOG_ERR, "No hostname specified!");  		return -1;  	} @@ -375,27 +347,26 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)  	/* open port to BMC */  	memset(&addr, 0, sizeof(addr)); -	sprintf(service, "%d", session->port); +	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; /*  */ -	if (getaddrinfo(session->hostname, service, &hints, &rp0) != 0) { +	if (getaddrinfo(params->hostname, service, &hints, &rp0) != 0) {  		lprintf(LOG_ERR, "Address lookup for %s failed", -			session->hostname); +				params->hostname);  		return -1;  	}  	/* getaddrinfo() returns a list of address structures.  	 * Try each address until we successfully connect(2).  	 * If socket(2) (or connect(2)) fails, we (close the socket -	 * and) try the next address.  +	 * and) try the next address.  	 */ -	session->ai_family = AF_UNSPEC;  	for (rp = rp0; rp != NULL; rp = rp->ai_next) {  		/* We are only interested in IPv4 and IPv6 */  		if ((rp->ai_family != AF_INET6) && (rp->ai_family != AF_INET)) { @@ -409,9 +380,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)  		if (rp->ai_family == AF_INET) {  			if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { -				memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); -				session->addrlen = rp->ai_addrlen; -				session->ai_family = rp->ai_family; +				hints.ai_family = rp->ai_family;  				break;  /* Success */  			}  		}  else if (rp->ai_family == AF_INET6) { @@ -423,14 +392,12 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)  			if (addr6->sin6_scope_id != 0) {  				len = sizeof(struct sockaddr_in6);  				if (getnameinfo((struct sockaddr *)addr6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { -					lprintf(LOG_DEBUG, "Trying address: %s scope=%d",  -						hbuf,  +					lprintf(LOG_DEBUG, "Trying address: %s scope=%d", +						hbuf,  						addr6->sin6_scope_id);  				}  				if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { -					memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); -					session->addrlen = rp->ai_addrlen; -					session->ai_family = rp->ai_family; +					hints.ai_family = rp->ai_family;  					break;  /* Success */  				}  			} else { @@ -440,7 +407,7 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)  				if (getifaddrs(&ifaddrs) < 0) {  					lprintf(LOG_ERR, "Interface address lookup for %s failed", -						session->hostname); +						params->hostname);  					break;  				} @@ -461,44 +428,42 @@ ipmi_intf_socket_connect(struct ipmi_intf * intf)  						}  						len = sizeof(struct sockaddr_in6);  						if ( getnameinfo((struct sockaddr *)tmp6, len, hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0) { -							lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d",  -								ifa->ifa_name != NULL ? ifa->ifa_name : "???",  -								hbuf,  +							lprintf(LOG_DEBUG, "Testing %s interface address: %s scope=%d", +								ifa->ifa_name != NULL ? ifa->ifa_name : "???", +								hbuf,  								tmp6->sin6_scope_id);  						}  						if (tmp6->sin6_scope_id != 0) {  							addr6->sin6_scope_id = tmp6->sin6_scope_id;  						} else { -							/*  -							 * No scope information in interface address information  +							/* +							 * No scope information in interface address information  							 * On some OS'es, getifaddrs() is returning out the 'kernel' representation  							 * of scoped addresses which stores the scope in the 3rd and 4th  							 * byte. See also this page:  							 * http://www.freebsd.org/doc/en/books/developers-handbook/ipv6.html  							 */  							if (IN6_IS_ADDR_LINKLOCAL(&tmp6->sin6_addr) -									&& (tmp6->sin6_addr.s6_addr16[1] != 0)) { -								addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr16[1]); +									&& (tmp6->sin6_addr.s6_addr[1] != 0)) { +								addr6->sin6_scope_id = ntohs(tmp6->sin6_addr.s6_addr[1]);  							}  						}  						/* OK, now try to connect with the scope id from this interface address */  						if (addr6->sin6_scope_id != 0) {  							if (connect(intf->fd, rp->ai_addr, rp->ai_addrlen) != -1) { -								memcpy(&session->addr, rp->ai_addr, rp->ai_addrlen); -								session->addrlen = rp->ai_addrlen; -								session->ai_family = rp->ai_family; +								hints.ai_family = rp->ai_family;  								lprintf(LOG_DEBUG, "Successful connected on %s interface with scope id %d", ifa->ifa_name, tmp6->sin6_scope_id);  								break;  /* Success */  							} -						}  +						}  					}  				}  				freeifaddrs(ifaddrs);  			}  		} -		if (session->ai_family != AF_UNSPEC) { +		if (hints.ai_family != AF_UNSPEC) {  			break;  		}  		close(intf->fd); diff --git a/src/plugins/lan/Makefile.in b/src/plugins/lan/Makefile.in index fc48fe4..9d1ce80 100644 --- a/src/plugins/lan/Makefile.in +++ b/src/plugins/lan/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/lan/lan.c b/src/plugins/lan/lan.c index dd90706..14730d3 100644 --- a/src/plugins/lan/lan.c +++ b/src/plugins/lan/lan.c @@ -29,12 +29,15 @@   * 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 _GNU_SOURCE  #include <stdlib.h>  #include <stdio.h>  #include <inttypes.h>  #include <string.h> +#include <sys/time.h>  #include <sys/types.h> +#include <sys/select.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h> @@ -100,19 +103,19 @@ static void ipmi_lan_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size  static void ipmi_lan_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size);  struct ipmi_intf ipmi_lan_intf = { -	name:		"lan", -	desc:		"IPMI v1.5 LAN Interface", -	setup:		ipmi_lan_setup, -	open:		ipmi_lan_open, -	close:		ipmi_lan_close, -	sendrecv:	ipmi_lan_send_cmd, -	sendrsp:	ipmi_lan_send_rsp, -	recv_sol:	ipmi_lan_recv_sol, -	send_sol:	ipmi_lan_send_sol, -	keepalive:	ipmi_lan_keepalive, -	set_max_request_data_size: ipmi_lan_set_max_rq_data_size, -	set_max_response_data_size: ipmi_lan_set_max_rp_data_size, -	target_addr:	IPMI_BMC_SLAVE_ADDR, +	.name = "lan", +	.desc = "IPMI v1.5 LAN Interface", +	.setup = ipmi_lan_setup, +	.open = ipmi_lan_open, +	.close = ipmi_lan_close, +	.sendrecv = ipmi_lan_send_cmd, +	.sendrsp = ipmi_lan_send_rsp, +	.recv_sol = ipmi_lan_recv_sol, +	.send_sol = ipmi_lan_send_sol, +	.keepalive = ipmi_lan_keepalive, +	.set_max_request_data_size = ipmi_lan_set_max_rq_data_size, +	.set_max_response_data_size = ipmi_lan_set_max_rp_data_size, +	.target_addr = IPMI_BMC_SLAVE_ADDR,  };  static struct ipmi_rq_entry * @@ -214,6 +217,7 @@ ipmi_req_clear_entries(void)  		}  	}  	ipmi_req_entries = NULL; +	ipmi_req_entries_tail = NULL;  }  static int @@ -248,7 +252,8 @@ static struct ipmi_rs *  ipmi_lan_recv_packet(struct ipmi_intf * intf)  {  	static struct ipmi_rs rsp; -	fd_set read_set, err_set; +	fd_set read_set; +	fd_set err_set;  	struct timeval tmout;  	int ret; @@ -258,7 +263,7 @@ ipmi_lan_recv_packet(struct ipmi_intf * intf)  	FD_ZERO(&err_set);  	FD_SET(intf->fd, &err_set); -	tmout.tv_sec = intf->session->timeout; +	tmout.tv_sec = intf->ssn_params.timeout;  	tmout.tv_usec = 0;  	ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); @@ -284,7 +289,7 @@ ipmi_lan_recv_packet(struct ipmi_intf * intf)  		FD_ZERO(&err_set);  		FD_SET(intf->fd, &err_set); -		tmout.tv_sec = intf->session->timeout; +		tmout.tv_sec = intf->ssn_params.timeout;  		tmout.tv_usec = 0;  		ret = select(intf->fd + 1, &read_set, NULL, &err_set, &tmout); @@ -813,7 +818,7 @@ ipmi_lan_build_cmd(struct ipmi_intf * intf, struct ipmi_rq * req, int isRetry)  	}  	/* ipmi message header */ -	msg[len++] = intf->target_addr; +	msg[len++] = entry->bridging_level ? intf->target_addr : IPMI_BMC_SLAVE_ADDR;  	msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3);  	tmp = len - cs;  	msg[len++] = ipmi_csum(msg+cs, tmp); @@ -951,7 +956,7 @@ ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  			break;  		usleep(5000); -		if (++try >= intf->session->retry) { +		if (++try >= intf->ssn_params.retry) {  			lprintf(LOG_DEBUG, "  No response from remote controller");  			break;  		} @@ -1301,7 +1306,7 @@ ipmi_lan_send_sol_payload(struct ipmi_intf * intf,  		}  		usleep(5000); -		if (++try >= intf->session->retry) { +		if (++try >= intf->ssn_params.retry) {  			lprintf(LOG_DEBUG, "  No response from remote controller");  			break;  		} @@ -1548,10 +1553,12 @@ static int  ipmi_lan_keepalive(struct ipmi_intf * intf)  {  	struct ipmi_rs * rsp; -	struct ipmi_rq req = { msg: { -		netfn: IPMI_NETFN_APP, -		cmd: 1, -	}}; +	struct ipmi_rq req = { +		.msg = { +			.netfn = IPMI_NETFN_APP, +			.cmd = 1, +		} +	};  	if (!intf->opened)  		return 0; @@ -1574,10 +1581,11 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)  	struct ipmi_rs * rsp;  	struct ipmi_rq req;  	struct ipmi_session * s = intf->session; +	struct ipmi_session_params *p = &intf->ssn_params;  	uint8_t msg_data[2];  	msg_data[0] = IPMI_LAN_CHANNEL_E; -	msg_data[1] = s->privlvl; +	msg_data[1] = p->privlvl;  	memset(&req, 0, sizeof(req));  	req.msg.netfn    = IPMI_NETFN_APP; @@ -1628,44 +1636,44 @@ ipmi_get_auth_capabilities_cmd(struct ipmi_intf * intf)  	s->authstatus = rsp->data[2]; -	if (s->password && -	    (s->authtype_set == 0 || -	     s->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) && +	if (p->password && +	    (p->authtype_set == 0 || +	     p->authtype_set == IPMI_SESSION_AUTHTYPE_MD5) &&  	    (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD5))  	{  		s->authtype = IPMI_SESSION_AUTHTYPE_MD5;  	} -	else if (s->password && -		 (s->authtype_set == 0 || -		  s->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) && +	else if (p->password && +		 (p->authtype_set == 0 || +		  p->authtype_set == IPMI_SESSION_AUTHTYPE_MD2) &&  		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_MD2))  	{  		s->authtype = IPMI_SESSION_AUTHTYPE_MD2;  	} -	else if (s->password && -		 (s->authtype_set == 0 || -		  s->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) && +	else if (p->password && +		 (p->authtype_set == 0 || +		  p->authtype_set == IPMI_SESSION_AUTHTYPE_PASSWORD) &&  		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_PASSWORD))  	{  		s->authtype = IPMI_SESSION_AUTHTYPE_PASSWORD;  	} -	else if (s->password && -		 (s->authtype_set == 0 || -		  s->authtype_set == IPMI_SESSION_AUTHTYPE_OEM) && +	else if (p->password && +		 (p->authtype_set == 0 || +		  p->authtype_set == IPMI_SESSION_AUTHTYPE_OEM) &&  		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_OEM))  	{  		s->authtype = IPMI_SESSION_AUTHTYPE_OEM;  	} -	else if ((s->authtype_set == 0 || -		  s->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) && +	else if ((p->authtype_set == 0 || +		  p->authtype_set == IPMI_SESSION_AUTHTYPE_NONE) &&  		 (rsp->data[1] & 1<<IPMI_SESSION_AUTHTYPE_NONE))  	{  		s->authtype = IPMI_SESSION_AUTHTYPE_NONE;  	}  	else { -		if (!(rsp->data[1] & 1<<s->authtype_set)) +		if (!(rsp->data[1] & 1<<p->authtype_set))  			lprintf(LOG_ERR, "Authentication type %s not supported", -			       val2str(s->authtype_set, ipmi_authtype_session_vals)); +			       val2str(p->authtype_set, ipmi_authtype_session_vals));  		else  			lprintf(LOG_ERR, "No supported authtypes found"); @@ -1692,7 +1700,7 @@ ipmi_get_session_challenge_cmd(struct ipmi_intf * intf)  	memset(msg_data, 0, 17);  	msg_data[0] = s->authtype; -	memcpy(msg_data+1, s->username, 16); +	memcpy(msg_data+1, intf->ssn_params.username, 16);  	memset(&req, 0, sizeof(req));  	req.msg.netfn		= IPMI_NETFN_APP; @@ -1749,12 +1757,12 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)  	req.msg.cmd = 0x3a;  	msg_data[0] = s->authtype; -	msg_data[1] = s->privlvl; +	msg_data[1] = intf->ssn_params.privlvl;  	/* supermicro oem authentication hack */  	if (ipmi_oem_active(intf, "supermicro")) {  		uint8_t * special = ipmi_auth_special(s); -		memcpy(s->authcode, special, 16); +		memcpy(intf->session->authcode, special, 16);  		memset(msg_data + 2, 0, 16);  		lprintf(LOG_DEBUG, "  OEM Auth        : %s",  			buf2str(special, 16)); @@ -1831,8 +1839,6 @@ ipmi_activate_session_cmd(struct ipmi_intf * intf)  		return -1;  	} -	bridge_possible = 1; -  	lprintf(LOG_DEBUG, "\nSession Activated");  	lprintf(LOG_DEBUG, "  Auth Type       : %s",  		val2str(rsp->data[0], ipmi_authtype_session_vals)); @@ -1853,7 +1859,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)  {  	struct ipmi_rs * rsp;  	struct ipmi_rq req; -	uint8_t privlvl = intf->session->privlvl; +	uint8_t privlvl = intf->ssn_params.privlvl;  	uint8_t backup_bridge_possible = bridge_possible;  	if (privlvl <= IPMI_SESSION_PRIV_USER) @@ -1986,23 +1992,27 @@ ipmi_lan_activate_session(struct ipmi_intf * intf)  	rc = ipmi_set_session_privlvl_cmd(intf);  	if (rc < 0) -		goto fail; +		goto close_fail;  	return 0; + close_fail: +	ipmi_close_session_cmd(intf);   fail:  	lprintf(LOG_ERR, "Error: Unable to establish LAN session");  	return -1;  } -static void +void  ipmi_lan_close(struct ipmi_intf * intf)  { -	if (intf->abort == 0) +	if (!intf->abort && intf->session)  		ipmi_close_session_cmd(intf); -	if (intf->fd >= 0) +	if (intf->fd >= 0) {  		close(intf->fd); +		intf->fd = -1; +	}  	ipmi_req_clear_entries();  	ipmi_intf_session_cleanup(intf); @@ -2016,69 +2026,78 @@ ipmi_lan_open(struct ipmi_intf * intf)  {  	int rc;  	struct ipmi_session *s; +	struct ipmi_session_params *p; -	if (intf == NULL || intf->session == NULL) +	if (intf == NULL || intf->opened)  		return -1; -	s = intf->session; - -	if (s->port == 0) -		s->port = IPMI_LAN_PORT; -	if (s->privlvl == 0) -		s->privlvl = IPMI_SESSION_PRIV_ADMIN; -	if (s->timeout == 0) -		s->timeout = IPMI_LAN_TIMEOUT; -	if (s->retry == 0) -		s->retry = IPMI_LAN_RETRY; -	if (s->hostname == NULL || strlen((const char *)s->hostname) == 0) { +	s = intf->session; +	p = &intf->ssn_params; + +	if (p->port == 0) +		p->port = IPMI_LAN_PORT; +	if (p->privlvl == 0) +		p->privlvl = IPMI_SESSION_PRIV_ADMIN; +	if (p->timeout == 0) +		p->timeout = IPMI_LAN_TIMEOUT; +	if (p->retry == 0) +		p->retry = IPMI_LAN_RETRY; + +	if (p->hostname == NULL || strlen((const char *)p->hostname) == 0) {  		lprintf(LOG_ERR, "No hostname specified!");  		return -1;  	} -	intf->abort = 1; - -	intf->session->sol_data.sequence_number = 1; -	 -	if (ipmi_intf_socket_connect (intf) == -1) { +	if (ipmi_intf_socket_connect(intf) == -1) {  		lprintf(LOG_ERR, "Could not open socket!");  		return -1;  	} -	if (intf->fd < 0) { -		lperror(LOG_ERR, "Connect to %s failed", -			s->hostname); -		intf->close(intf); -		return -1; +	s = (struct ipmi_session *)malloc(sizeof(struct ipmi_session)); +	if (!s) { +		lprintf(LOG_ERR, "ipmitool: malloc failure"); +		goto fail;  	}  	intf->opened = 1; +	intf->abort = 1; + +	intf->session = s; + +	memset(s, 0, sizeof(struct ipmi_session)); +	s->sol_data.sequence_number = 1; +	s->timeout = p->timeout; +	memcpy(&s->authcode, &p->authcode_set, sizeof(s->authcode)); +	s->addrlen = sizeof(s->addr); +	if (getsockname(intf->fd, (struct sockaddr *)&s->addr, &s->addrlen)) { +		goto fail; +	}  	/* try to open session */  	rc = ipmi_lan_activate_session(intf);  	if (rc < 0) { -		intf->close(intf); -		intf->opened = 0; -		return -1; +	    goto fail;  	} -	intf->manufacturer_id = ipmi_get_oem(intf); -  	/* automatically detect interface request and response sizes */  	hpm2_detect_max_payload_size(intf); +	/* set manufactirer OEM id */ +	intf->manufacturer_id = ipmi_get_oem(intf); + +	/* now allow bridging */ +	bridge_possible = 1;  	return intf->fd; + + fail: +	lprintf(LOG_ERR, "Error: Unable to establish IPMI v1.5 / RMCP session"); +	intf->close(intf); +	return -1;  }  static int  ipmi_lan_setup(struct ipmi_intf * intf)  { -	intf->session = malloc(sizeof(struct ipmi_session)); -	if (intf->session == NULL) { -		lprintf(LOG_ERR, "ipmitool: malloc failure"); -		return -1; -	} -	memset(intf->session, 0, sizeof(struct ipmi_session)); -  	/* setup default LAN maximum request and response sizes */  	intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;  	intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE; diff --git a/src/plugins/lanplus/Makefile.in b/src/plugins/lanplus/Makefile.in index 09458aa..eef233d 100644 --- a/src/plugins/lanplus/Makefile.in +++ b/src/plugins/lanplus/Makefile.in @@ -242,6 +242,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c index 0bff5b2..8776212 100644 --- a/src/plugins/lanplus/lanplus.c +++ b/src/plugins/lanplus/lanplus.c @@ -29,12 +29,15 @@   * 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 _GNU_SOURCE  #include <stdlib.h>  #include <stdio.h>  #include <inttypes.h>  #include <string.h> +#include <sys/time.h>  #include <sys/types.h> +#include <sys/select.h>  #include <sys/socket.h>  #include <netinet/in.h>  #include <arpa/inet.h> @@ -126,18 +129,18 @@ static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t siz  static uint8_t bridgePossible = 0;  struct ipmi_intf ipmi_lanplus_intf = { -	name:		"lanplus", -	desc:		"IPMI v2.0 RMCP+ LAN Interface", -	setup:		ipmi_lanplus_setup, -	open:		ipmi_lanplus_open, -	close:		ipmi_lanplus_close, -	sendrecv:	ipmi_lanplus_send_ipmi_cmd, -	recv_sol:	ipmi_lanplus_recv_sol, -	send_sol:	ipmi_lanplus_send_sol, -	keepalive:	ipmi_lanplus_keepalive, -	set_max_request_data_size: ipmi_lanp_set_max_rq_data_size, -	set_max_response_data_size: ipmi_lanp_set_max_rp_data_size, -	target_addr:	IPMI_BMC_SLAVE_ADDR, +	.name = "lanplus", +	.desc = "IPMI v2.0 RMCP+ LAN Interface", +	.setup = ipmi_lanplus_setup, +	.open = ipmi_lanplus_open, +	.close = ipmi_lanplus_close, +	.sendrecv = ipmi_lanplus_send_ipmi_cmd, +	.recv_sol = ipmi_lanplus_recv_sol, +	.send_sol = ipmi_lanplus_send_sol, +	.keepalive = ipmi_lanplus_keepalive, +	.set_max_request_data_size = ipmi_lanp_set_max_rq_data_size, +	.set_max_response_data_size = ipmi_lanp_set_max_rp_data_size, +	.target_addr = IPMI_BMC_SLAVE_ADDR,  }; @@ -383,6 +386,9 @@ ipmi_req_clear_entries(void)  		free(e);  		e = p;  	} + +	ipmi_req_entries = NULL; +	ipmi_req_entries_tail = NULL;  } @@ -595,7 +601,7 @@ ipmiv2_lan_ping(struct ipmi_intf * intf)  /**   * - * ipmi_lan_poll_recv + * ipmi_lan_poll_single   *   * Receive whatever comes back.  Ignore received packets that don't correspond   * to a request we've sent. @@ -603,99 +609,88 @@ ipmiv2_lan_ping(struct ipmi_intf * intf)   * Returns: the ipmi_rs packet describing the/a reponse we expect.   */  static struct ipmi_rs * -ipmi_lan_poll_recv(struct ipmi_intf * intf) +ipmi_lan_poll_single(struct ipmi_intf * intf)  { -	struct rmcp_hdr rmcp_rsp; +	struct rmcp_hdr * rmcp_rsp;  	struct ipmi_rs * rsp;  	struct ipmi_session * session = intf->session;  	int offset, rv;  	uint16_t payload_size; -	uint8_t ourAddress = intf->my_addr; - -	if (ourAddress == 0) { -		ourAddress = IPMI_BMC_SLAVE_ADDR; -	} +	/* receive packet */  	rsp = ipmi_lan_recv_packet(intf); -	/* -	 * Not positive why we're looping.  Do we sometimes get stuff we don't -	 * expect? -	 */ -	while (rsp != NULL) { - -		/* parse response headers */ -		memcpy(&rmcp_rsp, rsp->data, 4); - -		if (rmcp_rsp.class == RMCP_CLASS_ASF) { -			/* might be ping response packet */ -			rv = ipmi_handle_pong(intf, rsp); -			return (rv <= 0) ? NULL : rsp; -		} +	/* check if no packet has come */ +	if (rsp == NULL) { +		return NULL; +	} -		if (rmcp_rsp.class != RMCP_CLASS_IPMI) { -			lprintf(LOG_DEBUG, "Invalid RMCP class: %x", -				rmcp_rsp.class); -			rsp = ipmi_lan_recv_packet(intf); -			continue; -		} +	/* parse response headers */ +	rmcp_rsp = (struct rmcp_hdr *)rsp->data; +	if (rmcp_rsp->class == RMCP_CLASS_ASF) { +		/* might be ping response packet */ +		rv = ipmi_handle_pong(intf, rsp); +		return (rv <= 0) ? NULL : rsp; +	} -		/* -		 * The authtype / payload type determines what we are receiving -		 */ -		offset = 4; - - -		/*-------------------------------------------------------------------- -		 *  -		 * The current packet could be one of several things: -		 * -		 * 1) An IPMI 1.5 packet (the response to our GET CHANNEL -		 *    AUTHENTICATION CAPABILITIES request) -		 * 2) An RMCP+ message with an IPMI reponse payload -		 * 3) AN RMCP+ open session response -		 * 4) An RAKP-2 message (response to an RAKP 1 message) -		 * 5) An RAKP-4 message (response to an RAKP 3 message) -		 * 6) A Serial Over LAN packet -		 * 7) An Invalid packet (one that doesn't match a request) -		 * ------------------------------------------------------------------- -		 */ +	if (rmcp_rsp->class != RMCP_CLASS_IPMI) { +		lprintf(LOG_DEBUG, "Invalid RMCP class: %x", rmcp_rsp->class); +		/* read one more packet */ +		return (struct ipmi_rs *)1; +	} -		read_session_data(rsp, &offset, intf->session); +	/* +	 * The authtype / payload type determines what we are receiving +	 */ +	offset = 4; -		if (lanplus_has_valid_auth_code(rsp, intf->session) == 0) -		{ -			lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!"); -			rsp = ipmi_lan_recv_packet(intf); -			assert(0); -			//continue; -		} +	/*-------------------------------------------------------------------- +	 * +	 * The current packet could be one of several things: +	 * +	 * 1) An IPMI 1.5 packet (the response to our GET CHANNEL +	 *    AUTHENTICATION CAPABILITIES request) +	 * 2) An RMCP+ message with an IPMI reponse payload +	 * 3) AN RMCP+ open session response +	 * 4) An RAKP-2 message (response to an RAKP 1 message) +	 * 5) An RAKP-4 message (response to an RAKP 3 message) +	 * 6) A Serial Over LAN packet +	 * 7) An Invalid packet (one that doesn't match a request) +	 * ------------------------------------------------------------------- +	 */ -		if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE)    && -			 (rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && -			 (rsp->session.bEncrypted)) +	read_session_data(rsp, &offset, intf->session); -		{ -			lanplus_decrypt_payload(session->v2_data.crypt_alg, -						session->v2_data.k2, -						rsp->data + offset, -						rsp->session.msglen, -						rsp->data + offset, -						&payload_size); -		} -		else -			payload_size = rsp->session.msglen; +	if (lanplus_has_valid_auth_code(rsp, intf->session) == 0) { +		lprintf(LOG_ERR, "ERROR: Received message with invalid authcode!"); +		return NULL; +	} +	if ((session->v2_data.session_state == LANPLUS_STATE_ACTIVE)    && +			(rsp->session.authtype == IPMI_SESSION_AUTHTYPE_RMCP_PLUS) && +			(rsp->session.bEncrypted)) { +		lanplus_decrypt_payload(session->v2_data.crypt_alg, +				session->v2_data.k2, +				rsp->data + offset, +				rsp->session.msglen, +				rsp->data + offset, +				&payload_size); +	} else { +		payload_size = rsp->session.msglen; +	} -		/* -		 * Handle IPMI responses (case #1 and #2) -- all IPMI reponses -		 */ -		if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) -		{ -			struct ipmi_rq_entry * entry; -			int payload_start = offset; -			int extra_data_length; +	/* +	 * Handle IPMI responses (case #1 and #2) -- all IPMI reponses +	 */ +	if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) { +		struct ipmi_rq_entry * entry; +		int payload_start = offset; +		int extra_data_length; +		int loop = 1; + +		while (loop--) { +			/* fill-in response data */  			read_ipmi_response(rsp, &offset);  			lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); @@ -731,159 +726,154 @@ ipmi_lan_poll_recv(struct ipmi_intf * intf)  			entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq,  								rsp->payload.ipmi_response.cmd); -			if (entry != NULL) { -				lprintf(LOG_DEBUG+2, "IPMI Request Match found"); -				if ( intf->target_addr != intf->my_addr && -				     bridgePossible && -				     rsp->data_len && -				     rsp->payload.ipmi_response.cmd == 0x34 && -				     (rsp->payload.ipmi_response.netfn == 0x06 || -				     rsp->payload.ipmi_response.netfn == 0x07) && -				     rsp->payload.ipmi_response.rs_lun == 0 ) -				{ -					/* Check completion code */ -					if (rsp->data[offset-1] == 0) -					{ -						lprintf(LOG_DEBUG, "Bridged command answer," -						     " waiting for next answer... "); -						ipmi_req_remove_entry( -							rsp->payload.ipmi_response.rq_seq, -							rsp->payload.ipmi_response.cmd); -						return ipmi_lan_poll_recv(intf); -					} -					else -					{ -						lprintf(LOG_DEBUG, "WARNING: Bridged " -								   "cmd ccode = 0x%02x", -								   rsp->data[offset-1]); +			if (entry == NULL) { +				lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); +				/* read one more packet */ +				return (struct ipmi_rs *)1; +			}; + +			uint8_t target_cmd = entry->req.msg.target_cmd; + +			lprintf(LOG_DEBUG+2, "IPMI Request Match found"); + +			if (entry->bridging_level) { +				/* Check completion code */ +				if (rsp->ccode) { +					lprintf(LOG_DEBUG, "WARNING: Bridged " +							"cmd ccode = 0x%02x", rsp->ccode); +				} else { +					/* decrement bridging level */ +					entry->bridging_level--; +					if (!entry->bridging_level) { +						entry->req.msg.cmd = entry->req.msg.target_cmd;  					} -					if (rsp->data_len && -					    rsp->payload.ipmi_response.cmd == 0x34) { -						memcpy(rsp->data, &rsp->data[offset], -							(rsp->data_len-offset)); -						if (verbose > 2) -							printbuf( &rsp->data[offset], -							(rsp->data_len-offset), -							"bridge command response"); +					/* check if bridged response is embedded */ +					if (payload_size > 8) { +						printbuf(&rsp->data[offset], (rsp->data_len-offset-1), +								"bridge command response"); +						/* +						 * decrement payload size +						 * (cks2 for outer Send Message) +						 */ +						payload_size--; + +						/* +						 * need to make a loop for embedded bridged response +						 */ +						loop++; +					} else { +						lprintf(LOG_DEBUG, "Bridged command answer," +								" waiting for next answer... "); +						/* read one more packet */ +						return (struct ipmi_rs *)1;  					}  				} - -				ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, -								rsp->payload.ipmi_response.cmd); -			} else { -				lprintf(LOG_INFO, "IPMI Request Match NOT FOUND"); -				rsp = ipmi_lan_recv_packet(intf); -				continue;  			} +			/* Remove request entry */ +			ipmi_req_remove_entry(rsp->payload.ipmi_response.rq_seq, +					rsp->payload.ipmi_response.cmd); +  			/*  			 * Good packet.  Shift response data to start of array.  			 * rsp->data becomes the variable length IPMI response data  			 * rsp->data_len becomes the length of that data  			 */  			extra_data_length = payload_size - (offset - payload_start) - 1; -			if (rsp != NULL && extra_data_length) -			{ +			if (extra_data_length) {  				rsp->data_len = extra_data_length;  				memmove(rsp->data, rsp->data + offset, extra_data_length); -			} -			else +			} else {  				rsp->data_len = 0; - -			break; +			}  		} - - -		/* -		 * Open Response -		 */ -		else if (rsp->session.payloadtype == -			 IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE) -		{ -			if (session->v2_data.session_state != -				 LANPLUS_STATE_OPEN_SESSION_SENT) -			{ -				lprintf(LOG_ERR, "Error: Received an Unexpected Open Session " +	/* +	 * Open Response +	 */ +	} else if (rsp->session.payloadtype == +			IPMI_PAYLOAD_TYPE_RMCP_OPEN_RESPONSE) { +		if (session->v2_data.session_state != +				LANPLUS_STATE_OPEN_SESSION_SENT) { +			lprintf(LOG_ERR, "Error: Received an Unexpected Open Session "  					"Response"); -				rsp = ipmi_lan_recv_packet(intf); -				continue; -			} - -			read_open_session_response(rsp, offset); -			break; +			/* read one more packet */ +			return (struct ipmi_rs *)1;  		} - - -		/* -		 * RAKP 2 -		 */ -		else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2) -		{ -			if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT) -			{ -				lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message"); -				rsp = ipmi_lan_recv_packet(intf); -				continue; -			} - -			read_rakp2_message(rsp, offset, session->v2_data.auth_alg); -			break; +		read_open_session_response(rsp, offset); +	/* +	 * RAKP 2 +	 */ +	} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_2) { +		if (session->v2_data.session_state != LANPLUS_STATE_RAKP_1_SENT) { +			lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 2 message"); +			/* read one more packet */ +			return (struct ipmi_rs *)1;  		} - - -		/* -		 * RAKP 4 -		 */ -		else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4) -		{ -			if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT) -			{ -				lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message"); -				rsp = ipmi_lan_recv_packet(intf); -				continue; -			} - -			read_rakp4_message(rsp, offset, session->v2_data.auth_alg); -			break; +		read_rakp2_message(rsp, offset, session->v2_data.auth_alg); +	/* +	 * RAKP 4 +	 */ +	} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_RAKP_4) { +		if (session->v2_data.session_state != LANPLUS_STATE_RAKP_3_SENT) { +			lprintf(LOG_ERR, "Error: Received an Unexpected RAKP 4 message"); +			/* read one more packet */ +			return (struct ipmi_rs *)1;  		} +		read_rakp4_message(rsp, offset, session->v2_data.auth_alg); +	/* +	 * SOL +	 */ +	} else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) { +		int payload_start = offset; +		int extra_data_length; + +		if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) { +			lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet"); +			/* read one more packet */ +			return (struct ipmi_rs *)1; +		} +		read_sol_packet(rsp, &offset); +		extra_data_length = payload_size - (offset - payload_start); +		if (rsp && extra_data_length) { +			rsp->data_len = extra_data_length; +			memmove(rsp->data, rsp->data + offset, extra_data_length); +		} else { +			rsp->data_len = 0; +		} +	/* +	 * Unknown Payload type +	 */ +	} else { +		lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x", +				rsp->session.payloadtype); +		/* read one more packet */ +		return (struct ipmi_rs *)1; +	} +	return rsp; +} -		/* -		 * SOL -		 */ -		else if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) -		{ -			int payload_start = offset; -			int extra_data_length; - -			if (session->v2_data.session_state != LANPLUS_STATE_ACTIVE) -			{ -				lprintf(LOG_ERR, "Error: Received an Unexpected SOL packet"); -				rsp = ipmi_lan_recv_packet(intf); -				continue; -			} -			read_sol_packet(rsp, &offset); -			extra_data_length = payload_size - (offset - payload_start); -			if (rsp && extra_data_length) -			{ -				rsp->data_len = extra_data_length; -				memmove(rsp->data, rsp->data + offset, extra_data_length); -			} -			else -				rsp->data_len = 0; -			break; -		} +/** + * + * ipmi_lan_poll_recv + * + * Receive whatever comes back.  Ignore received packets that don't correspond + * to a request we've sent. + * + * Returns: the ipmi_rs packet describing the/a reponse we expect. + */ +static struct ipmi_rs * +ipmi_lan_poll_recv(struct ipmi_intf * intf) +{ +	struct ipmi_rs * rsp; -		else -		{ -			lprintf(LOG_ERR, "Invalid RMCP+ payload type : 0x%x", -				rsp->session.payloadtype); -			assert(0); -		} -	} +	do { +		/* poll single packet */ +		rsp = ipmi_lan_poll_single(intf); +	} while (rsp == (struct ipmi_rs *) 1);  	return rsp;  } @@ -1406,7 +1396,7 @@ void getIpmiPayloadWireRep(  			tmp = len - cs;  			msg[len++] = ipmi_csum(msg+cs, tmp);  			cs3 = len; -			msg[len++] = intf->my_addr; +			msg[len++] = IPMI_REMOTE_SWID;  			msg[len++] = curr_seq << 2;  			msg[len++] = 0x34;			/* Send Message rqst */  	#if 0  /* From lan.c example */ @@ -1429,7 +1419,10 @@ void getIpmiPayloadWireRep(  		bridgePossible);  	/* rsAddr */ -	msg[len++] = intf->target_addr; /* IPMI_BMC_SLAVE_ADDR; */ +	if (bridgedRequest) +		msg[len++] = intf->target_addr; +	else +		msg[len++] = IPMI_BMC_SLAVE_ADDR;  	/* net Fn */  	msg[len++] = req->msg.netfn << 2 | (req->msg.lun & 3); @@ -1440,7 +1433,7 @@ void getIpmiPayloadWireRep(  	cs = len;  	/* rqAddr */ -	if (!bridgedRequest) +	if (bridgedRequest < 2)  		msg[len++] = IPMI_REMOTE_SWID;  	else  /* Bridged message */  		msg[len++] = intf->my_addr; @@ -1690,7 +1683,7 @@ ipmi_lanplus_build_v2x_msg(  							  curr_seq);  		break; -	case IPMI_PAYLOAD_TYPE_SOL:  +	case IPMI_PAYLOAD_TYPE_SOL:  		getSolPayloadWireRep(intf,  							 msg + IPMI_LANPLUS_OFFSET_PAYLOAD,  							 payload); @@ -1890,26 +1883,26 @@ ipmi_lanplus_build_v2x_ipmi_cmd(  	/* IPMI Message Header -- Figure 13-4 of the IPMI v2.0 spec */ -	if ((intf->target_addr == intf->my_addr) || (!bridgePossible)) -   { -	entry = ipmi_req_add_entry(intf, req, curr_seq); -   } -   else /* it's a bridge command */ -   { -      unsigned char backup_cmd; - -      /* Add entry for cmd */ -   	entry = ipmi_req_add_entry(intf, req, curr_seq); - -      if(entry) -      { -         /* Add entry for bridge cmd */ -         backup_cmd = req->msg.cmd; -         req->msg.cmd = 0x34; -   	   entry = ipmi_req_add_entry(intf, req, curr_seq); -         req->msg.cmd = backup_cmd; -      } -   }    +	if ((intf->target_addr == intf->my_addr) || (!bridgePossible)) { +		entry = ipmi_req_add_entry(intf, req, curr_seq); +	/* it's a bridge command */ +	} else { +		unsigned char backup_cmd; + +		/* Add entry for cmd */ +		entry = ipmi_req_add_entry(intf, req, curr_seq); + +		if (entry) { +			entry->req.msg.target_cmd = entry->req.msg.cmd; +			entry->req.msg.cmd = 0x34; + +			if (intf->transit_addr && +					intf->transit_addr != intf->my_addr) +				entry->bridging_level = 2; +			else +				entry->bridging_level = 1; +		} +	}  	if (entry == NULL)  		return NULL; @@ -2125,7 +2118,7 @@ ipmi_lanplus_send_payload(  	 * so it will only be valid after the open completes.  	 */  	saved_timeout = session->timeout; -	while (try < session->retry) { +	while (try < intf->ssn_params.retry) {  		//ltime = time(NULL);  		if (xmit) { @@ -2263,16 +2256,16 @@ ipmi_lanplus_send_payload(  		case IPMI_PAYLOAD_TYPE_RMCP_OPEN_REQUEST:  			session->v2_data.session_state = LANPLUS_STATE_OPEN_SESSION_SENT;  			/* not retryable for timeouts, force no retry */ -			try = session->retry; +			try = intf->ssn_params.retry;  			break;  		case IPMI_PAYLOAD_TYPE_RAKP_1:  			session->v2_data.session_state = LANPLUS_STATE_RAKP_1_SENT;  			/* not retryable for timeouts, force no retry */ -			try = session->retry; +			try = intf->ssn_params.retry;  			break;  		case IPMI_PAYLOAD_TYPE_RAKP_3:  			/* not retryable for timeouts, force no retry */ -			try = session->retry; +			try = intf->ssn_params.retry;  			session->v2_data.session_state = LANPLUS_STATE_RAKP_3_SENT;  			break;  		} @@ -2574,7 +2567,7 @@ ack_sol_packet(  	{  		struct ipmi_v2_payload ack; -		bzero(&ack, sizeof(struct ipmi_v2_payload)); +		memset(&ack, 0, sizeof(struct ipmi_v2_payload));  		ack.payload_type   = IPMI_PAYLOAD_TYPE_SOL; @@ -2677,7 +2670,7 @@ ipmi_get_auth_capabilities_cmd(  	bridgePossible = 0;  	msg_data[0] = IPMI_LAN_CHANNEL_E | 0x80; // Ask for IPMI v2 data as well -	msg_data[1] = intf->session->privlvl; +	msg_data[1] = intf->ssn_params.privlvl;  	memset(&req, 0, sizeof(req));  	req.msg.netfn    = IPMI_NETFN_APP;            // 0x06 @@ -2728,7 +2721,8 @@ ipmi_close_session_cmd(struct ipmi_intf * intf)  	uint32_t bmc_session_lsbf;  	uint8_t backupBridgePossible; -	if (intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE) +	if (intf->session == NULL +			|| intf->session->v2_data.session_state != LANPLUS_STATE_ACTIVE)  		return -1;  	backupBridgePossible = bridgePossible; @@ -2809,8 +2803,8 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)  	memset(msg, 0, IPMI_OPEN_SESSION_REQUEST_SIZE);  	msg[0] = 0; /* Message tag */ -	if (ipmi_oem_active(intf, "intelplus") || session->privlvl != IPMI_SESSION_PRIV_ADMIN) -		msg[1] = session->privlvl; +	if (ipmi_oem_active(intf, "intelplus") || intf->ssn_params.privlvl != IPMI_SESSION_PRIV_ADMIN) +		msg[1] = intf->ssn_params.privlvl;  	else  		msg[1] = 0; /* Give us highest privlg level based on supported algorithms */  	msg[2] = 0; /* reserved */ @@ -2824,13 +2818,13 @@ ipmi_lanplus_open_session(struct ipmi_intf * intf)  	msg[7] = (session->v2_data.console_id >> 24) & 0xff; -	if (lanplus_get_requested_ciphers(session->cipher_suite_id, +	if (lanplus_get_requested_ciphers(intf->ssn_params.cipher_suite_id,  									  &(session->v2_data.requested_auth_alg),  									  &(session->v2_data.requested_integrity_alg),  									  &(session->v2_data.requested_crypt_alg)))  	{  		lprintf(LOG_WARNING, "Unsupported cipher suite ID : %d\n", -				session->cipher_suite_id); +				intf->ssn_params.cipher_suite_id);  		free(msg);  		msg = NULL;  		return 1; @@ -3030,14 +3024,14 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)  	/*  	 * Requested maximum privilege level.  	 */ -	msg[24] = session->privlvl | session->v2_data.lookupbit; +	msg[24] = intf->ssn_params.privlvl | intf->ssn_params.lookupbit;  	session->v2_data.requested_role = msg[24];  	msg[25] = 0; /* reserved */  	msg[26] = 0; /* reserved */  	/* Username specification */ -	msg[27] = strlen((const char *)session->username); +	msg[27] = strlen((const char *)intf->ssn_params.username);  	if (msg[27] > IPMI_MAX_USER_NAME_LENGTH)  	{  		lprintf(LOG_ERR, "ERROR: user name too long.  " @@ -3047,11 +3041,20 @@ ipmi_lanplus_rakp1(struct ipmi_intf * intf)  		msg = NULL;  		return 1;  	} -	memcpy(msg + 28, session->username, msg[27]); +	memcpy(msg + 28, intf->ssn_params.username, msg[27]); -	v2_payload.payload_type                   = IPMI_PAYLOAD_TYPE_RAKP_1; -	v2_payload.payload_length                 = -		IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]); +	v2_payload.payload_type = IPMI_PAYLOAD_TYPE_RAKP_1; +	if (ipmi_oem_active(intf, "i82571spt")) { +		/* +		 * The IPMI v2.0 spec hints on that all user name bytes +		 * must be occupied (29:44).  The Intel 82571 GbE refuses +		 * to establish a session if this field is shorter. +		 */ +		v2_payload.payload_length = IPMI_RAKP1_MESSAGE_SIZE; +	} else { +		v2_payload.payload_length = +			IPMI_RAKP1_MESSAGE_SIZE - (16 - msg[27]); +	}  	v2_payload.payload.rakp_1_message.message = msg;  	rsp = ipmi_lanplus_send_payload(intf, &v2_payload); @@ -3284,15 +3287,16 @@ ipmi_lanplus_rakp3(struct ipmi_intf * intf)  void  ipmi_lanplus_close(struct ipmi_intf * intf)  { -	if (!intf->abort) +	if (!intf->abort && intf->session)  		ipmi_close_session_cmd(intf); -	if (intf->fd >= 0) +	if (intf->fd >= 0) {  		close(intf->fd); +		intf->fd = -1; +	}  	ipmi_req_clear_entries();  	ipmi_intf_session_cleanup(intf); -	intf->session = NULL;  	intf->opened = 0;  	intf->manufacturer_id = IPMI_OEM_UNKNOWN;  	intf = NULL; @@ -3306,7 +3310,7 @@ ipmi_set_session_privlvl_cmd(struct ipmi_intf * intf)  	struct ipmi_rs * rsp;  	struct ipmi_rq req;  	uint8_t backupBridgePossible; -	uint8_t privlvl = intf->session->privlvl; +	uint8_t privlvl = intf->ssn_params.privlvl;  	if (privlvl <= IPMI_SESSION_PRIV_USER)  		return 0;	/* no need to set higher */ @@ -3356,55 +3360,54 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  	int rc;  	int retry;  	struct get_channel_auth_cap_rsp auth_cap; +	struct ipmi_session_params *params;  	struct ipmi_session *session; -	if (!intf || !intf->session) +	if (!intf)  		return -1; -	session = intf->session; - -	if (!session->port) -		session->port = IPMI_LANPLUS_PORT; -	if (!session->privlvl) -		session->privlvl = IPMI_SESSION_PRIV_ADMIN; -	if (!session->timeout) -		session->timeout = IPMI_LAN_TIMEOUT; -	if (!session->retry) -		session->retry = IPMI_LAN_RETRY; - -	if (session->hostname == NULL || strlen((const char *)session->hostname) == 0) { + +	if (intf->opened) +		return intf->fd; + +	params = &intf->ssn_params; + +	if (!params->port) +		params->port = IPMI_LANPLUS_PORT; +	if (!params->privlvl) +		params->privlvl = IPMI_SESSION_PRIV_ADMIN; +	if (!params->timeout) +		params->timeout = IPMI_LAN_TIMEOUT; +	if (!params->retry) +		params->retry = IPMI_LAN_RETRY; + +	if (params->hostname == NULL || strlen((const char *)params->hostname) == 0) {  		lprintf(LOG_ERR, "No hostname specified!");  		return -1;  	} -	intf->abort = 1; +	if (ipmi_intf_socket_connect(intf) == -1) { +		lprintf(LOG_ERR, "Could not open socket!"); +		goto fail; +	} + +	session = (struct ipmi_session *)malloc(sizeof (struct ipmi_session)); +	if (!session) { +		lprintf(LOG_ERR, "ipmitool: malloc failure"); +		goto fail; +	} +	intf->session = session;  	/* Setup our lanplus session state */ +	memset(session, 0, sizeof(struct ipmi_session)); +	session->timeout = params->timeout; +	memcpy(&session->authcode, ¶ms->authcode_set, sizeof(session->authcode));  	session->v2_data.auth_alg         = IPMI_AUTH_RAKP_NONE;  	session->v2_data.crypt_alg        = IPMI_CRYPT_NONE; -	session->v2_data.console_id       = 0x00; -	session->v2_data.bmc_id           = 0x00;  	session->sol_data.sequence_number = 1; -	//session->sol_data.last_received_sequence_number = 0; -	//session->sol_data.last_received_byte_count      = 0; -	memset(session->v2_data.sik, 0, IPMI_SIK_BUFFER_SIZE); - -	/* Kg is set in ipmi_intf */ -	//memset(session->v2_data.kg,  0, IPMI_KG_BUFFER_SIZE); - -	if (ipmi_intf_socket_connect (intf) == -1) { -		lprintf(LOG_ERR, "Could not open socket!"); -		return -1; -	} - -	if (intf->fd < 0) { -		lperror(LOG_ERR, "Connect to %s failed", -			session->hostname); -		intf->close(intf); -		return -1; -	}  	intf->opened = 1; +	intf->abort = 1;  	/*  	 * @@ -3417,8 +3420,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  		goto fail;  	} -	if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) -	{ +	if (!ipmi_oem_active(intf, "i82571spt") && ! auth_cap.v20_data_available) {  		lprintf(LOG_INFO, "This BMC does not support IPMI v2 / RMCP+");  		goto fail;  	} @@ -3434,7 +3436,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  		 * Open session  		 */  		if ((rc = ipmi_lanplus_open_session(intf)) == 1) { -			intf->close(intf);  			goto fail;  		}  		if (rc == 2) { @@ -3445,7 +3446,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  		 * RAKP 1  		 */  		if ((rc = ipmi_lanplus_rakp1(intf)) == 1) { -			intf->close(intf);  			goto fail;  		}  		if (rc == 2) { @@ -3456,7 +3456,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  		 * RAKP 3  		 */  		if ((rc = ipmi_lanplus_rakp3(intf)) == 1) { -			intf->close(intf);  			goto fail;  		}  		if (rc == 0) break; @@ -3465,24 +3464,29 @@ ipmi_lanplus_open(struct ipmi_intf * intf)  	lprintf(LOG_DEBUG, "IPMIv2 / RMCP+ SESSION OPENED SUCCESSFULLY\n"); +	intf->abort = 0; +  	if (!ipmi_oem_active(intf, "i82571spt")) {  		rc = ipmi_set_session_privlvl_cmd(intf);  		if (rc < 0) { -			intf->close(intf);  			goto fail;  		} + +		/* automatically detect interface request and response sizes */ +		hpm2_detect_max_payload_size(intf);  	} -	intf->manufacturer_id = ipmi_get_oem(intf); +  	bridgePossible = 1; -	/* automatically detect interface request and response sizes */ -	hpm2_detect_max_payload_size(intf); +	if (!ipmi_oem_active(intf, "i82571spt")) { +		intf->manufacturer_id = ipmi_get_oem(intf); +	}  	return intf->fd;   fail:  	lprintf(LOG_ERR, "Error: Unable to establish IPMI v2 / RMCP+ session"); -	intf->opened = 0; +	intf->close(intf);  	return -1;  } @@ -3582,10 +3586,12 @@ static int  ipmi_lanplus_keepalive(struct ipmi_intf * intf)  {  	struct ipmi_rs * rsp; -	struct ipmi_rq req = { msg: { -		netfn: IPMI_NETFN_APP, -		cmd: 1, -	}}; +	struct ipmi_rq req = { +		.msg = { +			.netfn = IPMI_NETFN_APP, +			.cmd = 1, +		} +	};  	if (!intf->opened)  		return 0; @@ -3623,13 +3629,6 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)  	if (lanplus_seed_prng(16))  		return -1; -	intf->session = malloc(sizeof(struct ipmi_session)); -	if (intf->session == NULL) { -		lprintf(LOG_ERR, "ipmitool: malloc failure"); -		return -1; -	} -	memset(intf->session, 0, sizeof(struct ipmi_session)); -      /* setup default LAN maximum request and response sizes */      intf->max_request_data_size = IPMI_LAN_MAX_REQUEST_SIZE;      intf->max_response_data_size = IPMI_LAN_MAX_RESPONSE_SIZE; @@ -3639,7 +3638,7 @@ static int ipmi_lanplus_setup(struct ipmi_intf * intf)  static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t size)  { -	if (intf->session->cipher_suite_id == 3) { +	if (intf->ssn_params.cipher_suite_id == 3) {  		/*  		 * encrypted payload can only be multiple of 16 bytes  		 */ @@ -3657,7 +3656,7 @@ static void ipmi_lanp_set_max_rq_data_size(struct ipmi_intf * intf, uint16_t siz  static void ipmi_lanp_set_max_rp_data_size(struct ipmi_intf * intf, uint16_t size)  { -	if (intf->session->cipher_suite_id == 3) { +	if (intf->ssn_params.cipher_suite_id == 3) {  		/*  		 * encrypted payload can only be multiple of 16 bytes  		 */ diff --git a/src/plugins/lanplus/lanplus_crypt.c b/src/plugins/lanplus/lanplus_crypt.c index 54fd5cb..1cdd050 100644 --- a/src/plugins/lanplus/lanplus_crypt.c +++ b/src/plugins/lanplus/lanplus_crypt.c @@ -95,7 +95,7 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,  		16 +                       /* GUIDc    */  		1  +                       /* ROLEm    */  		1  +                       /* ULENGTHm */ -		strlen((const char *)session->username); /* optional */ +		strlen((const char *)intf->ssn_params.username); /* optional */  	buffer = malloc(bufferLength);  	if (buffer == NULL) { @@ -163,11 +163,11 @@ lanplus_rakp2_hmac_matches(const struct ipmi_session * session,  	}  	/* ULENGTHm */ -	buffer[57] = strlen((const char *)session->username); +	buffer[57] = strlen((const char *)intf->ssn_params.username);  	/* UserName [optional] */  	for (i = 0; i < buffer[57]; ++i) -		buffer[58 + i] = session->username[i]; +		buffer[58 + i] = intf->ssn_params.username[i];  	if (verbose > 2)  	{ @@ -375,7 +375,7 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,  		4  + /* SIDm     */  		1  + /* ROLEm    */  		1  + /* ULENGTHm */ -		strlen((const char *)session->username); +		strlen((const char *)intf->ssn_params.username);  	input_buffer = malloc(input_buffer_length);  	if (input_buffer == NULL) { @@ -406,16 +406,16 @@ lanplus_generate_rakp3_authcode(uint8_t * output_buffer,  	/* ROLEm */  	if (ipmi_oem_active(intf, "intelplus") || ipmi_oem_active(intf, "i82571spt")) -		input_buffer[20] = session->privlvl; +		input_buffer[20] = intf->ssn_params.privlvl;  	else   		input_buffer[20] = session->v2_data.requested_role;  	/* ULENGTHm */ -	input_buffer[21] = strlen((const char *)session->username); +	input_buffer[21] = strlen((const char *)intf->ssn_params.username);  	/* USERNAME */  	for (i = 0; i < input_buffer[21]; ++i) -		input_buffer[22 + i] = session->username[i]; +		input_buffer[22 + i] = intf->ssn_params.username[i];  	if (verbose > 2)  	{ @@ -491,7 +491,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)  		16 +  /* Rc       */  		1  +  /* ROLEm     */  		1  +  /* ULENGTHm  */ -		strlen((const char *)session->username); +		strlen((const char *)intf->ssn_params.username);  	input_buffer = malloc(input_buffer_length);  	if (input_buffer == NULL) { @@ -536,13 +536,13 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)  	}  	/* ULENGTHm */ -	input_buffer[33] = strlen((const char *)session->username); +	input_buffer[33] = strlen((const char *)intf->ssn_params.username);  	/* USERNAME */  	for (i = 0; i < input_buffer[33]; ++i) -		input_buffer[34 + i] = session->username[i]; +		input_buffer[34 + i] = intf->ssn_params.username[i]; -	if (session->v2_data.kg[0]) +	if (intf->ssn_params.kg[0])  	{  		/* We will be hashing with Kg */  		/* @@ -550,7 +550,7 @@ lanplus_generate_sik(struct ipmi_session * session, struct ipmi_intf * intf)  		 * using Kg.  It specifies that Kg should not be truncated.  		 * Kg is set in ipmi_intf.  		 */ -		input_key        = session->v2_data.kg; +		input_key        = intf->ssn_params.kg;  	}  	else  	{ diff --git a/src/plugins/lipmi/Makefile.in b/src/plugins/lipmi/Makefile.in index d70d55d..eb8000f 100644 --- a/src/plugins/lipmi/Makefile.in +++ b/src/plugins/lipmi/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/open/Makefile.in b/src/plugins/open/Makefile.in index da116b7..bb4be5e 100644 --- a/src/plugins/open/Makefile.in +++ b/src/plugins/open/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c index f1ea0dd..fc685de 100644 --- a/src/plugins/open/open.c +++ b/src/plugins/open/open.c @@ -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 _POSIX_SOURCE  #include <stdio.h>  #include <fcntl.h> @@ -38,6 +39,7 @@  #include <stdlib.h>  #include <string.h>  #include <sys/types.h> +#include <sys/select.h>  #include <sys/stat.h>  #include <ipmitool/ipmi.h> @@ -81,6 +83,9 @@   */  #define IPMI_OPENIPMI_MAX_RS_DATA_SIZE 35 +/* Timeout for reading data from BMC in seconds */ +#define IPMI_OPENIPMI_READ_TIMEOUT 15 +  extern int verbose;  static int @@ -164,19 +169,21 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  	struct ipmi_recv recv;  	struct ipmi_addr addr;  	struct ipmi_system_interface_addr bmc_addr = { -		addr_type:	IPMI_SYSTEM_INTERFACE_ADDR_TYPE, -		channel:	IPMI_BMC_CHANNEL, +		.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE, +		.channel = IPMI_BMC_CHANNEL,  	};  	struct ipmi_ipmb_addr ipmb_addr = { -		addr_type:	IPMI_IPMB_ADDR_TYPE, +		.addr_type = IPMI_IPMB_ADDR_TYPE,  	};  	struct ipmi_req _req;  	static struct ipmi_rs rsp; +	struct timeval read_timeout;  	static int curr_seq = 0;  	fd_set rset;  	uint8_t * data = NULL;  	int data_len = 0; +	int retval = 0;  	if (intf == NULL || req == NULL) @@ -325,14 +332,23 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  	FD_ZERO(&rset);  	FD_SET(intf->fd, &rset); - -	if (select(intf->fd+1, &rset, NULL, NULL, NULL) < 0) { +	read_timeout.tv_sec = IPMI_OPENIPMI_READ_TIMEOUT; +	read_timeout.tv_usec = 0; +	retval = select(intf->fd+1, &rset, NULL, NULL, &read_timeout); +	if (retval < 0) {  	   lperror(LOG_ERR, "I/O Error");  	   if (data != NULL) {  	      free(data);  				data = NULL;  		 }  	   return NULL; +	} else if (retval == 0) { +		lprintf(LOG_ERR, "No data available"); +		if (data != NULL) { +			free(data); +			data = NULL; +		} +		return NULL;  	}  	if (FD_ISSET(intf->fd, &rset) == 0) {  	   lprintf(LOG_ERR, "No data available"); @@ -375,8 +391,6 @@ ipmi_openipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  	}  	if(intf->transit_addr != 0 && intf->transit_addr != intf->my_addr) { -	   uint8_t index = 0; -       	   /* ipmb_addr.transit_slave_addr = intf->transit_addr; */  	   lprintf(LOG_DEBUG, "Decapsulating data received from transit "  		   "IPMB target @ 0x%x", intf->transit_addr); @@ -432,13 +446,13 @@ int ipmi_openipmi_setup(struct ipmi_intf * intf)  }  struct ipmi_intf ipmi_open_intf = { -	name:		"open", -	desc:		"Linux OpenIPMI Interface", -	setup:		ipmi_openipmi_setup, -	open:		ipmi_openipmi_open, -	close:		ipmi_openipmi_close, -	sendrecv:	ipmi_openipmi_send_cmd, -	set_my_addr:	ipmi_openipmi_set_my_addr, -	my_addr:	IPMI_BMC_SLAVE_ADDR, -	target_addr:	0, /* init so -m local_addr does not cause bridging */ +	.name = "open", +	.desc = "Linux OpenIPMI Interface", +	.setup = ipmi_openipmi_setup, +	.open = ipmi_openipmi_open, +	.close = ipmi_openipmi_close, +	.sendrecv = ipmi_openipmi_send_cmd, +	.set_my_addr = ipmi_openipmi_set_my_addr, +	.my_addr = IPMI_BMC_SLAVE_ADDR, +	.target_addr = 0, /* init so -m local_addr does not cause bridging */  }; diff --git a/src/plugins/serial/Makefile.in b/src/plugins/serial/Makefile.in index 9826ebf..cae1857 100644 --- a/src/plugins/serial/Makefile.in +++ b/src/plugins/serial/Makefile.in @@ -241,6 +241,8 @@ INTF_OPEN = @INTF_OPEN@  INTF_OPEN_LIB = @INTF_OPEN_LIB@  INTF_SERIAL = @INTF_SERIAL@  INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@  IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@  LD = @LD@  LDFLAGS = @LDFLAGS@ diff --git a/src/plugins/serial/serial_basic.c b/src/plugins/serial/serial_basic.c index 871593f..fe2ebff 100644 --- a/src/plugins/serial/serial_basic.c +++ b/src/plugins/serial/serial_basic.c @@ -29,9 +29,11 @@   * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,   * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.   */ +#define _GNU_SOURCE 1  /* Serial Interface, Basic Mode plugin. */ +#include <alloca.h>  #include <stdio.h>  #include <fcntl.h>  #include <time.h> @@ -183,16 +185,10 @@ static int is_system;  static int  serial_bm_setup(struct ipmi_intf * intf)  { -	intf->session = malloc(sizeof(struct ipmi_session)); -	if (intf->session == NULL) { -		lprintf(LOG_ERR, "ipmitool: malloc failure"); -		return -1; -	} -	memset(intf->session, 0, sizeof(struct ipmi_session)); -  	/* setup default LAN maximum request and response sizes */  	intf->max_request_data_size = SERIAL_BM_MAX_RQ_SIZE;  	intf->max_response_data_size = SERIAL_BM_MAX_RS_SIZE; +  	return 0;  } @@ -285,10 +281,10 @@ serial_bm_open(struct ipmi_intf * intf)  	/* set the new options for the port with flushing */  	tcsetattr(intf->fd, TCSAFLUSH, &ti); -	if (intf->session->timeout == 0) -		intf->session->timeout = SERIAL_BM_TIMEOUT; -	if (intf->session->retry == 0) -		intf->session->retry = SERIAL_BM_RETRY_COUNT; +	if (intf->ssn_params.timeout == 0) +		intf->ssn_params.timeout = SERIAL_BM_TIMEOUT; +	if (intf->ssn_params.retry == 0) +		intf->ssn_params.retry = SERIAL_BM_RETRY_COUNT;  	intf->opened = 1; @@ -459,7 +455,7 @@ serial_bm_wait_for_data(struct ipmi_intf * intf)  	pfd.events = POLLIN;  	pfd.revents = 0; -	n = poll(&pfd, 1, intf->session->timeout*1000); +	n = poll(&pfd, 1, intf->ssn_params.timeout * 1000);  	if (n < 0) {  		lperror(LOG_ERR, "Poll for serial data failed");  		return -1; @@ -887,7 +883,7 @@ serial_bm_get_message(struct ipmi_intf * intf,  		tm = clock() - start;  		tm /= CLOCKS_PER_SEC; -	} while (tm < intf->session->timeout); +	} while (tm < intf->ssn_params.timeout);  	return 0;  } @@ -910,7 +906,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)  	read_ctx.max_buffer_size = SERIAL_BM_MAX_BUFFER_SIZE;  	/* Send the message and receive the answer */ -	for (retry = 0; retry < intf->session->retry; retry++) { +	for (retry = 0; retry < intf->ssn_params.retry; retry++) {  		/* build output message */  		bridging_level = serial_bm_build_msg(intf, req, msg,  				sizeof (msg), req_ctx, &msg_len); @@ -956,7 +952,7 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)  			/* check if response for inner request is not encapsulated */  			} else if (rv == 1) {  				/* wait for response for inner request */ -				rv = serial_bm_wait_response(intf, &req_ctx[0], +				rv = serial_bm_wait_response(intf, &req_ctx[1],  						&read_ctx, msg, sizeof (msg));  				/* check for IO error */ @@ -1003,22 +999,14 @@ serial_bm_send_request(struct ipmi_intf * intf, struct ipmi_rq * req)  	return NULL;  } -int -serial_bm_set_my_addr(struct ipmi_intf * intf, uint8_t addr) -{ -	intf->my_addr = addr; -	return 0; -} -  /*   *	Serial BM interface   */  struct ipmi_intf ipmi_serial_bm_intf = { -	name:		"serial-basic", -	desc:		"Serial Interface, Basic Mode", -	setup:		serial_bm_setup, -	open:		serial_bm_open, -	close:		serial_bm_close, -	sendrecv:	serial_bm_send_request, -	set_my_addr:serial_bm_set_my_addr +	.name = "serial-basic", +	.desc = "Serial Interface, Basic Mode", +	.setup = serial_bm_setup, +	.open = serial_bm_open, +	.close = serial_bm_close, +	.sendrecv = serial_bm_send_request,  }; diff --git a/src/plugins/serial/serial_terminal.c b/src/plugins/serial/serial_terminal.c index 34c6fc5..dfcc202 100644 --- a/src/plugins/serial/serial_terminal.c +++ b/src/plugins/serial/serial_terminal.c @@ -29,9 +29,11 @@   * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,   * EVEN IF PPS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.   */ +#define _GNU_SOURCE 1  /* Serial Interface, Terminal Mode plugin. */ +#include <alloca.h>  #include <stdio.h>  #include <fcntl.h>  #include <unistd.h> @@ -225,10 +227,10 @@ ipmi_serial_term_open(struct ipmi_intf * intf)  	/* set the new options for the port with flushing */  	tcsetattr(intf->fd, TCSAFLUSH, &ti); -	if (intf->session->timeout == 0) -		intf->session->timeout = IPMI_SERIAL_TIMEOUT; -	if (intf->session->retry == 0) -		intf->session->retry = IPMI_SERIAL_RETRY; +	if (intf->ssn_params.timeout == 0) +		intf->ssn_params.timeout = IPMI_SERIAL_TIMEOUT; +	if (intf->ssn_params.retry == 0) +		intf->ssn_params.retry = IPMI_SERIAL_RETRY;  	intf->opened = 1; @@ -259,7 +261,7 @@ serial_wait_for_data(struct ipmi_intf * intf)  	pfd.events = POLLIN;  	pfd.revents = 0; -	n = poll(&pfd, 1, intf->session->timeout*1000); +	n = poll(&pfd, 1, intf->ssn_params.timeout*1000);  	if (n < 0) {  		lperror(LOG_ERR, "Poll for serial data failed");  		return -1; @@ -357,7 +359,7 @@ recv_response(struct ipmi_intf * intf, unsigned char *data, int len)  {  	char hex_rs[IPMI_SERIAL_MAX_RESPONSE * 3];  	int i, j, resp_len = 0; -	unsigned long rv; +	long rv;  	char *p, *pp;  	char ch, str_hex[3]; @@ -769,7 +771,7 @@ serial_term_get_message(struct ipmi_intf * intf,  		tm = clock() - start;  		tm /= CLOCKS_PER_SEC; -	} while (tm < intf->session->timeout); +	} while (tm < intf->ssn_params.timeout);  	return 0;  } @@ -787,7 +789,7 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  	}  	/* Send the message and receive the answer */ -	for (retry = 0; retry < intf->session->retry; retry++) { +	for (retry = 0; retry < intf->ssn_params.retry; retry++) {  		/* build output message */  		bridging_level = serial_term_build_msg(intf, req, msg,  				sizeof (msg), req_ctx, &msg_len); @@ -882,33 +884,18 @@ ipmi_serial_term_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)  static int  ipmi_serial_term_setup(struct ipmi_intf * intf)  { -	intf->session = malloc(sizeof(struct ipmi_session)); -	if (intf->session == NULL) { -		lprintf(LOG_ERR, "ipmitool: malloc failure"); -		return -1; -	} - -	memset(intf->session, 0, sizeof(struct ipmi_session)); -  	/* setup default LAN maximum request and response sizes */  	intf->max_request_data_size = IPMI_SERIAL_MAX_RQ_SIZE;  	intf->max_response_data_size = IPMI_SERIAL_MAX_RS_SIZE; -	return 0; -} -int -ipmi_serial_term_set_my_addr(struct ipmi_intf * intf, uint8_t addr) -{ -	intf->my_addr = addr;  	return 0;  }  struct ipmi_intf ipmi_serial_term_intf = { -	name:		"serial-terminal", -	desc:		"Serial Interface, Terminal Mode", -	setup:		ipmi_serial_term_setup, -	open:		ipmi_serial_term_open, -	close:		ipmi_serial_term_close, -	sendrecv:	ipmi_serial_term_send_cmd, -	set_my_addr:ipmi_serial_term_set_my_addr +	.name = "serial-terminal", +	.desc = "Serial Interface, Terminal Mode", +	.setup = ipmi_serial_term_setup, +	.open = ipmi_serial_term_open, +	.close = ipmi_serial_term_close, +	.sendrecv = ipmi_serial_term_send_cmd,  }; diff --git a/src/plugins/usb/Makefile.am b/src/plugins/usb/Makefile.am new file mode 100644 index 0000000..2a431f7 --- /dev/null +++ b/src/plugins/usb/Makefile.am @@ -0,0 +1,40 @@ + # + # Copyright (c) 2015 American Megatrends, 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: + # + # 1. Redistributions of source code must retain the above copyright notice, + #    this list of conditions and the following disclaimer. + # + # 2. Redistributions 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. + # + # 3. Neither the name of the copyright holder nor the names of its contributors + #    may be used to endorse or promote products derived from this software + #    without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + # AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + # ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + +MAINTAINERCLEANFILES	= Makefile.in + +INCLUDES		= -I$(top_srcdir)/include + +EXTRA_LTLIBRARIES	= libintf_usb.la +noinst_LTLIBRARIES	= @INTF_USB_LIB@ +libintf_usb_la_LIBADD	= $(top_builddir)/lib/libipmitool.la +libintf_usb_la_SOURCES	= usb.c + diff --git a/src/plugins/usb/Makefile.in b/src/plugins/usb/Makefile.in new file mode 100644 index 0000000..298e11d --- /dev/null +++ b/src/plugins/usb/Makefile.in @@ -0,0 +1,637 @@ +# Makefile.in generated by automake 1.14.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2013 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' +am__make_running_with_option = \ +  case $${target_option-} in \ +      ?) ;; \ +      *) echo "am__make_running_with_option: internal error: invalid" \ +              "target option '$${target_option-}' specified" >&2; \ +         exit 1;; \ +  esac; \ +  has_opt=no; \ +  sane_makeflags=$$MAKEFLAGS; \ +  if $(am__is_gnu_make); then \ +    sane_makeflags=$$MFLAGS; \ +  else \ +    case $$MAKEFLAGS in \ +      *\\[\ \	]*) \ +        bs=\\; \ +        sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ +          | sed "s/$$bs$$bs[$$bs $$bs	]*//g"`;; \ +    esac; \ +  fi; \ +  skip_next=no; \ +  strip_trailopt () \ +  { \ +    flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ +  }; \ +  for flg in $$sane_makeflags; do \ +    test $$skip_next = yes && { skip_next=no; continue; }; \ +    case $$flg in \ +      *=*|--*) continue;; \ +        -*I) strip_trailopt 'I'; skip_next=yes;; \ +      -*I?*) strip_trailopt 'I';; \ +        -*O) strip_trailopt 'O'; skip_next=yes;; \ +      -*O?*) strip_trailopt 'O';; \ +        -*l) strip_trailopt 'l'; skip_next=yes;; \ +      -*l?*) strip_trailopt 'l';; \ +      -[dEDm]) skip_next=yes;; \ +      -[JT]) skip_next=yes;; \ +    esac; \ +    case $$flg in \ +      *$$target_option*) has_opt=yes; break;; \ +    esac; \ +  done; \ +  test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = src/plugins/usb +DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ +	$(top_srcdir)/depcomp +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ +	$(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libintf_usb_la_DEPENDENCIES = $(top_builddir)/lib/libipmitool.la +am_libintf_usb_la_OBJECTS = usb.lo +libintf_usb_la_OBJECTS = $(am_libintf_usb_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 =  +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo "  GEN     " $@; +am__v_GEN_1 =  +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 =  +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ +	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ +	$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ +	$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ +	$(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo "  CC      " $@; +am__v_CC_1 =  +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ +	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ +	$(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo "  CCLD    " $@; +am__v_CCLD_1 =  +SOURCES = $(libintf_usb_la_SOURCES) +DIST_SOURCES = $(libintf_usb_la_SOURCES) +am__can_run_installinfo = \ +  case $$AM_UPDATE_INFO_DIR in \ +    n|no|NO) false;; \ +    *) (install-info --version) >/dev/null 2>&1;; \ +  esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates.  Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ +  BEGIN { nonempty = 0; } \ +  { items[$$0] = 1; nonempty = 1; } \ +  END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique.  This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ +  list='$(am__tagged_files)'; \ +  unique=`for i in $$list; do \ +    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ +  done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +ARCH = @ARCH@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BASEDIR = @BASEDIR@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DISTRO = @DISTRO@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTF_BMC = @INTF_BMC@ +INTF_BMC_LIB = @INTF_BMC_LIB@ +INTF_DUMMY = @INTF_DUMMY@ +INTF_DUMMY_LIB = @INTF_DUMMY_LIB@ +INTF_FREE = @INTF_FREE@ +INTF_FREE_LIB = @INTF_FREE_LIB@ +INTF_IMB = @INTF_IMB@ +INTF_IMB_LIB = @INTF_IMB_LIB@ +INTF_LAN = @INTF_LAN@ +INTF_LANPLUS = @INTF_LANPLUS@ +INTF_LANPLUS_LIB = @INTF_LANPLUS_LIB@ +INTF_LAN_LIB = @INTF_LAN_LIB@ +INTF_LIPMI = @INTF_LIPMI@ +INTF_LIPMI_LIB = @INTF_LIPMI_LIB@ +INTF_OPEN = @INTF_OPEN@ +INTF_OPEN_LIB = @INTF_OPEN_LIB@ +INTF_SERIAL = @INTF_SERIAL@ +INTF_SERIAL_LIB = @INTF_SERIAL_LIB@ +INTF_USB = @INTF_USB@ +INTF_USB_LIB = @INTF_USB_LIB@ +IPMITOOL_INTF_LIB = @IPMITOOL_INTF_LIB@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OS = @OS@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +POW_LIB = @POW_LIB@ +PSTAMP = @PSTAMP@ +RANLIB = @RANLIB@ +RPMBUILD = @RPMBUILD@ +RPM_RELEASE = @RPM_RELEASE@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_configure_args = @ac_configure_args@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +MAINTAINERCLEANFILES = Makefile.in +INCLUDES = -I$(top_srcdir)/include +EXTRA_LTLIBRARIES = libintf_usb.la +noinst_LTLIBRARIES = @INTF_USB_LIB@ +libintf_usb_la_LIBADD = $(top_builddir)/lib/libipmitool.la +libintf_usb_la_SOURCES = usb.c +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps) +	@for dep in $?; do \ +	  case '$(am__configure_deps)' in \ +	    *$$dep*) \ +	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ +	        && { if test -f $@; then exit 0; else break; fi; }; \ +	      exit 1;; \ +	  esac; \ +	done; \ +	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/plugins/usb/Makefile'; \ +	$(am__cd) $(top_srcdir) && \ +	  $(AUTOMAKE) --foreign src/plugins/usb/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status +	@case '$?' in \ +	  *config.status*) \ +	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ +	  *) \ +	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ +	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ +	esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure:  $(am__configure_deps) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4):  $(am__aclocal_m4_deps) +	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: +	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) +	@list='$(noinst_LTLIBRARIES)'; \ +	locs=`for p in $$list; do echo $$p; done | \ +	      sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ +	      sort -u`; \ +	test -z "$$locs" || { \ +	  echo rm -f $${locs}; \ +	  rm -f $${locs}; \ +	} + +libintf_usb.la: $(libintf_usb_la_OBJECTS) $(libintf_usb_la_DEPENDENCIES) $(EXTRA_libintf_usb_la_DEPENDENCIES)  +	$(AM_V_CCLD)$(LINK)  $(libintf_usb_la_OBJECTS) $(libintf_usb_la_LIBADD) $(LIBS) + +mostlyclean-compile: +	-rm -f *.$(OBJEXT) + +distclean-compile: +	-rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/usb.Plo@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@	$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@	$(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: +	-rm -f *.lo + +clean-libtool: +	-rm -rf .libs _libs + +ID: $(am__tagged_files) +	$(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +	set x; \ +	here=`pwd`; \ +	$(am__define_uniq_tagged_files); \ +	shift; \ +	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ +	  test -n "$$unique" || unique=$$empty_fix; \ +	  if test $$# -gt 0; then \ +	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +	      "$$@" $$unique; \ +	  else \ +	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ +	      $$unique; \ +	  fi; \ +	fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) +	$(am__define_uniq_tagged_files); \ +	test -z "$(CTAGS_ARGS)$$unique" \ +	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ +	     $$unique + +GTAGS: +	here=`$(am__cd) $(top_builddir) && pwd` \ +	  && $(am__cd) $(top_srcdir) \ +	  && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) +	list='$(am__tagged_files)'; \ +	case "$(srcdir)" in \ +	  [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ +	  *) sdir=$(subdir)/$(srcdir) ;; \ +	esac; \ +	for i in $$list; do \ +	  if test -f "$$i"; then \ +	    echo "$(subdir)/$$i"; \ +	  else \ +	    echo "$$sdir/$$i"; \ +	  fi; \ +	done >> $(top_builddir)/cscope.files + +distclean-tags: +	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) +	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ +	list='$(DISTFILES)'; \ +	  dist_files=`for file in $$list; do echo $$file; done | \ +	  sed -e "s|^$$srcdirstrip/||;t" \ +	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ +	case $$dist_files in \ +	  */*) $(MKDIR_P) `echo "$$dist_files" | \ +			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ +			   sort -u` ;; \ +	esac; \ +	for file in $$dist_files; do \ +	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ +	  if test -d $$d/$$file; then \ +	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ +	    if test -d "$(distdir)/$$file"; then \ +	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +	    fi; \ +	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ +	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ +	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ +	    fi; \ +	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ +	  else \ +	    test -f "$(distdir)/$$file" \ +	    || cp -p $$d/$$file "$(distdir)/$$file" \ +	    || exit 1; \ +	  fi; \ +	done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am +	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: +	if test -z '$(STRIP)'; then \ +	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +	      install; \ +	else \ +	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ +	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ +	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ +	fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: +	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) +	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: +	@echo "This command is intended for maintainers to use" +	@echo "it deletes files that may require special tools to rebuild." +	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ +	mostlyclean-am + +distclean: distclean-am +	-rm -rf ./$(DEPDIR) +	-rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ +	distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am +	-rm -rf ./$(DEPDIR) +	-rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ +	mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ +	clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ +	ctags-am distclean distclean-compile distclean-generic \ +	distclean-libtool distclean-tags distdir dvi dvi-am html \ +	html-am info info-am install install-am install-data \ +	install-data-am install-dvi install-dvi-am install-exec \ +	install-exec-am install-html install-html-am install-info \ +	install-info-am install-man install-pdf install-pdf-am \ +	install-ps install-ps-am install-strip installcheck \ +	installcheck-am installdirs maintainer-clean \ +	maintainer-clean-generic mostlyclean mostlyclean-compile \ +	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ +	tags tags-am uninstall uninstall-am + + # + # Copyright (c) 2015 American Megatrends, 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: + # + # 1. Redistributions of source code must retain the above copyright notice, + #    this list of conditions and the following disclaimer. + # + # 2. Redistributions 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. + # + # 3. Neither the name of the copyright holder nor the names of its contributors + #    may be used to endorse or promote products derived from this software + #    without specific prior written permission. + # + # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + # AND ANY EXPRESS OR IMPLIED WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE + # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + # ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + # POSSIBILITY OF SUCH DAMAGE. + # + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/plugins/usb/usb.c b/src/plugins/usb/usb.c new file mode 100644 index 0000000..0049400 --- /dev/null +++ b/src/plugins/usb/usb.c @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2015 American Megatrends, 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: + * + * 1. Redistributions of source code must retain the above copyright notice, + *    this list of conditions and the following disclaimer. + * + * 2. Redistributions 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. + * + * 3. Neither the name of the copyright holder nor the names of its + *    contributors may be used to endorse or promote products derived from this + *    software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#define _BSD_SOURCE + +#include <ipmitool/helper.h> +#include <ipmitool/log.h> +#include <ipmitool/bswap.h> +#include <ipmitool/ipmi.h> +#include <ipmitool/ipmi_intf.h> +#include <ipmitool/ipmi_oem.h> +#include <ipmitool/ipmi_strings.h> +#include <ipmitool/ipmi_constants.h> +#include <scsi/sg.h> +#include <sys/ioctl.h> +#include <scsi/scsi_ioctl.h> +#include <scsi/scsi.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> + +#define PACKED __attribute__ ((packed)) +#define BEGIN_SIG                   "$G2-CONFIG-HOST$" +#define BEGIN_SIG_LEN               16 +#define MAX_REQUEST_SIZE            64 * 1024 +#define CMD_RESERVED                0x0000 +#define SCSI_AMICMD_CURI_WRITE      0xE2 +#define SCSI_AMICMD_CURI_READ       0xE3 +#define SCSI_AMIDEF_CMD_SECTOR      0x01 +#define SCSI_AMIDEF_DATA_SECTOR     0x02 +#define ERR_SUCCESS                 0       /* Success */ +#define ERR_BIG_DATA                1       /* Too Much Data */ +#define ERR_NO_DATA                 2       /* No/Less Data Available */ +#define ERR_UNSUPPORTED             3       /* Unsupported Command */ +#define IN_PROCESS                  0x8000  /* Bit 15 of Status */ +#define SCSI_AMICMD_ID              0xEE + +/* SCSI Command Packets */ +typedef struct { +	unsigned char   OpCode; +	unsigned char   Lun; +	unsigned int    Lba; +	union { +		struct { +			unsigned char   Reserved6; +			unsigned short  Length; +			unsigned char   Reserved9[3]; +		} PACKED Cmd10; +		struct Len32 { +			unsigned int    Length32; +			unsigned char   Reserved10[2]; +		} PACKED Cmd12; +	} PACKED CmdLen; +} PACKED SCSI_COMMAND_PACKET; + +typedef struct { +	uint8_t byNetFnLUN; +	uint8_t byCmd; +	uint8_t byData[MAX_REQUEST_SIZE]; +} PACKED IPMIUSBRequest_T; + +typedef struct { +	uint8_t   BeginSig[BEGIN_SIG_LEN]; +	uint16_t  Command; +	uint16_t  Status; +	uint32_t  DataInLen; +	uint32_t  DataOutLen; +	uint32_t  InternalUseDataIn; +	uint32_t  InternalUseDataOut; +} CONFIG_CMD; + +static int ipmi_usb_setup(struct ipmi_intf *intf); +static struct ipmi_rs *ipmi_usb_send_cmd(struct ipmi_intf *intf, +		struct ipmi_rq *req); + +struct ipmi_intf ipmi_usb_intf = { +	.name = "usb", +	.desc = "IPMI USB Interface(OEM Interface for AMI Devices)", +	.setup = ipmi_usb_setup, +	.sendrecv = ipmi_usb_send_cmd, +}; + +int +scsiProbeNew(int *num_ami_devices, int *sg_nos) +{ +	int inplen = *num_ami_devices; +	int numdevfound = 0; +	char linebuf[81]; +	char vendor[81]; +	int lineno = 0; +	FILE *fp; + +	fp = fopen("/proc/scsi/sg/device_strs", "r"); +	if (fp == NULL) { +		/* Return 1 on error */ +		return 1; +	} + +	while (1) { +		/* Read line by line and search for "AMI" */ +		if (fgets(linebuf, 80, fp) == NULL) { +			break; +		} + +		if (sscanf(linebuf, "%s", vendor) == 1) { +			if (strncmp(vendor, "AMI", strlen("AMI")) == 0) { +				numdevfound++; +				sg_nos[numdevfound - 1] = lineno; +				if (numdevfound == inplen) { +					break; +				} +			} +			lineno++; +		} +	} + +	*num_ami_devices = numdevfound; +	if (fp != NULL) { +		fclose(fp); +		fp = NULL; +	} + +	return 0; +} + +int +OpenCD(struct ipmi_intf *intf, char *CDName) +{ +	intf->fd = open(CDName, O_RDWR); +	if (intf->fd == (-1)) { +		lprintf(LOG_ERR, "OpenCD:Unable to open device, %s", +				strerror(errno)); +		return 1; +	} +	return 0; +} + +int +sendscsicmd_SGIO(int cd_desc, unsigned char *cdb_buf, unsigned char cdb_len, +		void *data_buf, unsigned int *data_len, int direction, +		void *sense_buf, unsigned char slen, unsigned int timeout) +{ +	sg_io_hdr_t io_hdr; + +	/* Prepare command */ +	memset(&io_hdr, 0, sizeof(sg_io_hdr_t)); +	io_hdr.interface_id = 'S'; +	io_hdr.cmd_len = cdb_len; + +	/* Transfer direction and length */ +	io_hdr.dxfer_direction = direction; +	io_hdr.dxfer_len = *data_len; + +	io_hdr.dxferp = data_buf; + +	io_hdr.cmdp = cdb_buf; + +	io_hdr.sbp = (unsigned char *)sense_buf; +	io_hdr.mx_sb_len = slen; + +	io_hdr.timeout = timeout; + +	if (!timeout) { +		io_hdr.timeout = 20000; +	} + +	if (ioctl(cd_desc, SG_IO, &io_hdr) < 0) { +		lprintf(LOG_ERR, "sendscsicmd_SGIO: SG_IO ioctl error"); +		return 1; +	} else { +		if (io_hdr.status != 0) { +			return 1; +		} +	} + +	if (!timeout) { +		return 0; +	} + +	if ((io_hdr.info & SG_INFO_OK_MASK) != SG_INFO_OK) { +		lprintf(LOG_DEBUG, "sendscsicmd_SGIO: SG_INFO_OK - Not OK"); +	} else { +		lprintf(LOG_DEBUG, "sendscsicmd_SGIO: SG_INFO_OK - OK"); +		return 0; +	} + +	return 1; +} + +int +AMI_SPT_CMD_Identify(int cd_desc, char *szSignature) +{ +	SCSI_COMMAND_PACKET IdPkt = {0}; +	int ret; +	unsigned int siglen = 10; + +	IdPkt.OpCode = SCSI_AMICMD_ID; +	ret = sendscsicmd_SGIO(cd_desc, (unsigned char *)&IdPkt, +				10, szSignature, &siglen, SG_DXFER_FROM_DEV, +				NULL, 0, 5000); + +	return ret; +} + +int +IsG2Drive(int cd_desc) +{ +	char szSignature[15]; +	int ret; + +	memset(szSignature, 0, 15); + +	flock(cd_desc, LOCK_EX); +	ret = AMI_SPT_CMD_Identify(cd_desc, szSignature); +	flock(cd_desc, LOCK_UN); +	if (ret != 0) { +		lprintf(LOG_DEBUG, +				"IsG2Drive:Unable to send ID command to the device"); +		return 1; +	} + +	if (strncmp(szSignature, "$$$AMI$$$", strlen("$$$AMI$$$")) != 0) { +		lprintf(LOG_ERR, +				"IsG2Drive:Signature mismatch when ID command sent"); +		return 1; +	} + +	return 0; +} + +int +FindG2CDROM(struct ipmi_intf *intf) +{ +	int err = 0; +	char device[256]; +	int devarray[16]; +	int numdev = 16; +	int iter; +	err = scsiProbeNew(&numdev, devarray); + +	if (err == 0 && numdev > 0) { +		for (iter = 0; iter < numdev; iter++) { +			sprintf(device, "/dev/sg%d", devarray[iter]); + +			if (!OpenCD(intf, device)) { +				if (!IsG2Drive(intf->fd)) { +					lprintf(LOG_DEBUG, "USB Device found"); +					return 1; +				} +				close(intf->fd); +			} +		} +	} else { +		lprintf(LOG_DEBUG, "Unable to find Virtual CDROM Device"); +	} + +	return 0; +} + +static int +ipmi_usb_setup(struct ipmi_intf *intf) +{ +	if (FindG2CDROM(intf) == 0) { +		lprintf(LOG_ERR, "Error in USB session setup \n"); +		return (-1); +	} +	intf->opened = 1; +	return 0; +} + +void +InitCmdHeader(CONFIG_CMD *pG2CDCmdHeader) +{ +	memset(pG2CDCmdHeader, 0, sizeof(CONFIG_CMD)); +	memcpy((char *)pG2CDCmdHeader->BeginSig, BEGIN_SIG, BEGIN_SIG_LEN); +} + +int +AMI_SPT_CMD_SendCmd(int cd_desc, char *Buffer, char type, uint16_t buflen, +		unsigned int timeout) +{ +	SCSI_COMMAND_PACKET Cmdpkt; +	char sensebuff[32]; +	int ret; +	unsigned int pktLen; +	int count = 3; + +	memset(&Cmdpkt, 0, sizeof(SCSI_COMMAND_PACKET)); + +	Cmdpkt.OpCode = SCSI_AMICMD_CURI_WRITE; +	Cmdpkt.Lba = htonl(type); +	Cmdpkt.CmdLen.Cmd10.Length = htons(1); + +	pktLen = buflen; +	while (count > 0) { +		ret = sendscsicmd_SGIO(cd_desc, (unsigned char *)&Cmdpkt, +				10, Buffer, &pktLen, SG_DXFER_TO_DEV, +				sensebuff, 32, timeout); +		count--; +		if (ret == 0) { +			break; +		} else { +			ret = (-1); +		} +	} + +	return ret; +} + +int +AMI_SPT_CMD_RecvCmd(int cd_desc, char *Buffer, char type, uint16_t buflen) +{ +	SCSI_COMMAND_PACKET Cmdpkt; +	char sensebuff[32]; +	int ret; +	unsigned int pktLen; +	int count = 3; + +	memset(&Cmdpkt, 0, sizeof(SCSI_COMMAND_PACKET)); + +	Cmdpkt.OpCode = SCSI_AMICMD_CURI_READ; +	Cmdpkt.Lba = htonl(type); +	Cmdpkt.CmdLen.Cmd10.Length = htons(1); + +	pktLen = buflen; +	while (count > 0) { +		ret = sendscsicmd_SGIO(cd_desc, (unsigned char *)&Cmdpkt, +				10, Buffer, &pktLen, SG_DXFER_FROM_DEV, +				sensebuff, 32, 5000); +		count--; +		if (0 == ret) { +			break; +		} else { +			ret = (-1); +		} +	} + +	return ret; +} + +int +ReadCD(int cd_desc, char CmdData, char *Buffer, uint32_t DataLen) +{ +	int ret; + +	ret = AMI_SPT_CMD_RecvCmd(cd_desc, Buffer, CmdData, DataLen); +	if (ret != 0) { +		lprintf(LOG_ERR, "Error while reading CD-Drive"); +		return (-1); +	} +	return 0; +} + +int +WriteCD(int cd_desc, char CmdData, char *Buffer, unsigned int timeout, +		uint32_t DataLen) +{ +	int ret; + +	ret = AMI_SPT_CMD_SendCmd(cd_desc, Buffer, CmdData, DataLen, timeout); +	if (ret != 0) { +		lprintf(LOG_ERR, "Error while writing to CD-Drive"); +		return (-1); +	} +	return 0; +} + +int +WriteSplitData(struct ipmi_intf *intf, char *Buffer, char Sector, +			uint32_t NumBytes, uint32_t timeout) +{ +	uint32_t BytesWritten = 0; +	int retVal; + +	if (NumBytes == 0) { +		return 0; +	} + +	while (BytesWritten < NumBytes) { +		if ((retVal = WriteCD(intf->fd, Sector, +						(Buffer + BytesWritten), +						timeout, NumBytes)) != 0) { +			return retVal; +		} + +		BytesWritten += NumBytes; +	} + +	return 0; +} + +int +ReadSplitData(struct ipmi_intf *intf, char *Buffer, char Sector, +				uint32_t NumBytes) +{ +	uint32_t BytesRead = 0; + +	if (NumBytes == 0) { +		return 0; +	} + +	while (BytesRead < NumBytes) { +		if (ReadCD(intf->fd, Sector, (Buffer + BytesRead), +					NumBytes) == (-1)) { +			return 1; +		} +		BytesRead += NumBytes; +	} + +	return 0; +} + +int +WaitForCommandCompletion(struct ipmi_intf *intf, CONFIG_CMD *pG2CDCmdHeader, +		uint32_t timeout, uint32_t DataLen) +{ +	uint32_t TimeCounter = 0; + +	do { +		if (ReadCD(intf->fd, SCSI_AMIDEF_CMD_SECTOR, +					(char *)(pG2CDCmdHeader), DataLen) == (-1)) { +			lprintf(LOG_ERR, "ReadCD returned ERROR"); +			return 1; +		} + +		if (pG2CDCmdHeader->Status & IN_PROCESS) { +			usleep(1000); +			if (timeout > 0) { +				TimeCounter++; +				if (TimeCounter == (timeout + 1)) { +					return 2; +				} +			} +		} else { +			lprintf(LOG_DEBUG, "Command completed"); +			break; +		} +	} while (1); + +	return 0; +} + +int +SendDataToUSBDriver(struct ipmi_intf *intf, char *ReqBuffer, +			unsigned int ReqBuffLen, unsigned char *ResBuffer, +			int *ResBuffLen, unsigned int timeout) +{ +	char CmdHeaderBuffer[sizeof(CONFIG_CMD)]; +	int retVal; +	int waitretval = 0; +	unsigned int to = 0; +	uint32_t DataLen = 0; + +	CONFIG_CMD *pG2CDCmdHeader = (CONFIG_CMD *)CmdHeaderBuffer; + +	/* FillHeader */ +	InitCmdHeader(pG2CDCmdHeader); + +	/* Set command number */ +	pG2CDCmdHeader->Command = CMD_RESERVED; + +	/* Fill Lengths */ +	pG2CDCmdHeader->DataOutLen = *ResBuffLen; +	pG2CDCmdHeader->DataInLen = ReqBuffLen; + +	if (!timeout) { +		to = 3000; +	} + +	DataLen = sizeof(CONFIG_CMD); + +	if (WriteCD(intf->fd, SCSI_AMIDEF_CMD_SECTOR, +				(char *)(pG2CDCmdHeader), to, DataLen) == (-1)) { +		lprintf(LOG_ERR, +				"Error in Write CD of SCSI_AMIDEF_CMD_SECTOR"); +		return (-1); +	} + +	/* Write the data to hard disk */ +	if ((retVal = WriteSplitData(intf, ReqBuffer, +					SCSI_AMIDEF_DATA_SECTOR, +					ReqBuffLen, timeout)) != 0) { +		lprintf(LOG_ERR, +				"Error in WriteSplitData of SCSI_AMIDEF_DATA_SECTOR"); +		return (-1); +	} + +	if (!timeout) { +		return 0; +	} + +	/* Read Status now */ +	waitretval = WaitForCommandCompletion(intf, pG2CDCmdHeader, timeout, +			DataLen); +	if (waitretval != 0) { +		lprintf(LOG_ERR, "WaitForCommandComplete failed"); +		return (0 - waitretval); +	} else { +		lprintf(LOG_DEBUG, "WaitForCommandCompletion SUCCESS"); +	} + +	switch (pG2CDCmdHeader->Status) { +		case ERR_SUCCESS: +			*ResBuffLen = pG2CDCmdHeader->DataOutLen; +			lprintf(LOG_DEBUG, "Before ReadSplitData %x", *ResBuffLen); +			if (ReadSplitData(intf, (char *)ResBuffer, +						SCSI_AMIDEF_DATA_SECTOR, +						pG2CDCmdHeader->DataOutLen) != 0) { +				lprintf(LOG_ERR, +						"Err ReadSplitData SCSI_AMIDEF_DATA_SCTR"); +				return (-1); +			} +			/* Additional read to see verify there was not problem +			 * with the previous read +			 */ +			DataLen = sizeof(CONFIG_CMD); +			ReadCD(intf->fd, SCSI_AMIDEF_CMD_SECTOR, +					(char *)(pG2CDCmdHeader), DataLen); +			break; +		case ERR_BIG_DATA: +			lprintf(LOG_ERR, "Too much data"); +			break; +		case ERR_NO_DATA: +			lprintf(LOG_ERR, "Too little data"); +			break; +		case ERR_UNSUPPORTED: +			lprintf(LOG_ERR, "Unsupported command"); +			break; +		default: +			lprintf(LOG_ERR, "Unknown status"); +	} + +	return pG2CDCmdHeader->Status; +} + +static struct ipmi_rs * +ipmi_usb_send_cmd(struct ipmi_intf *intf, struct ipmi_rq *req) +{ +	static struct ipmi_rs rsp; +	long timeout = 20000; +	uint8_t byRet = 0; +	char ReqBuff[MAX_REQUEST_SIZE] = {0}; +	IPMIUSBRequest_T *pReqPkt = (IPMIUSBRequest_T *)ReqBuff; +	int retries = 0; +	/********** FORM IPMI PACKET *****************/ +	pReqPkt->byNetFnLUN = req->msg.netfn << 2; +	pReqPkt->byNetFnLUN += req->msg.lun; +	pReqPkt->byCmd = req->msg.cmd; +	if (req->msg.data_len) { +		memcpy(pReqPkt->byData, req->msg.data, req->msg.data_len); +	} + +	/********** SEND DATA TO USB ******************/ +	while (retries < 3) { +		retries++; +		byRet = SendDataToUSBDriver(intf, ReqBuff, +				2 + req->msg.data_len, rsp.data, +				&rsp.data_len,timeout); + +		if (byRet == 0) { +			break; +		} +	} + +	if (retries == 3) { +		lprintf(LOG_ERR, +				"Error while sending command using", +				"SendDataToUSBDriver"); +		rsp.ccode = byRet; +		return &rsp; +	} + +	rsp.ccode = rsp.data[0]; + +	/* Save response data for caller */ +	if ((rsp.ccode == 0) && (rsp.data_len > 0)) { +		memmove(rsp.data, rsp.data + 1, rsp.data_len - 1); +		rsp.data[rsp.data_len] = 0; +		rsp.data_len -= 1; +	} +	return &rsp; +} | 
