diff options
Diffstat (limited to 'src/plugins/lan')
| -rw-r--r-- | src/plugins/lan/Makefile.in | 2 | ||||
| -rw-r--r-- | src/plugins/lan/lan.c | 187 | 
2 files changed, 105 insertions, 84 deletions
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;  | 
