diff options
Diffstat (limited to 'debian')
| -rw-r--r-- | debian/changelog | 10 | ||||
| -rw-r--r-- | debian/compat | 1 | ||||
| -rw-r--r-- | debian/control | 4 | ||||
| -rw-r--r-- | debian/patches/00list | 4 | ||||
| -rw-r--r-- | debian/patches/10_ipmi_lanp.dpatch | 72 | ||||
| -rw-r--r-- | debian/patches/20-linux-libc-dev.dpatch | 29 | ||||
| -rw-r--r-- | debian/patches/20_ipmi_impi.dpatch | 340 | ||||
| -rw-r--r-- | debian/patches/20_ipmi_isol.dpatch | 1857 | ||||
| -rwxr-xr-x | debian/rules | 46 | ||||
| -rw-r--r-- | debian/watch | 3 | 
10 files changed, 2308 insertions, 58 deletions
| diff --git a/debian/changelog b/debian/changelog index c5d9592..77979da 100644 --- a/debian/changelog +++ b/debian/changelog @@ -2,8 +2,14 @@ ipmitool (1.8.9-1) unstable; urgency=low    * Adopt package (Closes: #432027)    * New upstream release - - -- Matthew Johnson <mjj29@debian.org>  Thu, 13 Dec 2007 09:41:47 +0000 +    - Closes: #422864 +    - Closes: #377628 +  * Add patch to fix segfault (Closes: #389741) +  * Add patch to fix isol (Closes: #412816) +  * Add watch file +  * Move from DH_COMPAT to debian/compat  + + -- Matthew Johnson <mjj29@debian.org>  Thu, 13 Dec 2007 10:25:22 +0000  ipmitool (1.8.8-3.1) unstable; urgency=high diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control index bde6a60..b937781 100644 --- a/debian/control +++ b/debian/control @@ -1,8 +1,8 @@  Source: ipmitool  Section: utils  Priority: optional -Maintainer: Petter Reinholdtsen <pere@debian.org> -Uploaders: Duncan Laurie <duncan@iceblink.org> +Maintainer: Matthew Johnson <mjj29@debian.org> +Uploaders:  Build-Depends: debhelper (>> 4.0.0), libreadline5-dev | libreadline-dev, libssl-dev, dpatch  Standards-Version: 3.7.2 diff --git a/debian/patches/00list b/debian/patches/00list index 1db6d00..3b14fa3 100644 --- a/debian/patches/00list +++ b/debian/patches/00list @@ -1 +1,3 @@ -20-linux-libc-dev.dpatch +10_ipmi_lanp.dpatch +20_ipmi_isol.dpatch +20_ipmi_impi.dpatch diff --git a/debian/patches/10_ipmi_lanp.dpatch b/debian/patches/10_ipmi_lanp.dpatch new file mode 100644 index 0000000..4e7edfd --- /dev/null +++ b/debian/patches/10_ipmi_lanp.dpatch @@ -0,0 +1,72 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 10_ipmi_lanp.dpatch by  <mjj29@debian.org> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: 10_ipmi_lanp closes #389741 + +@DPATCH@ + +--- ipmitool-1.8.9.orig/lib/ipmi_lanp.c	2007-03-06 22:15:36.000000000 +0000 ++++ ipmitool-1.8.9/lib/ipmi_lanp.c	2007-12-13 10:06:18.045813387 +0000 +@@ -1489,28 +1489,43 @@ + 		} + 	} + 	/* ip address */ +-	else if ((strncmp(argv[1], "ipaddr", 6) == 0) && +-		 (get_cmdline_ipaddr(argv[2], data) == 0)) { +-		printf("Setting LAN %s to %d.%d.%d.%d\n", +-		       ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, +-		       data[0], data[1], data[2], data[3]); +-		rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); ++	else if (strncmp(argv[1], "ipaddr", 6) == 0) { ++		if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++				get_cmdline_ipaddr(argv[2], data) != 0 ) { ++			lprintf(LOG_NOTICE, "lan set <channel> ipaddr <x.x.x.x>"); ++		} ++		else { ++			printf("Setting LAN %s to %d.%d.%d.%d\n", ++					ipmi_lan_params[IPMI_LANP_IP_ADDR].desc, ++					data[0], data[1], data[2], data[3]); ++			rc = set_lan_param(intf, chan, IPMI_LANP_IP_ADDR, data, 4); ++		} + 	} + 	/* network mask */ +-	else if ((strncmp(argv[1], "netmask", 7) == 0) && +-		 (get_cmdline_ipaddr(argv[2], data) == 0)) { +-		printf("Setting LAN %s to %d.%d.%d.%d\n", +-		       ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, +-		       data[0], data[1], data[2], data[3]); +-		rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); ++	else if (strncmp(argv[1], "netmask", 7) == 0) { ++		if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++				get_cmdline_ipaddr(argv[2], data) != 0 ) { ++			lprintf(LOG_NOTICE, "lan set <channel> netmask <x.x.x.x>"); ++		} ++		else { ++			printf("Setting LAN %s to %d.%d.%d.%d\n", ++					ipmi_lan_params[IPMI_LANP_SUBNET_MASK].desc, ++					data[0], data[1], data[2], data[3]); ++			rc = set_lan_param(intf, chan, IPMI_LANP_SUBNET_MASK, data, 4); ++		} + 	} + 	/* mac address */ +-	else if ((strncmp(argv[1], "macaddr", 7) == 0) && +-		 (get_cmdline_macaddr(argv[2], data) == 0)) { +-		printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", +-		       ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, +-		       data[0], data[1], data[2], data[3], data[4], data[5]); +-		rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); ++	else if (strncmp(argv[1], "macaddr", 7) == 0) { ++		if ( argc < 3 || strncmp(argv[2], "help", 4) == 0 || ++				get_cmdline_macaddr(argv[2], data) != 0 ) { ++			lprintf(LOG_NOTICE, "lan set <channel> macaddr <x:x:x:x:x:x>"); ++		} ++		else { ++			printf("Setting LAN %s to %02x:%02x:%02x:%02x:%02x:%02x\n", ++					ipmi_lan_params[IPMI_LANP_MAC_ADDR].desc, ++					data[0], data[1], data[2], data[3], data[4], data[5]); ++			rc = set_lan_param(intf, chan, IPMI_LANP_MAC_ADDR, data, 6); ++		} + 	} + 	/* default gateway settings */ + 	else if (strncmp(argv[1], "defgw", 5) == 0) { diff --git a/debian/patches/20-linux-libc-dev.dpatch b/debian/patches/20-linux-libc-dev.dpatch deleted file mode 100644 index 8aecb3c..0000000 --- a/debian/patches/20-linux-libc-dev.dpatch +++ /dev/null @@ -1,29 +0,0 @@ -#! /bin/sh /usr/share/dpatch/dpatch-run -## 20-linux-libc-dev.dpatch by  <jcristau@debian.org> -## -## All lines beginning with `## DP:' are a description of the patch. -## DP: No description. - -@DPATCH@ -diff -urNad ipmitool-1.8.8~/src/ipmievd.c ipmitool-1.8.8/src/ipmievd.c ---- ipmitool-1.8.8~/src/ipmievd.c	2007-07-20 16:01:43.000000000 +0200 -+++ ipmitool-1.8.8/src/ipmievd.c	2007-07-20 16:02:14.000000000 +0200 -@@ -54,7 +54,6 @@ -  - #ifdef IPMI_INTF_OPEN - # if defined(HAVE_OPENIPMI_H) --#  include <linux/compiler.h> - #  include <linux/ipmi.h> - # elif defined(HAVE_FREEBSD_IPMI_H) - #  include <sys/ipmi.h> -diff -urNad ipmitool-1.8.8~/src/plugins/open/open.c ipmitool-1.8.8/src/plugins/open/open.c ---- ipmitool-1.8.8~/src/plugins/open/open.c	2007-07-20 16:01:21.000000000 +0200 -+++ ipmitool-1.8.8/src/plugins/open/open.c	2007-07-20 16:01:43.000000000 +0200 -@@ -50,7 +50,6 @@ - #endif -  - #if defined(HAVE_OPENIPMI_H) --# include <linux/compiler.h> - # include <linux/ipmi.h> - #elif defined(HAVE_FREEBSD_IPMI_H) - /* FreeBSD OpenIPMI-compatible header */ diff --git a/debian/patches/20_ipmi_impi.dpatch b/debian/patches/20_ipmi_impi.dpatch new file mode 100644 index 0000000..d966a1d --- /dev/null +++ b/debian/patches/20_ipmi_impi.dpatch @@ -0,0 +1,340 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 20ipmi_impi.dpatch by  <mjj29@debian.org> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: 20ipmi_impi, closes #412816 + +@DPATCH@ + +--- ipmitool-1.8.9-rc1/lib/ipmi_strings.c.orig	2005-05-15 06:26:33.000000000 +0200 ++++ ipmitool-1.8.9-rc1/lib/ipmi_strings.c	2005-10-23 15:22:57.000000000 +0200 +@@ -43,7 +43,7 @@ + /* +  * From table 26-4 of the IPMI v2 specification +  */ +-const struct valstr impi_bit_rate_vals[] = { ++const struct valstr ipmi_bit_rate_vals[] = { + 	{ 0x00, "IPMI-Over-Serial-Setting"}, /* Using the value in the IPMI Over Serial Config */ + 	{ 0x06, "9.6" }, + 	{ 0x07, "19.2" }, +--- ipmitool-1.8.9-rc1/lib/ipmi_sol.c.orig	2006-08-02 19:17:10.000000000 +0200 ++++ ipmitool-1.8.9-rc1/lib/ipmi_sol.c	2006-08-25 16:01:54.000000000 +0200 +@@ -108,7 +108,7 @@ +  + 	memset(&req, 0, sizeof(req)); + 	req.msg.netfn    = IPMI_NETFN_TRANSPORT; +-	req.msg.cmd      = IMPI_GET_SOL_CONFIG_PARAMETERS; ++	req.msg.cmd      = IPMI_GET_SOL_CONFIG_PARAMETERS; + 	req.msg.data_len = 4; + 	req.msg.data     = data; +  +@@ -485,10 +485,10 @@ + 		printf("%d,", params.retry_interval * 10); +  + 		printf("%s,", +-			   val2str(params.volatile_bit_rate, impi_bit_rate_vals)); ++			   val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); +  + 		printf("%s,", +-			   val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); ++			   val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); +  + 		printf("%d,", params.payload_channel); + 		printf("%d\n", params.payload_port); +@@ -516,10 +516,10 @@ + 			   params.retry_interval * 10); +  + 		printf("Volatile Bit Rate (kbps)        : %s\n", +-			   val2str(params.volatile_bit_rate, impi_bit_rate_vals)); ++			   val2str(params.volatile_bit_rate, ipmi_bit_rate_vals)); +  + 		printf("Non-Volatile Bit Rate (kbps)    : %s\n", +-			   val2str(params.non_volatile_bit_rate, impi_bit_rate_vals)); ++			   val2str(params.non_volatile_bit_rate, ipmi_bit_rate_vals)); +  + 		printf("Payload Channel                 : %d (0x%02x)\n", + 			   params.payload_channel, params.payload_channel); +@@ -554,7 +554,7 @@ +  + 	memset(&req, 0, sizeof(req)); + 	req.msg.netfn    = IPMI_NETFN_TRANSPORT;           /* 0x0c */ +-	req.msg.cmd      = IMPI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ ++	req.msg.cmd      = IPMI_SET_SOL_CONFIG_PARAMETERS; /* 0x21 */ + 	req.msg.data     = data; +  + 	data[0] = channel; +@@ -1105,7 +1105,7 @@ +  +  + /* +- * impi_sol_deactivate ++ * ipmi_sol_deactivate +  */ + static int + ipmi_sol_deactivate(struct ipmi_intf * intf) +@@ -1451,7 +1451,7 @@ +  +  + /* +- * impi_sol_activate ++ * ipmi_sol_activate +  */ + static int + ipmi_sol_activate(struct ipmi_intf * intf, int looptest, int interval) +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h.orig	2005-04-21 01:03:57.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_intf.h	2005-10-23 16:07:56.000000000 +0200 +@@ -96,7 +96,7 @@ + 	socklen_t addrlen; +  + 	/* +-	 * This struct holds state data specific to IMPI v2 / RMCP+ sessions ++	 * This struct holds state data specific to IPMI v2 / RMCP+ sessions + 	 */ + 	struct { + 		enum LANPLUS_SESSION_STATE session_state; +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h.orig	2005-01-07 03:05:45.000000000 +0100 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_user.h	2005-10-23 16:08:25.000000000 +0200 +@@ -44,7 +44,7 @@ +  +  + /* +- * The GET USER ACCESS response from table 22-32 of the IMPI v2.0 spec ++ * The GET USER ACCESS response from table 22-32 of the IPMI v2.0 spec +  */ + struct user_access_rsp { + #if WORDS_BIGENDIAN +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h.orig	2005-05-11 07:46:40.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_strings.h	2005-10-23 15:22:19.000000000 +0200 +@@ -45,7 +45,7 @@ +  + extern const struct valstr ipmi_channel_activity_type_vals[]; + extern const struct valstr ipmi_privlvl_vals[]; +-extern const struct valstr impi_bit_rate_vals[]; ++extern const struct valstr ipmi_bit_rate_vals[]; + extern const struct valstr ipmi_set_in_progress_vals[]; + extern const struct valstr ipmi_authtype_session_vals[]; + extern const struct valstr ipmi_authtype_vals[]; +--- ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h.orig	2005-05-11 07:46:40.000000000 +0200 ++++ ipmitool-1.8.9-rc1/include/ipmitool/ipmi_constants.h	2005-10-23 16:08:13.000000000 +0200 +@@ -42,9 +42,9 @@ +  * COMMANDS +  */ + #define IPMI_GET_SDR_REPOSITORY_INFO            0x20 +-#define IMPI_SOL_ACTIVATING                     0x20 +-#define IMPI_SET_SOL_CONFIG_PARAMETERS          0x21 +-#define IMPI_GET_SOL_CONFIG_PARAMETERS          0x22 ++#define IPMI_SOL_ACTIVATING                     0x20 ++#define IPMI_SET_SOL_CONFIG_PARAMETERS          0x21 ++#define IPMI_GET_SOL_CONFIG_PARAMETERS          0x22 + #define IPMI_SET_USER_ACCESS                    0x43 + #define IPMI_GET_USER_ACCESS                    0x44 + #define IPMI_SET_USER_NAME                      0x45 +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c.orig	2006-08-03 18:26:06.000000000 +0200 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.c	2006-08-25 16:06:37.000000000 +0200 +@@ -862,7 +862,7 @@ + /* +  * read_open_session_reponse +  * +- * Initialize the ipmi_rs from the IMPI 2.x open session response data. ++ * Initialize the ipmi_rs from the IPMI 2.x open session response data. +  * +  * The offset should point to the first byte of the the Open Session Response +  * payload when this function is called. +@@ -924,7 +924,7 @@ + /* +  * read_rakp2_message +  * +- * Initialize the ipmi_rs from the IMPI 2.x RAKP 2 message ++ * Initialize the ipmi_rs from the IPMI 2.x RAKP 2 message +  * +  * The offset should point the first byte of the the RAKP 2 payload when this +  * function is called. +@@ -1004,7 +1004,7 @@ + /* +  * read_rakp4_message +  * +- * Initialize the ipmi_rs from the IMPI 2.x RAKP 4 message ++ * Initialize the ipmi_rs from the IPMI 2.x RAKP 4 message +  * +  * The offset should point the first byte of the the RAKP 4 payload when this +  * function is called. +@@ -1212,7 +1212,7 @@ + /* +  * read_ipmi_response +  * +- * Initialize the impi_rs from with the IPMI response specific data ++ * Initialize the ipmi_rs from with the IPMI response specific data +  * +  * The offset should point the first byte of the the IPMI payload when this +  * function is called.  +@@ -1244,7 +1244,7 @@ + /* +  * read_sol_packet +  * +- * Initialize the impi_rs with the SOL response data ++ * Initialize the ipmi_rs with the SOL response data +  * +  * The offset should point the first byte of the the SOL payload when this +  * function is called.  +@@ -1562,32 +1562,32 @@ + 	 *------------------------------------------ + 	 */ + 	/* ipmi session Auth Type / Format is always 0x06 for IPMI v2 */ +-	msg[IMPI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; ++	msg[IPMI_LANPLUS_OFFSET_AUTHTYPE] = 0x06; +  + 	/* Payload Type -- also specifies whether were authenticated/encyrpted */ +-	msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; ++	msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] = payload->payload_type; +  + 	if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) + 	{ +-		msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= ++		msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= + 			((session->v2_data.crypt_alg != IPMI_CRYPT_NONE	)? 0x80 : 0x00); +-		msg[IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= ++		msg[IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE] |= + 			((session->v2_data.integrity_alg  != IPMI_INTEGRITY_NONE)? 0x40 : 0x00); + 	} +  + 	if (session->v2_data.session_state == LANPLUS_STATE_ACTIVE) + 	{ + 		/* Session ID  -- making it LSB */ +-		msg[IMPI_LANPLUS_OFFSET_SESSION_ID    ] = session->v2_data.bmc_id         & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8)  & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SESSION_ID    ] = session->v2_data.bmc_id         & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 1] = (session->v2_data.bmc_id >> 8)  & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 2] = (session->v2_data.bmc_id >> 16) & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SESSION_ID + 3] = (session->v2_data.bmc_id >> 24) & 0xff; +  + 		/* Sequence Number -- making it LSB */ +-		msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM    ] = session->out_seq         & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8)  & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; +-		msg[IMPI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM    ] = session->out_seq         & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 1] = (session->out_seq >> 8)  & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 2] = (session->out_seq >> 16) & 0xff; ++		msg[IPMI_LANPLUS_OFFSET_SEQUENCE_NUM + 3] = (session->out_seq >> 24) & 0xff; + 	} +  + 	/* +@@ -1679,9 +1679,9 @@ + 	} +  + 	/* Now we know the payload length */ +-	msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE    ] = ++	msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE    ] = + 		payload->payload_length        & 0xff; +-	msg[IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = ++	msg[IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE + 1] = + 		(payload->payload_length >> 8) & 0xff; +  +  +@@ -1745,14 +1745,14 @@ + 			2; +  + 		if (verbose > 2) +-			printbuf(msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); ++			printbuf(msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, hmac_input_size, "authcode input"); +  +  + 		/* Auth Code */ + 		lanplus_HMAC(session->v2_data.integrity_alg, + 					 session->v2_data.k1,                /* key        */ + 					 20,                                 /* key length */ +-					 msg + IMPI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ ++					 msg + IPMI_LANPLUS_OFFSET_AUTHTYPE, /* hmac input */ + 					 hmac_input_size, + 					 hmac_output, + 					 &hmac_length); +@@ -2529,7 +2529,7 @@ +  * ipmi_get_auth_capabilities_cmd +  * +  * This command may have to be sent twice.  We first ask for the +- * authentication capabilities with the "request IMPI v2 data bit" ++ * authentication capabilities with the "request IPMI v2 data bit" +  * set.  If this fails, we send the same command without that bit +  * set. +  * +@@ -2602,7 +2602,7 @@ +  +  + static int +-impi_close_session_cmd(struct ipmi_intf * intf) ++ipmi_close_session_cmd(struct ipmi_intf * intf) + { + 	struct ipmi_rs * rsp; + 	struct ipmi_rq req; +@@ -2836,7 +2836,7 @@ + /* +  * ipmi_lanplus_rakp1 +  * +- * Build and send the RAKP 1 message as part of the IMPI v2 / RMCP+ session ++ * Build and send the RAKP 1 message as part of the IPMI v2 / RMCP+ session +  * negotiation protocol.  We also read and validate the RAKP 2 message received +  * from the BMC, here.  See section 13.20 of the IPMI v2 specification for +  * details. +@@ -2990,7 +2990,7 @@ + /* +  * ipmi_lanplus_rakp3 +  * +- * Build and send the RAKP 3 message as part of the IMPI v2 / RMCP+ session ++ * Build and send the RAKP 3 message as part of the IPMI v2 / RMCP+ session +  * negotiation protocol.  We also read and validate the RAKP 4 message received +  * from the BMC, here.  See section 13.20 of the IPMI v2 specification for +  * details. +@@ -3154,7 +3154,7 @@ + ipmi_lanplus_close(struct ipmi_intf * intf) + { + 	if (!intf->abort) +-		impi_close_session_cmd(intf); ++		ipmi_close_session_cmd(intf); +  + 	if (intf->fd >= 0) + 		close(intf->fd); +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h.orig	2005-03-17 00:17:37.000000000 +0100 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus.h	2005-10-23 16:09:48.000000000 +0200 +@@ -84,11 +84,11 @@ +  +  + /* Session message offsets, from table 13-8 of the v2 specification */ +-#define IMPI_LANPLUS_OFFSET_AUTHTYPE     0x04 +-#define IMPI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 +-#define IMPI_LANPLUS_OFFSET_SESSION_ID   0x06 +-#define IMPI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A +-#define IMPI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E ++#define IPMI_LANPLUS_OFFSET_AUTHTYPE     0x04 ++#define IPMI_LANPLUS_OFFSET_PAYLOAD_TYPE 0x05 ++#define IPMI_LANPLUS_OFFSET_SESSION_ID   0x06 ++#define IPMI_LANPLUS_OFFSET_SEQUENCE_NUM 0x0A ++#define IPMI_LANPLUS_OFFSET_PAYLOAD_SIZE 0x0E + #define IPMI_LANPLUS_OFFSET_PAYLOAD      0x10 +  +  +--- ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c.orig	2005-03-24 02:46:03.000000000 +0100 ++++ ipmitool-1.8.9-rc1/src/plugins/lanplus/lanplus_crypt.c	2005-10-23 16:10:06.000000000 +0200 +@@ -800,8 +800,8 @@ + 	lanplus_HMAC(session->v2_data.integrity_alg, + 				 session->v2_data.k1, + 				 IPMI_AUTHCODE_BUFFER_SIZE, +-				 rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, +-				 rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, ++				 rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, ++				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + 				 generated_authcode, + 				 &generated_authcode_length); +  +@@ -809,8 +809,8 @@ + 	{ + 		lprintf(LOG_DEBUG+2, "Validating authcode"); + 		printbuf(session->v2_data.k1, 20, "K1"); +-		printbuf(rs->data + IMPI_LANPLUS_OFFSET_AUTHTYPE, +-				 rs->data_len - IMPI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, ++		printbuf(rs->data + IPMI_LANPLUS_OFFSET_AUTHTYPE, ++				 rs->data_len - IPMI_LANPLUS_OFFSET_AUTHTYPE - IPMI_SHA1_AUTHCODE_SIZE, + 				 "Authcode Input Data"); + 		printbuf(generated_authcode, 12, "Generated authcode"); + 		printbuf(bmc_authcode,       12, "Expected authcode"); diff --git a/debian/patches/20_ipmi_isol.dpatch b/debian/patches/20_ipmi_isol.dpatch new file mode 100644 index 0000000..382e62a --- /dev/null +++ b/debian/patches/20_ipmi_isol.dpatch @@ -0,0 +1,1857 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 20_ipmi_isol.dpatch by  <mjj29@debian.org> +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: 20_ipmi_isol, closes #412816 + +@DPATCH@ + +diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h ipmitool-1.8.9/include/ipmitool/ipmi_isol.h +--- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h	2007-02-22 08:38:55.000000000 +0000 ++++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h	2007-12-13 10:16:57.063986495 +0000 +@@ -41,15 +41,16 @@ +  + #define ISOL_ENABLE_PARAM		0x01 + #define ISOL_AUTHENTICATION_PARAM	0x02 +-#define ISOL_ENABLE_FLAG			0x01 +-#define ISOL_PRIVILEGE_LEVEL_USER	0x02 ++ + #define ISOL_BAUD_RATE_PARAM		0x05 +-#define ISOL_BAUD_RATE_9600		0x06 +-#define ISOL_BAUD_RATE_19200		0x07 +-#define ISOL_BAUD_RATE_38400		0x08 +-#define ISOL_BAUD_RATE_57600		0x09 +-#define ISOL_BAUD_RATE_115200		0x0A +-#define ISOL_PREFERRED_BAUD_RATE		0x07 ++ ++#define ISOL_PREFERRED_BAUD_RATE	0x07 ++ ++struct isol_config_parameters { ++	uint8_t  enabled; ++	uint8_t  privilege_level; ++	uint8_t  bit_rate; ++}; +  + int ipmi_isol_main(struct ipmi_intf *, int, char **); +  +diff -urN ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig +--- ipmitool-1.8.9.orig/include/ipmitool/ipmi_isol.h.orig	1970-01-01 01:00:00.000000000 +0100 ++++ ipmitool-1.8.9/include/ipmitool/ipmi_isol.h.orig	2007-02-22 08:38:55.000000000 +0000 +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved. ++ *  ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ *  ++ * Redistribution of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ *  ++ * Redistribution in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ *  ++ * Neither the name of Sun Microsystems, Inc. or the names of ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ *  ++ * This software is provided "AS IS," without a warranty of any kind. ++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, ++ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A ++ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ++ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING ++ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL ++ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, ++ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR ++ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF ++ * 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. ++ */ ++ ++#ifndef IPMI_ISOL_H ++#define IPMI_ISOL_H ++ ++#include <ipmitool/ipmi.h> ++ ++#define ACTIVATE_ISOL			0x01 ++#define SET_ISOL_CONFIG			0x03 ++#define GET_ISOL_CONFIG			0x04 ++ ++#define ISOL_ENABLE_PARAM		0x01 ++#define ISOL_AUTHENTICATION_PARAM	0x02 ++#define ISOL_ENABLE_FLAG			0x01 ++#define ISOL_PRIVILEGE_LEVEL_USER	0x02 ++#define ISOL_BAUD_RATE_PARAM		0x05 ++#define ISOL_BAUD_RATE_9600		0x06 ++#define ISOL_BAUD_RATE_19200		0x07 ++#define ISOL_BAUD_RATE_38400		0x08 ++#define ISOL_BAUD_RATE_57600		0x09 ++#define ISOL_BAUD_RATE_115200		0x0A ++#define ISOL_PREFERRED_BAUD_RATE		0x07 ++ ++int ipmi_isol_main(struct ipmi_intf *, int, char **); ++ ++#endif /* IPMI_SOL_H */ +diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c ipmitool-1.8.9/lib/ipmi_isol.c +--- ipmitool-1.8.9.orig/lib/ipmi_isol.c	2007-02-22 08:38:56.000000000 +0000 ++++ ipmitool-1.8.9/lib/ipmi_isol.c	2007-12-13 10:16:57.063986495 +0000 +@@ -32,7 +32,17 @@ +  + #include <stdlib.h> + #include <string.h> ++#include <strings.h> + #include <stdio.h> ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <sys/select.h> ++#include <sys/time.h> ++#include <signal.h> ++#include <unistd.h> ++ ++ ++#include <termios.h> +  + #include <ipmitool/helper.h> + #include <ipmitool/log.h> +@@ -41,39 +51,40 @@ + #include <ipmitool/ipmi_intf.h> + #include <ipmitool/ipmi_isol.h> +  +-const struct valstr ipmi_isol_baud_vals[] = { +-	{ ISOL_BAUD_RATE_9600,   "9600" }, +-	{ ISOL_BAUD_RATE_19200,  "19200" }, +-	{ ISOL_BAUD_RATE_38400,  "38400" }, +-	{ ISOL_BAUD_RATE_57600,  "57600" }, +-	{ ISOL_BAUD_RATE_115200, "115200" }, +-	{ 0x00, NULL } +-}; ++static struct termios _saved_tio; ++static int            _in_raw_mode = 0; +  + extern int verbose; +  +-static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) ++#define ISOL_ESCAPE_CHARACTER                    '~' ++ ++/* ++ * ipmi_get_isol_info ++ */ ++static int ipmi_get_isol_info(struct ipmi_intf * intf, ++			      struct isol_config_parameters * params) + { + 	struct ipmi_rs * rsp; + 	struct ipmi_rq req; +-	unsigned char data[6];	 ++	unsigned char data[6]; +  +-	/* TEST FOR AVAILABILITY */ ++	memset(&req, 0, sizeof(req)); ++	req.msg.netfn = IPMI_NETFN_ISOL; ++	req.msg.cmd = GET_ISOL_CONFIG; ++	req.msg.data = data; ++	req.msg.data_len = 4; +  ++	/* GET ISOL ENABLED CONFIG */ ++	 + 	memset(data, 0, 6); + 	data[0] = 0x00; + 	data[1] = ISOL_ENABLE_PARAM; +-	data[2] = ISOL_ENABLE_FLAG; +- +-	memset(&req, 0, sizeof(req)); +-	req.msg.netfn = IPMI_NETFN_ISOL; +-	req.msg.cmd = SET_ISOL_CONFIG; +-	req.msg.data = data; +-	req.msg.data_len = 3; ++	data[2] = 0x00;		/* block */ ++	data[3] = 0x00;		/* selector */ +  + 	rsp = intf->sendrecv(intf, &req); + 	if (rsp == NULL) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config Command"); ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command"); + 		return -1; + 	} + 	if (rsp->ccode == 0xc1) { +@@ -81,20 +92,19 @@ + 		return -1; + 	} + 	if (rsp->ccode > 0) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", + 			val2str(rsp->ccode, completion_code_vals)); + 		return -1; + 	} ++	params->enabled = rsp->data[1]; +  +-	/* GET ISOL CONFIG */ +- ++	/* GET ISOL AUTHENTICATON CONFIG */ ++	 + 	memset(data, 0, 6); + 	data[0] = 0x00; + 	data[1] = ISOL_AUTHENTICATION_PARAM; + 	data[2] = 0x00;		/* block */ + 	data[3] = 0x00;		/* selector */ +-	req.msg.cmd = GET_ISOL_CONFIG; +-	req.msg.data_len = 4; +  + 	rsp = intf->sendrecv(intf, &req); + 	if (rsp == NULL) { +@@ -106,86 +116,713 @@ + 			val2str(rsp->ccode, completion_code_vals)); + 		return -1; + 	} +- +-	if (verbose > 1) +-		printbuf(rsp->data, rsp->data_len, "ISOL Config"); +- +-	/* SET ISOL CONFIG - AUTHENTICATION */ +- ++	params->privilege_level = rsp->data[1]; ++	 ++	/* GET ISOL BAUD RATE CONFIG */ ++	 + 	memset(data, 0, 6); + 	data[0] = 0x00; +-	data[1] = ISOL_AUTHENTICATION_PARAM; +-	data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); +-	req.msg.cmd = SET_ISOL_CONFIG; +-	req.msg.data_len = 3; ++	data[1] = ISOL_BAUD_RATE_PARAM; ++	data[2] = 0x00;		/* block */ ++	data[3] = 0x00;		/* selector */ +  + 	rsp = intf->sendrecv(intf, &req); + 	if (rsp == NULL) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command"); + 		return -1; + 	} + 	if (rsp->ccode > 0) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", + 			val2str(rsp->ccode, completion_code_vals)); + 		return -1; + 	} ++	params->bit_rate = rsp->data[1]; +  +-	/* SET ISOL CONFIG - BAUD RATE */ ++	return 0; ++} +  +-	memset(data, 0, 6); +-	data[0] = 0x00; +-	data[1] = ISOL_BAUD_RATE_PARAM; +-	data[2] = baudsetting; ++static int ipmi_print_isol_info(struct ipmi_intf * intf) ++{ ++	struct isol_config_parameters params = {0}; ++	if (ipmi_get_isol_info(intf, ¶ms)) ++		return -1; ++ ++	if (csv_output) ++	{ ++		printf("%s,", (params.enabled & 0x1)?"true": "false"); ++		printf("%s,", ++			   val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); ++		printf("%s,", ++			   val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); ++	} ++	else ++	{ ++		printf("Enabled                         : %s\n", ++		       (params.enabled & 0x1)?"true": "false"); ++		printf("Privilege Level                 : %s\n", ++		       val2str((params.privilege_level & 0xf), ipmi_privlvl_vals)); ++		printf("Bit Rate (kbps)                 : %s\n", ++		       val2str((params.bit_rate & 0xf), ipmi_bit_rate_vals)); ++	} ++ ++	return 0; ++} ++ ++static int ipmi_isol_set_param(struct ipmi_intf * intf, ++			       const char *param, ++			       const char *value) ++{ ++	struct ipmi_rs * rsp; ++	struct ipmi_rq req; ++	unsigned char data[6];	 ++	struct isol_config_parameters params = {0}; ++ ++	/* We need other values to complete the request */ ++	if (ipmi_get_isol_info(intf, ¶ms)) ++		return -1; ++ ++	memset(&req, 0, sizeof(req)); ++	req.msg.netfn = IPMI_NETFN_ISOL; + 	req.msg.cmd = SET_ISOL_CONFIG; ++	req.msg.data = data; + 	req.msg.data_len = 3; +  ++	memset(data, 0, 6); ++	 ++	/* ++	 * enabled ++	 */ ++	if (strcmp(param, "enabled") == 0) ++	{ ++		data[1] = ISOL_ENABLE_PARAM; ++		if (strcmp(value, "true") == 0) ++			data[2] = 0x01; ++		else if (strcmp(value, "false") == 0) ++			data[2] = 0x00; ++		else { ++			lprintf(LOG_ERR, "Invalid value %s for parameter %s", ++				   value, param); ++			lprintf(LOG_ERR, "Valid values are true and false"); ++			return -1; ++		} ++	} ++ ++	/* ++	 * privilege-level ++	 */ ++	else if (strcmp(param, "privilege-level") == 0) ++	{ ++		data[1] = ISOL_AUTHENTICATION_PARAM; ++		if (! strcmp(value, "user")) ++			data[2] = 0x02; ++		else if (! strcmp(value, "operator")) ++			data[2] = 0x03; ++		else if (! strcmp(value, "admin")) ++			data[2] = 0x04; ++		else if (! strcmp(value, "oem")) ++			data[2] = 0x05; ++		else ++		{ ++			lprintf(LOG_ERR, "Invalid value %s for parameter %s", ++				   value, param); ++			lprintf(LOG_ERR, "Valid values are user, operator, admin, and oem"); ++			return -1; ++		} ++		/* We need to mask bit7 from the fetched value */ ++		data[2] |= (params.privilege_level & 0x80) ? 0x80 : 0x00; ++	} ++ ++	/* ++	 * bit-rate ++	 */ ++	else if (strcmp(param, "bit-rate") == 0) ++	{ ++		data[1] = ISOL_BAUD_RATE_PARAM; ++		if (strncmp(value, "9.6", 3) == 0) { ++			data[2] = 0x06; ++		} ++		else if (strncmp(value, "19.2", 4) == 0) { ++			data[2] = 0x07; ++		} ++		else if (strncmp(value, "38.4", 4) == 0) { ++			data[2] = 0x08; ++		} ++		else if (strncmp(value, "57.6", 4) == 0) { ++			data[2] = 0x09; ++		} ++		else if (strncmp(value, "115.2", 5) == 0) { ++			data[2] = 0x0A; ++		} ++		else { ++			lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", value); ++			lprintf(LOG_ERR, "Valid values are 9.6, 19.2, 38.4, 57.6 and 115.2"); ++			return -1; ++		} ++	} ++	else ++	{ ++		lprintf(LOG_ERR, "Error: invalid ISOL parameter %s", param); ++		return -1; ++	} ++	 ++	 ++	/* ++	 * Execute the request ++	 */ ++ + 	rsp = intf->sendrecv(intf, &req); + 	if (rsp == NULL) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); ++		lprintf(LOG_ERR, "Error setting ISOL parameter '%s'", param); + 		return -1; + 	} + 	if (rsp->ccode > 0) { +-		lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", +-			val2str(rsp->ccode, completion_code_vals)); ++		lprintf(LOG_ERR, "Error setting ISOL parameter '%s': %s", ++			   param, val2str(rsp->ccode, completion_code_vals)); + 		return -1; + 	} +  +-	printf("Set ISOL Baud Rate to %s\n", +-	       val2str(baudsetting, ipmi_isol_baud_vals)); ++	return 0; ++} ++ ++static void ++leave_raw_mode(void) ++{ ++	if (!_in_raw_mode) ++		return; ++	if (tcsetattr(fileno(stdin), TCSADRAIN, &_saved_tio) == -1) ++		perror("tcsetattr"); ++	else ++		_in_raw_mode = 0; ++} ++ ++ ++ ++static void ++enter_raw_mode(void) ++{ ++	struct termios tio; ++	if (tcgetattr(fileno(stdin), &tio) == -1) { ++		perror("tcgetattr"); ++		return; ++	} ++	_saved_tio = tio; ++	tio.c_iflag |= IGNPAR; ++	tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF)\ ++		; ++	tio.c_lflag &= ~(ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHONL); ++	//	#ifdef IEXTEN ++	tio.c_lflag &= ~IEXTEN; ++	//	#endif ++	tio.c_oflag &= ~OPOST; ++	tio.c_cc[VMIN] = 1; ++	tio.c_cc[VTIME] = 0; ++	if (tcsetattr(fileno(stdin), TCSADRAIN, &tio) == -1) ++		perror("tcsetattr"); ++	else ++		_in_raw_mode = 1; ++} ++ ++ ++static void ++sendBreak(struct ipmi_intf * intf) ++{ ++	struct ipmi_v2_payload  v2_payload; ++ ++	memset(&v2_payload, 0, sizeof(v2_payload)); ++ ++	v2_payload.payload.sol_packet.character_count = 0; ++	v2_payload.payload.sol_packet.generate_break  = 1; ++ ++	intf->send_sol(intf, &v2_payload); ++} ++ ++/* ++ * suspendSelf ++ * ++ * Put ourself in the background ++ * ++ * param bRestoreTty specifies whether we will put our self back ++ *       in raw mode when we resume ++ */ ++static void ++suspendSelf(int bRestoreTty) ++{ ++	leave_raw_mode(); ++	kill(getpid(), SIGTSTP); ++ ++	if (bRestoreTty) ++		enter_raw_mode(); ++} ++ ++ ++ ++/* ++ * printiSolEscapeSequences ++ * ++ * Send some useful documentation to the user ++ */ ++static void ++printiSolEscapeSequences(void) ++{ ++	printf( ++		   "%c?\r\n\ ++	Supported escape sequences:\r\n\ ++	%c.  - terminate connection\r\n\ ++	%c^Z - suspend ipmitool\r\n\ ++	%c^X - suspend ipmitool, but don't restore tty on restart\r\n\ ++	%cB  - send break\r\n\ ++	%c?  - this message\r\n\ ++	%c%c  - send the escape character by typing it twice\r\n\ ++	(Note that escapes are only recognized immediately after newline.)\r\n", ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER, ++		   ISOL_ESCAPE_CHARACTER); ++} ++ ++ ++ ++/* ++ * output ++ * ++ * Send the specified data to stdout ++ */ ++static void ++output(struct ipmi_rs * rsp) ++{ ++	if (rsp) ++	{ ++		int i; ++		for (i = 0; i < rsp->data_len; ++i) ++			putc(rsp->data[i], stdout); ++ ++		fflush(stdout); ++	} ++} ++ ++/* ++ * ipmi_isol_deactivate ++ */ ++static int ++ipmi_isol_deactivate(struct ipmi_intf * intf) ++{ ++	struct ipmi_rs * rsp; ++	struct ipmi_rq   req; ++	uint8_t    data[6];	  ++	struct isol_config_parameters params; ++ ++	memset(&req, 0, sizeof(req)); ++	req.msg.netfn = IPMI_NETFN_ISOL; ++	req.msg.cmd = ACTIVATE_ISOL; ++	req.msg.data = data; ++	req.msg.data_len = 5; +  ++	memset(data, 0, 6); ++	data[0] = 0x00; /* Deactivate */ ++	data[1] = 0x00; ++	data[2] = 0x00; ++	data[3] = 0x00; ++	data[5] = 0x00; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (rsp == NULL) { ++		lprintf(LOG_ERR, "Error deactivating ISOL"); ++		return -1; ++	} ++	if (rsp->ccode > 0) { ++		lprintf(LOG_ERR, "Error deactivating ISOL: %s", ++			val2str(rsp->ccode, completion_code_vals)); ++		return -1; ++	} ++	/* response contain 4 additional bytes : 80 00 32 ff ++	   Don't know what to use them for yet... */ + 	return 0; + } +  +-int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++/* ++ * processiSolUserInput ++ * ++ * Act on user input into the ISOL session.  The only reason this ++ * is complicated is that we have to process escape sequences. ++ * ++ * return   0 on success ++ *          1 if we should exit ++ *        < 0 on error (BMC probably closed the session) ++ */ ++static int ++processiSolUserInput(struct ipmi_intf * intf, ++		    uint8_t * input, ++		    uint16_t  buffer_length) + { +-	int ret = 0; ++	static int escape_pending = 0; ++	static int last_was_cr    = 1; ++	struct ipmi_v2_payload v2_payload; ++	int  length               = 0; ++	int  retval               = 0; ++	char ch; ++	int  i; ++ ++	memset(&v2_payload, 0, sizeof(v2_payload)); ++	 ++	/* ++	 * Our first order of business is to check the input for escape ++	 * sequences to act on. ++	 */ ++	for (i = 0; i < buffer_length; ++i) ++	{ ++		ch = input[i]; ++ ++		if (escape_pending){ ++			escape_pending = 0; ++			 ++			/* ++			 * Process a possible escape sequence. ++			 */ ++			switch (ch) { ++			case '.': ++				printf("%c. [terminated ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++				retval = 1; ++				break; ++			case 'Z' - 64: ++				printf("%c^Z [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++				suspendSelf(1); /* Restore tty back to raw */ ++				continue; ++ ++			case 'X' - 64: ++				printf("%c^X [suspend ipmitool]\r\n", ISOL_ESCAPE_CHARACTER); ++				suspendSelf(0); /* Don't restore to raw mode */ ++				continue; ++ ++			case 'B': ++				printf("%cb [send break]\r\n", ISOL_ESCAPE_CHARACTER); ++				sendBreak(intf); ++				continue; ++ ++			case '?': ++				printiSolEscapeSequences(); ++				continue; ++			default: ++				if (ch != ISOL_ESCAPE_CHARACTER) ++					v2_payload.payload.sol_packet.data[length++] = ++						ISOL_ESCAPE_CHARACTER; ++				v2_payload.payload.sol_packet.data[length++] = ch; ++			} ++		} +  +-	if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { +-		lprintf(LOG_NOTICE, "ISOL Commands: setup <baud>"); +-		lprintf(LOG_NOTICE, "ISOL Baud Rates:  9600, 19200, 38400, 57600, 115200"); +-		return 0; +-	} +-		 +-	if (strncmp(argv[0], "setup", 5) == 0) { +-		if (strncmp(argv[1], "9600", 4) == 0) { +-			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); +-		} +-		else if (strncmp(argv[1], "19200", 5) == 0) { +-			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); ++		else ++		{ ++			if (last_was_cr && (ch == ISOL_ESCAPE_CHARACTER)) { ++				escape_pending = 1; ++				continue; ++			} ++ ++			v2_payload.payload.sol_packet.data[length++] =	ch; + 		} +-		else if (strncmp(argv[1], "38400", 5) == 0) { +-			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); ++ ++ ++		/* ++		 * Normal character.  Record whether it was a newline. ++		 */ ++		last_was_cr = (ch == '\r' || ch == '\n'); ++	} ++ ++	/* ++	 * If there is anything left to process we dispatch it to the BMC, ++	 * send intf->session->sol_data.max_outbound_payload_size bytes ++	 * at a time. ++	 */ ++	if (length) ++	{ ++		struct ipmi_rs * rsp; ++ ++		v2_payload.payload.sol_packet.flush_outbound = 1; /* Not sure if necessary ? */ ++		v2_payload.payload.sol_packet.character_count = length; ++		rsp = intf->send_sol(intf, &v2_payload); ++ ++		if (! rsp) { ++			lprintf(LOG_ERR, "Error sending SOL data"); ++			retval = -1; + 		} +-		else if (strncmp(argv[1], "57600", 5) == 0) { +-			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); ++ ++		/* If the sequence number is set we know we have new data */ ++		else if ((rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)        && ++			 (rsp->payload.sol_packet.packet_sequence_number)) ++			output(rsp); ++	} ++	return retval; ++} ++ ++/* ++ * ipmi_isol_red_pill ++ */ ++static int ++ipmi_isol_red_pill(struct ipmi_intf * intf) ++{ ++	char   * buffer; ++	int    numRead; ++	int    bShouldExit       = 0; ++	int    bBmcClosedSession = 0; ++	fd_set read_fds; ++	struct timeval tv; ++	int    retval; ++	int    buffer_size = 255; ++	int    timedout = 0; ++ ++	buffer = (char*)malloc(buffer_size); ++	if (buffer == NULL) { ++		lprintf(LOG_ERR, "ipmitool: malloc failure"); ++		return -1; ++	} ++ ++	enter_raw_mode(); ++ ++	while (! bShouldExit) ++	{ ++		FD_ZERO(&read_fds); ++		FD_SET(0, &read_fds); ++		FD_SET(intf->fd, &read_fds); ++ ++		/* Wait up to half a second */ ++		tv.tv_sec =  0; ++		tv.tv_usec = 500000; ++ ++		retval = select(intf->fd + 1, &read_fds, NULL, NULL, &tv); ++ ++		if (retval) ++		{ ++			if (retval == -1) ++			{ ++				/* ERROR */ ++				perror("select"); ++				return -1; ++			} ++ ++			timedout = 0; ++ ++			/* ++			 * Process input from the user ++			 */ ++			if (FD_ISSET(0, &read_fds)) ++	 		{ ++				bzero(buffer, sizeof(buffer)); ++				numRead = read(fileno(stdin), ++							   buffer, ++							   buffer_size); ++				 ++				if (numRead > 0) ++				{ ++					int rc = processiSolUserInput(intf, buffer, numRead); ++					 ++					if (rc) ++					{ ++						if (rc < 0) ++							bShouldExit = bBmcClosedSession = 1; ++						else ++							bShouldExit = 1; ++					} ++				} ++				else ++				{ ++					bShouldExit = 1; ++				} ++			} ++ ++ ++			/* ++			 * Process input from the BMC ++			 */ ++			else if (FD_ISSET(intf->fd, &read_fds)) ++			{ ++				struct ipmi_rs * rs = intf->recv_sol(intf); ++				if (! rs) ++				{ ++					bShouldExit = bBmcClosedSession = 1; ++				} ++				else ++					output(rs); ++ 			} ++ ++			 ++			/* ++			 * ERROR in select ++			 */ ++ 			else ++			{ ++				lprintf(LOG_ERR, "Error: Select returned with nothing to read"); ++				bShouldExit = 1; ++			} + 		} +-		else if (strncmp(argv[1], "115200", 6) == 0) { +-			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); ++		else ++		{ ++			if ((++timedout) == 20) /* Every 10 seconds we send a keepalive */ ++			{ ++				intf->keepalive(intf); ++				timedout = 0; ++			} + 		} +-		else { +-			lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); +-			ret = -1; ++	}		 ++ ++	leave_raw_mode(); ++ ++	if (bBmcClosedSession) ++	{ ++		lprintf(LOG_ERR, "SOL session closed by BMC"); ++	} ++	else ++		ipmi_isol_deactivate(intf); ++ ++	return 0; ++} ++ ++/* ++ * ipmi_isol_activate ++ */ ++static int ++ipmi_isol_activate(struct ipmi_intf * intf) ++{ ++	struct ipmi_rs * rsp; ++	struct ipmi_rq   req; ++	uint8_t    data[6];	  ++	struct isol_config_parameters params; ++ ++	if (ipmi_get_isol_info(intf, ¶ms)) ++		return -1; ++ ++	if (!(params.enabled & 0x1)) { ++		lprintf(LOG_ERR, "ISOL is not enabled!"); ++		return -1; ++	} ++ ++	/* ++	 * Setup a callback so that the lanplus processing knows what ++	 * to do with packets that come unexpectedly (while waiting for ++	 * an ACK, perhaps. ++	 */ ++	intf->session->sol_data.sol_input_handler = output; ++	 ++	memset(&req, 0, sizeof(req)); ++	req.msg.netfn = IPMI_NETFN_ISOL; ++	req.msg.cmd = ACTIVATE_ISOL; ++	req.msg.data = data; ++	req.msg.data_len = 5; ++ ++	memset(data, 0, 6); ++	data[0] = 0x01; ++	data[1] = 0x00; ++	data[2] = 0x00; ++	data[3] = 0x00; ++	data[5] = 0x00; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (NULL != rsp) { ++		switch (rsp->ccode) { ++			case 0x00:  ++				if (rsp->data_len == 4) { ++					break; ++				} else { ++					lprintf(LOG_ERR, "Error: Unexpected data length (%d) received " ++						   "in ISOL activation response", ++						   rsp->data_len); ++					return -1; ++				} ++				break; ++			case 0x80: ++				lprintf(LOG_ERR, "Info: ISOL already active on another session"); ++				return -1; ++			case 0x81: ++				lprintf(LOG_ERR, "Info: ISOL disabled"); ++				return -1; ++			case 0x82: ++				lprintf(LOG_ERR, "Info: ISOL activation limit reached"); ++				return -1; ++			default: ++				lprintf(LOG_ERR, "Error activating ISOL: %s", ++					val2str(rsp->ccode, completion_code_vals)); ++				return -1; ++		}				 ++	} else { ++		lprintf(LOG_ERR, "Error: No response activating ISOL"); ++		return -1; ++	} ++ ++	/* response contain 4 additional bytes : 80 01 32 ff ++	   Don't know what to use them for yet... */ ++ ++	printf("[SOL Session operational.  Use %c? for help]\r\n", ++	       ISOL_ESCAPE_CHARACTER); ++ ++	/* ++	 * At this point we are good to go with our SOL session.  We ++	 * need to listen to ++	 * 1) STDIN for user input ++	 * 2) The FD for incoming SOL packets ++	 */ ++	if (ipmi_isol_red_pill(intf)) { ++		lprintf(LOG_ERR, "Error in SOL session"); ++		return -1; ++	} ++ ++	return 0; ++} ++ ++static void print_isol_set_usage(void) { ++	lprintf(LOG_NOTICE, "\nISOL set parameters and values: \n"); ++	lprintf(LOG_NOTICE, "  enabled                     true | false"); ++	lprintf(LOG_NOTICE, "  privilege-level             user | operator | admin | oem"); ++	lprintf(LOG_NOTICE, "  bit-rate                    " ++		"9.6 | 19.2 | 38.4 | 57.6 | 115.2"); ++	lprintf(LOG_NOTICE, ""); ++} ++ ++static void print_isol_usage(void) { ++	lprintf(LOG_NOTICE, "ISOL Commands: info"); ++	lprintf(LOG_NOTICE, "               set <parameter> <setting>"); ++	lprintf(LOG_NOTICE, "               activate"); ++} ++ ++int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++{ ++	int ret = 0; ++ ++	/* ++	 * Help ++	 */ ++	if (!argc || !strncmp(argv[0], "help", 4)) ++		print_isol_usage(); ++ ++	/* ++	 * Info ++	 */ ++	else if (!strncmp(argv[0], "info", 4)) { ++		ret = ipmi_print_isol_info(intf); ++	} ++ ++	/* ++	 * Set a parameter value ++	 */ ++	else if (!strncmp(argv[0], "set", 3)) { ++		if (argc < 3) { ++			print_isol_set_usage(); ++			return -1; + 		} ++		ret = ipmi_isol_set_param(intf, argv[1], argv[2]); ++	} ++ ++	/* ++	 * Activate ++	 */ ++ 	else if (!strncmp(argv[0], "activate", 8)) { ++		ret = ipmi_isol_activate(intf); ++	} ++	 ++	else { ++		print_isol_usage(); ++		ret = -1; + 	} ++	 + 	return ret; + } +diff -urN ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig ipmitool-1.8.9/lib/ipmi_isol.c.orig +--- ipmitool-1.8.9.orig/lib/ipmi_isol.c.orig	1970-01-01 01:00:00.000000000 +0100 ++++ ipmitool-1.8.9/lib/ipmi_isol.c.orig	2007-02-22 08:38:56.000000000 +0000 +@@ -0,0 +1,191 @@ ++/* ++ * Copyright (c) 2003 Sun Microsystems, Inc.  All Rights Reserved. ++ *  ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ *  ++ * Redistribution of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ *  ++ * Redistribution in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ *  ++ * Neither the name of Sun Microsystems, Inc. or the names of ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ *  ++ * This software is provided "AS IS," without a warranty of any kind. ++ * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, ++ * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A ++ * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ++ * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE ++ * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING ++ * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.  IN NO EVENT WILL ++ * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, ++ * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR ++ * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF ++ * 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. ++ */ ++ ++#include <stdlib.h> ++#include <string.h> ++#include <stdio.h> ++ ++#include <ipmitool/helper.h> ++#include <ipmitool/log.h> ++#include <ipmitool/ipmi.h> ++#include <ipmitool/ipmi_strings.h> ++#include <ipmitool/ipmi_intf.h> ++#include <ipmitool/ipmi_isol.h> ++ ++const struct valstr ipmi_isol_baud_vals[] = { ++	{ ISOL_BAUD_RATE_9600,   "9600" }, ++	{ ISOL_BAUD_RATE_19200,  "19200" }, ++	{ ISOL_BAUD_RATE_38400,  "38400" }, ++	{ ISOL_BAUD_RATE_57600,  "57600" }, ++	{ ISOL_BAUD_RATE_115200, "115200" }, ++	{ 0x00, NULL } ++}; ++ ++extern int verbose; ++ ++static int ipmi_isol_setup(struct ipmi_intf * intf, char baudsetting) ++{ ++	struct ipmi_rs * rsp; ++	struct ipmi_rq req; ++	unsigned char data[6];	 ++ ++	/* TEST FOR AVAILABILITY */ ++ ++	memset(data, 0, 6); ++	data[0] = 0x00; ++	data[1] = ISOL_ENABLE_PARAM; ++	data[2] = ISOL_ENABLE_FLAG; ++ ++	memset(&req, 0, sizeof(req)); ++	req.msg.netfn = IPMI_NETFN_ISOL; ++	req.msg.cmd = SET_ISOL_CONFIG; ++	req.msg.data = data; ++	req.msg.data_len = 3; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (rsp == NULL) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config Command"); ++		return -1; ++	} ++	if (rsp->ccode == 0xc1) { ++		lprintf(LOG_ERR, "IPMI v1.5 Serial Over Lan (ISOL) not supported!"); ++		return -1; ++	} ++	if (rsp->ccode > 0) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config Command: %s", ++			val2str(rsp->ccode, completion_code_vals)); ++		return -1; ++	} ++ ++	/* GET ISOL CONFIG */ ++ ++	memset(data, 0, 6); ++	data[0] = 0x00; ++	data[1] = ISOL_AUTHENTICATION_PARAM; ++	data[2] = 0x00;		/* block */ ++	data[3] = 0x00;		/* selector */ ++	req.msg.cmd = GET_ISOL_CONFIG; ++	req.msg.data_len = 4; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (rsp == NULL) { ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command"); ++		return -1; ++	} ++	if (rsp->ccode > 0) { ++		lprintf(LOG_ERR, "Error in Get ISOL Config Command: %s", ++			val2str(rsp->ccode, completion_code_vals)); ++		return -1; ++	} ++ ++	if (verbose > 1) ++		printbuf(rsp->data, rsp->data_len, "ISOL Config"); ++ ++	/* SET ISOL CONFIG - AUTHENTICATION */ ++ ++	memset(data, 0, 6); ++	data[0] = 0x00; ++	data[1] = ISOL_AUTHENTICATION_PARAM; ++	data[2] = ISOL_PRIVILEGE_LEVEL_USER | (rsp->data[1] & 0x80); ++	req.msg.cmd = SET_ISOL_CONFIG; ++	req.msg.data_len = 3; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (rsp == NULL) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command"); ++		return -1; ++	} ++	if (rsp->ccode > 0) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config (Authentication) Command: %s", ++			val2str(rsp->ccode, completion_code_vals)); ++		return -1; ++	} ++ ++	/* SET ISOL CONFIG - BAUD RATE */ ++ ++	memset(data, 0, 6); ++	data[0] = 0x00; ++	data[1] = ISOL_BAUD_RATE_PARAM; ++	data[2] = baudsetting; ++	req.msg.cmd = SET_ISOL_CONFIG; ++	req.msg.data_len = 3; ++ ++	rsp = intf->sendrecv(intf, &req); ++	if (rsp == NULL) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command"); ++		return -1; ++	} ++	if (rsp->ccode > 0) { ++		lprintf(LOG_ERR, "Error in Set ISOL Config (Baud Rate) Command: %s", ++			val2str(rsp->ccode, completion_code_vals)); ++		return -1; ++	} ++ ++	printf("Set ISOL Baud Rate to %s\n", ++	       val2str(baudsetting, ipmi_isol_baud_vals)); ++ ++	return 0; ++} ++ ++int ipmi_isol_main(struct ipmi_intf * intf, int argc, char ** argv) ++{ ++	int ret = 0; ++ ++	if (argc < 2 || strncmp(argv[0], "help", 4) == 0) { ++		lprintf(LOG_NOTICE, "ISOL Commands: setup <baud>"); ++		lprintf(LOG_NOTICE, "ISOL Baud Rates:  9600, 19200, 38400, 57600, 115200"); ++		return 0; ++	} ++		 ++	if (strncmp(argv[0], "setup", 5) == 0) { ++		if (strncmp(argv[1], "9600", 4) == 0) { ++			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_9600); ++		} ++		else if (strncmp(argv[1], "19200", 5) == 0) { ++			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_19200); ++		} ++		else if (strncmp(argv[1], "38400", 5) == 0) { ++			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_38400); ++		} ++		else if (strncmp(argv[1], "57600", 5) == 0) { ++			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_57600); ++		} ++		else if (strncmp(argv[1], "115200", 6) == 0) { ++			ret = ipmi_isol_setup(intf, ISOL_BAUD_RATE_115200); ++		} ++		else { ++			lprintf(LOG_ERR, "ISOL - Unsupported baud rate: %s", argv[1]); ++			ret = -1; ++		} ++	} ++	return ret; ++} +diff -urN ipmitool-1.8.9.orig/src/plugins/lan/lan.c ipmitool-1.8.9/src/plugins/lan/lan.c +--- ipmitool-1.8.9.orig/src/plugins/lan/lan.c	2007-02-22 08:38:57.000000000 +0000 ++++ ipmitool-1.8.9/src/plugins/lan/lan.c	2007-12-13 10:16:57.063986495 +0000 +@@ -79,6 +79,11 @@ + static struct ipmi_rs * ipmi_lan_poll_recv(struct ipmi_intf * intf); + static int ipmi_lan_setup(struct ipmi_intf * intf); + static int ipmi_lan_keepalive(struct ipmi_intf * intf); ++static struct ipmi_rs * ipmi_lan_send_payload(struct ipmi_intf * intf, ++ 					      struct ipmi_v2_payload * payload); ++static struct ipmi_rs * ipmi_lan_recv_sol(struct ipmi_intf * intf); ++static struct ipmi_rs * ipmi_lan_send_sol(struct ipmi_intf * intf, ++					  struct ipmi_v2_payload * payload); + static struct ipmi_rs * ipmi_lan_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req); + static int ipmi_lan_send_rsp(struct ipmi_intf * intf, struct ipmi_rs * rsp); + static int ipmi_lan_open(struct ipmi_intf * intf); +@@ -93,6 +98,8 @@ + 	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, + 	target_addr:	IPMI_BMC_SLAVE_ADDR, + }; +@@ -456,80 +463,141 @@ + 		memcpy(&rsp->session.id, rsp->data+x, 4); + 		x += 4; +  +-		if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) +-			x += 16; +- +-		rsp->session.msglen = rsp->data[x++]; +-		rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; +-		rsp->payload.ipmi_response.netfn   = rsp->data[x] >> 2; +-		rsp->payload.ipmi_response.rq_lun  = rsp->data[x++] & 0x3; +-		x++;		/* checksum */ +-		rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; +-		rsp->payload.ipmi_response.rq_seq  = rsp->data[x] >> 2; +-		rsp->payload.ipmi_response.rs_lun  = rsp->data[x++] & 0x3; +-		rsp->payload.ipmi_response.cmd     = rsp->data[x++]; +-		rsp->ccode          = rsp->data[x++]; +- +-		if (verbose > 2) +-			printbuf(rsp->data, rsp->data_len, "ipmi message header"); +- +-		lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); +-		lprintf(LOG_DEBUG+1, "<<   Authtype   : %s", +-		       val2str(rsp->session.authtype, ipmi_authtype_session_vals)); +-		lprintf(LOG_DEBUG+1, "<<   Sequence   : 0x%08lx", +-			(long)rsp->session.seq); +-		lprintf(LOG_DEBUG+1, "<<   Session ID : 0x%08lx", +-			(long)rsp->session.id); +-		lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); +-		lprintf(LOG_DEBUG+1, "<<   Rq Addr    : %02x", +-			rsp->payload.ipmi_response.rq_addr); +-		lprintf(LOG_DEBUG+1, "<<   NetFn      : %02x", +-			rsp->payload.ipmi_response.netfn); +-		lprintf(LOG_DEBUG+1, "<<   Rq LUN     : %01x", +-			rsp->payload.ipmi_response.rq_lun); +-		lprintf(LOG_DEBUG+1, "<<   Rs Addr    : %02x", +-			rsp->payload.ipmi_response.rs_addr); +-		lprintf(LOG_DEBUG+1, "<<   Rq Seq     : %02x", +-			rsp->payload.ipmi_response.rq_seq); +-		lprintf(LOG_DEBUG+1, "<<   Rs Lun     : %01x", +-			rsp->payload.ipmi_response.rs_lun); +-		lprintf(LOG_DEBUG+1, "<<   Command    : %02x", +-			rsp->payload.ipmi_response.cmd); +-		lprintf(LOG_DEBUG+1, "<<   Compl Code : 0x%02x", +-			rsp->ccode); +- +-		/* now see if we have outstanding entry in request list */ +-		entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, +-					      rsp->payload.ipmi_response.cmd); +-		if (entry) { +-			lprintf(LOG_DEBUG+2, "IPMI Request Match found"); +-			if ((intf->target_addr != our_address) && bridge_possible) { +-				if ((rsp->data_len) && +-				    (rsp->payload.ipmi_response.cmd != 0x34)) { +-					printbuf(&rsp->data[x], rsp->data_len-x, +-						 "bridge command response"); +-				} +-				/* bridged command: lose extra header */ +-				if (rsp->payload.ipmi_response.cmd == 0x34) { +-					if (rsp->data_len == 38) { +-						entry->req.msg.cmd = entry->req.msg.target_cmd; +-						rsp = ipmi_lan_recv_packet(intf); +-						continue; ++		if (rsp->session.id == (intf->session->session_id + 0x10000000)) { ++			/* With SOL, authtype is always NONE, so we have no authcode */ ++			rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_SOL; ++	 ++			rsp->session.msglen = rsp->data[x++]; ++			 ++			rsp->payload.sol_packet.packet_sequence_number = ++				rsp->data[x++] & 0x0F; ++ ++			rsp->payload.sol_packet.acked_packet_number = ++				rsp->data[x++] & 0x0F; ++ ++			rsp->payload.sol_packet.accepted_character_count = ++				rsp->data[x++]; ++ ++			rsp->payload.sol_packet.is_nack = ++				rsp->data[x] & 0x40; ++ ++			rsp->payload.sol_packet.transfer_unavailable = ++				rsp->data[x] & 0x20; ++ ++			rsp->payload.sol_packet.sol_inactive =  ++				rsp->data[x] & 0x10; ++ ++			rsp->payload.sol_packet.transmit_overrun = ++				rsp->data[x] & 0x08; ++	 ++			rsp->payload.sol_packet.break_detected = ++				rsp->data[x++] & 0x04; ++ ++			x++; /* On ISOL there's and additional fifth byte before the data starts */ ++	 ++			lprintf(LOG_DEBUG, "SOL sequence number     : 0x%02x", ++				rsp->payload.sol_packet.packet_sequence_number); ++ ++			lprintf(LOG_DEBUG, "SOL acked packet        : 0x%02x", ++				rsp->payload.sol_packet.acked_packet_number); ++			 ++			lprintf(LOG_DEBUG, "SOL accepted char count : 0x%02x", ++				rsp->payload.sol_packet.accepted_character_count); ++			 ++			lprintf(LOG_DEBUG, "SOL is nack             : %s", ++				rsp->payload.sol_packet.is_nack? "true" : "false"); ++			 ++			lprintf(LOG_DEBUG, "SOL xfer unavailable    : %s", ++				rsp->payload.sol_packet.transfer_unavailable? "true" : "false"); ++			 ++			lprintf(LOG_DEBUG, "SOL inactive            : %s", ++				rsp->payload.sol_packet.sol_inactive? "true" : "false"); ++			 ++			lprintf(LOG_DEBUG, "SOL transmit overrun    : %s", ++				rsp->payload.sol_packet.transmit_overrun? "true" : "false"); ++			 ++			lprintf(LOG_DEBUG, "SOL break detected      : %s", ++				rsp->payload.sol_packet.break_detected? "true" : "false"); ++		} ++		else ++		{ ++			/* Standard IPMI 1.5 packet */ ++			rsp->session.payloadtype = IPMI_PAYLOAD_TYPE_IPMI; ++			if (intf->session->active && (rsp->session.authtype || intf->session->authtype)) ++				x += 16; ++ ++			rsp->session.msglen = rsp->data[x++]; ++			rsp->payload.ipmi_response.rq_addr = rsp->data[x++]; ++			rsp->payload.ipmi_response.netfn   = rsp->data[x] >> 2; ++			rsp->payload.ipmi_response.rq_lun  = rsp->data[x++] & 0x3; ++			x++;		/* checksum */ ++			rsp->payload.ipmi_response.rs_addr = rsp->data[x++]; ++			rsp->payload.ipmi_response.rq_seq  = rsp->data[x] >> 2; ++			rsp->payload.ipmi_response.rs_lun  = rsp->data[x++] & 0x3; ++			rsp->payload.ipmi_response.cmd     = rsp->data[x++]; ++			rsp->ccode          = rsp->data[x++]; ++			 ++			if (verbose > 2) ++				printbuf(rsp->data, rsp->data_len, "ipmi message header"); ++			 ++			lprintf(LOG_DEBUG+1, "<< IPMI Response Session Header"); ++			lprintf(LOG_DEBUG+1, "<<   Authtype   : %s", ++				val2str(rsp->session.authtype, ipmi_authtype_session_vals)); ++			lprintf(LOG_DEBUG+1, "<<   Sequence   : 0x%08lx", ++				(long)rsp->session.seq); ++			lprintf(LOG_DEBUG+1, "<<   Session ID : 0x%08lx", ++				(long)rsp->session.id); ++			lprintf(LOG_DEBUG+1, "<< IPMI Response Message Header"); ++			lprintf(LOG_DEBUG+1, "<<   Rq Addr    : %02x", ++				rsp->payload.ipmi_response.rq_addr); ++			lprintf(LOG_DEBUG+1, "<<   NetFn      : %02x", ++				rsp->payload.ipmi_response.netfn); ++			lprintf(LOG_DEBUG+1, "<<   Rq LUN     : %01x", ++				rsp->payload.ipmi_response.rq_lun); ++			lprintf(LOG_DEBUG+1, "<<   Rs Addr    : %02x", ++				rsp->payload.ipmi_response.rs_addr); ++			lprintf(LOG_DEBUG+1, "<<   Rq Seq     : %02x", ++				rsp->payload.ipmi_response.rq_seq); ++			lprintf(LOG_DEBUG+1, "<<   Rs Lun     : %01x", ++				rsp->payload.ipmi_response.rs_lun); ++			lprintf(LOG_DEBUG+1, "<<   Command    : %02x", ++				rsp->payload.ipmi_response.cmd); ++			lprintf(LOG_DEBUG+1, "<<   Compl Code : 0x%02x", ++				rsp->ccode); ++			 ++			/* now see if we have outstanding entry in request list */ ++			entry = ipmi_req_lookup_entry(rsp->payload.ipmi_response.rq_seq, ++						      rsp->payload.ipmi_response.cmd); ++			if (entry) { ++				lprintf(LOG_DEBUG+2, "IPMI Request Match found"); ++				if ((intf->target_addr != our_address) && bridge_possible) { ++					if ((rsp->data_len) && ++					    (rsp->payload.ipmi_response.cmd != 0x34)) { ++						printbuf(&rsp->data[x], rsp->data_len-x, ++							 "bridge command response"); ++					} ++					/* bridged command: lose extra header */ ++					if (rsp->payload.ipmi_response.cmd == 0x34) { ++						if (rsp->data_len == 38) { ++							entry->req.msg.cmd = entry->req.msg.target_cmd; ++							rsp = ipmi_lan_recv_packet(intf); ++							continue; ++						} ++					} else { ++						//x += sizeof(rsp->payload.ipmi_response); ++						if (rsp->data[x-1] != 0) ++							lprintf(LOG_DEBUG, "WARNING: Bridged " ++								"cmd ccode = 0x%02x", ++								rsp->data[x-1]); + 					} +-				} else { +-					//x += sizeof(rsp->payload.ipmi_response); +-					if (rsp->data[x-1] != 0) +-						lprintf(LOG_DEBUG, "WARNING: Bridged " +-							"cmd ccode = 0x%02x", +-						       rsp->data[x-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; + 			} +-			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; + 		} +  + 		break; +@@ -537,7 +605,9 @@ +  + 	/* shift response data to start of array */ + 	if (rsp && rsp->data_len > x) { +-		rsp->data_len -= x + 1; ++		rsp->data_len -= x; ++		if (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_IPMI) ++			rsp->data_len -= 1; /* We don't want the checksum */ + 		memmove(rsp->data, rsp->data + x, rsp->data_len); + 		memset(rsp->data + rsp->data_len, 0, IPMI_BUF_SIZE - rsp->data_len); + 	} +@@ -553,9 +623,9 @@ +  * |  rmcp.seq          | +  * |  rmcp.class        | +  * +--------------------+ +- * |  session.authtype | 9 bytes +- * |  session.seq   | +- * |  session.id    | ++ * |  session.authtype  | 9 bytes ++ * |  session.seq       | ++ * |  session.id        | +  * +--------------------+ +  * | [session.authcode] | 16 bytes (AUTHTYPE != none) +  * +--------------------+ +@@ -910,6 +980,430 @@ + 	return 0; + } +  ++/* ++ * IPMI SOL Payload Format ++ * +--------------------+ ++ * |  rmcp.ver          | 4 bytes ++ * |  rmcp.__reserved   | ++ * |  rmcp.seq          | ++ * |  rmcp.class        | ++ * +--------------------+ ++ * |  session.authtype  | 9 bytes ++ * |  session.seq       | ++ * |  session.id        | ++ * +--------------------+ ++ * |  message length    | 1 byte ++ * +--------------------+ ++ * |  sol.seq           | 5 bytes ++ * |  sol.ack_seq       | ++ * |  sol.acc_count     | ++ * |  sol.control       | ++ * |  sol.__reserved    | ++ * +--------------------+ ++ * | [request data]     | data_len bytes ++ * +--------------------+ ++ */ ++uint8_t * ipmi_lan_build_sol_msg(struct ipmi_intf * intf, ++				 struct ipmi_v2_payload * payload, ++				 int * llen) ++{ ++	struct rmcp_hdr rmcp = { ++		.ver		= RMCP_VERSION_1, ++		.class		= RMCP_CLASS_IPMI, ++		.seq		= 0xff, ++	}; ++	struct ipmi_session * session = intf->session; ++ ++	/* msg will hold the entire message to be sent */ ++	uint8_t * msg; ++ ++	int len = 0; ++ ++	len =	sizeof(rmcp)                                 +  // RMCP Header (4) ++		10                                           +  // IPMI Session Header ++		5                                            +  // SOL header ++		payload->payload.sol_packet.character_count;    // The actual payload ++ ++	msg = malloc(len); ++	if (msg == NULL) { ++		lprintf(LOG_ERR, "ipmitool: malloc failure"); ++		return; ++	} ++	memset(msg, 0, len); ++ ++	/* rmcp header */ ++	memcpy(msg, &rmcp, sizeof(rmcp)); ++	len = sizeof(rmcp); ++ ++	/* ipmi session header */ ++	msg[len++] = 0; /* SOL is always authtype = NONE */ ++	msg[len++] = session->in_seq & 0xff; ++	msg[len++] = (session->in_seq >> 8) & 0xff; ++	msg[len++] = (session->in_seq >> 16) & 0xff; ++	msg[len++] = (session->in_seq >> 24) & 0xff; ++ ++	msg[len++] = session->session_id & 0xff; ++	msg[len++] = (session->session_id >> 8) & 0xff; ++	msg[len++] = (session->session_id >> 16) & 0xff; ++	msg[len++] = ((session->session_id >> 24) + 0x10) & 0xff; /* Add 0x10 to MSB for SOL */ ++ ++	msg[len++] = payload->payload.sol_packet.character_count + 5; ++	 ++	/* sol header */ ++	msg[len++] = payload->payload.sol_packet.packet_sequence_number; ++	msg[len++] = payload->payload.sol_packet.acked_packet_number; ++	msg[len++] = payload->payload.sol_packet.accepted_character_count; ++	msg[len]    = payload->payload.sol_packet.is_nack           ? 0x40 : 0; ++	msg[len]   |= payload->payload.sol_packet.assert_ring_wor   ? 0x20 : 0; ++	msg[len]   |= payload->payload.sol_packet.generate_break    ? 0x10 : 0; ++	msg[len]   |= payload->payload.sol_packet.deassert_cts      ? 0x08 : 0; ++	msg[len]   |= payload->payload.sol_packet.deassert_dcd_dsr  ? 0x04 : 0; ++	msg[len]   |= payload->payload.sol_packet.flush_inbound     ? 0x02 : 0; ++	msg[len++] |= payload->payload.sol_packet.flush_outbound    ? 0x01 : 0; ++ ++	len++; /* On SOL there's and additional fifth byte before the data starts */ ++ ++	if (payload->payload.sol_packet.character_count) { ++		/* We may have data to add */ ++		memcpy(msg + len, ++		       payload->payload.sol_packet.data, ++		       payload->payload.sol_packet.character_count); ++		len += payload->payload.sol_packet.character_count;		 ++	} ++ ++	session->in_seq++; ++	if (session->in_seq == 0) ++		session->in_seq++; ++	 ++	*llen = len; ++	return msg; ++} ++ ++/* ++ * is_sol_packet ++ */ ++static int ++is_sol_packet(struct ipmi_rs * rsp) ++{ ++	return (rsp                                                           && ++		(rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)); ++} ++ ++ ++ ++/* ++ * sol_response_acks_packet ++ */ ++static int ++sol_response_acks_packet(struct ipmi_rs         * rsp, ++			 struct ipmi_v2_payload * payload) ++{ ++	return (is_sol_packet(rsp)                                            && ++		payload                                                       && ++		(payload->payload_type    == IPMI_PAYLOAD_TYPE_SOL)           &&  ++		(rsp->payload.sol_packet.acked_packet_number == ++		 payload->payload.sol_packet.packet_sequence_number)); ++} ++ ++/* ++ * ipmi_lan_send_sol_payload ++ * ++ */ ++static struct ipmi_rs * ++ipmi_lan_send_sol_payload(struct ipmi_intf * intf, ++			  struct ipmi_v2_payload * payload) ++{ ++	struct ipmi_rs      * rsp = NULL; ++	uint8_t             * msg; ++	int                   len; ++	int                   try = 0; ++ ++	if (intf->opened == 0 && intf->open != NULL) { ++		if (intf->open(intf) < 0) ++			return NULL; ++	} ++ ++	msg = ipmi_lan_build_sol_msg(intf, payload, &len); ++	if (len <= 0 || msg == NULL) { ++		lprintf(LOG_ERR, "Invalid SOL payload packet"); ++		if (msg != NULL) ++			free(msg); ++		return NULL; ++	} ++ ++	lprintf(LOG_DEBUG, ">> SENDING A SOL MESSAGE\n"); ++ ++	for (;;) { ++		if (ipmi_lan_send_packet(intf, msg, len) < 0) { ++			try++; ++			usleep(5000); ++			continue; ++		} ++ ++		/* if we are set to noanswer we do not expect response */ ++		if (intf->noanswer) ++			break; ++		 ++		if (payload->payload.sol_packet.packet_sequence_number == 0) { ++			/* We're just sending an ACK.  No need to retry. */ ++			break; ++		} ++ ++		usleep(100); ++		 ++		rsp = ipmi_lan_recv_sol(intf); /* Grab the next packet */ ++ ++		if (sol_response_acks_packet(rsp, payload)) ++			break; ++ ++		else if (is_sol_packet(rsp) && rsp->data_len) ++		{ ++			/* ++			 * We're still waiting for our ACK, but we more data from ++			 * the BMC ++			 */ ++			intf->session->sol_data.sol_input_handler(rsp); ++		} ++ ++		usleep(5000); ++		if (++try >= intf->session->retry) { ++			lprintf(LOG_DEBUG, "  No response from remote controller"); ++			break; ++		} ++	} ++ ++	return rsp; ++} ++ ++/* ++ * is_sol_partial_ack ++ * ++ * Determine if the response is a partial ACK/NACK that indicates ++ * we need to resend part of our packet. ++ * ++ * returns the number of characters we need to resend, or ++ *         0 if this isn't an ACK or we don't need to resend anything ++ */ ++static int is_sol_partial_ack(struct ipmi_v2_payload * v2_payload, ++			      struct ipmi_rs         * rsp) ++{ ++	int chars_to_resend = 0; ++ ++	if (v2_payload                                && ++	    rsp                                       && ++	    is_sol_packet(rsp)                        && ++	    sol_response_acks_packet(rsp, v2_payload) && ++	    (rsp->payload.sol_packet.accepted_character_count < ++	     v2_payload->payload.sol_packet.character_count)) ++	{ ++		if (rsp->payload.sol_packet.accepted_character_count == 0) { ++			/* We should not resend data */ ++			chars_to_resend = 0; ++		} ++		else ++		{ ++			chars_to_resend = ++				v2_payload->payload.sol_packet.character_count - ++				rsp->payload.sol_packet.accepted_character_count; ++		} ++	} ++ ++	return chars_to_resend; ++} ++ ++/* ++ * set_sol_packet_sequence_number ++ */ ++static void set_sol_packet_sequence_number(struct ipmi_intf * intf, ++					   struct ipmi_v2_payload * v2_payload) ++{ ++	/* Keep our sequence number sane */ ++	if (intf->session->sol_data.sequence_number > 0x0F) ++		intf->session->sol_data.sequence_number = 1; ++ ++	v2_payload->payload.sol_packet.packet_sequence_number = ++		intf->session->sol_data.sequence_number++; ++} ++ ++/* ++ * ipmi_lan_send_sol ++ * ++ * Sends a SOL packet..  We handle partial ACK/NACKs from the BMC here. ++ * ++ * Returns a pointer to the SOL ACK we received, or ++ *         0 on failure ++ *  ++ */ ++struct ipmi_rs * ++ipmi_lan_send_sol(struct ipmi_intf * intf, ++		  struct ipmi_v2_payload * v2_payload) ++{ ++	struct ipmi_rs * rsp; ++	int chars_to_resend = 0; ++ ++	v2_payload->payload_type   = IPMI_PAYLOAD_TYPE_SOL; ++ ++	/* ++	 * Payload length is just the length of the character ++	 * data here. ++	 */ ++	v2_payload->payload.sol_packet.acked_packet_number = 0; /* NA */ ++ ++	set_sol_packet_sequence_number(intf, v2_payload); ++	 ++	v2_payload->payload.sol_packet.accepted_character_count = 0; /* NA */ ++ ++	rsp = ipmi_lan_send_sol_payload(intf, v2_payload); ++ ++	/* Determine if we need to resend some of our data */ ++	chars_to_resend = is_sol_partial_ack(v2_payload, rsp); ++ ++	while (chars_to_resend) ++	{ ++		/* ++		 * We first need to handle any new data we might have ++		 * received in our NACK ++		 */ ++		if (rsp->data_len) ++			intf->session->sol_data.sol_input_handler(rsp); ++ ++		set_sol_packet_sequence_number(intf, v2_payload); ++		 ++		/* Just send the required data */ ++		memmove(v2_payload->payload.sol_packet.data, ++			v2_payload->payload.sol_packet.data + ++			rsp->payload.sol_packet.accepted_character_count, ++			chars_to_resend); ++ ++		v2_payload->payload.sol_packet.character_count = chars_to_resend; ++ ++		rsp = ipmi_lan_send_sol_payload(intf, v2_payload); ++ ++		chars_to_resend = is_sol_partial_ack(v2_payload, rsp); ++	} ++ ++	return rsp; ++} ++ ++/* ++ * check_sol_packet_for_new_data ++ * ++ * Determine whether the SOL packet has already been seen ++ * and whether the packet has new data for us. ++ * ++ * This function has the side effect of removing an previously ++ * seen data, and moving new data to the front. ++ * ++ * It also "Remembers" the data so we don't get repeats. ++ * ++ */ ++static int ++check_sol_packet_for_new_data(struct ipmi_intf * intf, ++			      struct ipmi_rs *rsp) ++{ ++	static uint8_t last_received_sequence_number = 0; ++	static uint8_t last_received_byte_count      = 0; ++	int new_data_size                            = 0; ++ ++	if (rsp && ++	    (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL)) ++	     ++	{ ++		uint8_t unaltered_data_len = rsp->data_len; ++		if (rsp->payload.sol_packet.packet_sequence_number == ++		    last_received_sequence_number) ++		{ ++			/* ++			 * This is the same as the last packet, but may include ++			 * extra data ++			 */ ++			new_data_size = rsp->data_len - last_received_byte_count; ++			 ++			if (new_data_size > 0) ++			{ ++				/* We have more data to process */ ++				memmove(rsp->data, ++					rsp->data + ++					rsp->data_len - new_data_size, ++					new_data_size); ++			} ++			 ++			rsp->data_len = new_data_size; ++		} ++	 ++		/* ++		 *Rember the data for next round ++		 */ ++		if (rsp && rsp->payload.sol_packet.packet_sequence_number) ++		{ ++			last_received_sequence_number = ++				rsp->payload.sol_packet.packet_sequence_number; ++			last_received_byte_count = unaltered_data_len; ++		} ++	} ++ ++	return new_data_size; ++} ++ ++/* ++ * ack_sol_packet ++ * ++ * Provided the specified packet looks reasonable, ACK it. ++ */ ++static void ++ack_sol_packet(struct ipmi_intf * intf, ++	       struct ipmi_rs * rsp) ++{ ++	if (rsp && ++	    (rsp->session.payloadtype == IPMI_PAYLOAD_TYPE_SOL) && ++	    (rsp->payload.sol_packet.packet_sequence_number)) ++	{ ++		struct ipmi_v2_payload ack; ++ ++		memset(&ack, 0, sizeof(struct ipmi_v2_payload)); ++ ++		ack.payload_type = IPMI_PAYLOAD_TYPE_SOL; ++ ++		/* ++		 * Payload length is just the length of the character ++		 * data here. ++		 */ ++		ack.payload_length = 0; ++ ++		/* ACK packets have sequence numbers of 0 */ ++		ack.payload.sol_packet.packet_sequence_number = 0; ++ ++		ack.payload.sol_packet.acked_packet_number = ++			rsp->payload.sol_packet.packet_sequence_number; ++ ++		ack.payload.sol_packet.accepted_character_count = rsp->data_len; ++		 ++		ipmi_lan_send_sol_payload(intf, &ack); ++	} ++} ++ ++/* ++ * ipmi_recv_sol ++ * ++ * Receive a SOL packet and send an ACK in response. ++ * ++ */ ++struct ipmi_rs * ++ipmi_lan_recv_sol(struct ipmi_intf * intf) ++{ ++	struct ipmi_rs * rsp = ipmi_lan_poll_recv(intf); ++ ++	ack_sol_packet(intf, rsp);               ++ ++	/* ++	 * Remembers the data sent, and alters the data to just ++	 * include the new stuff. ++	 */ ++	check_sol_packet_for_new_data(intf, rsp); ++ ++	return rsp; ++} ++ + /* send a get device id command to keep session active */ + static int + ipmi_lan_keepalive(struct ipmi_intf * intf) +@@ -1411,6 +1905,8 @@ +  + 	intf->abort = 1; +  ++	intf->session->sol_data.sequence_number = 1; ++	 + 	/* open port to BMC */ + 	memset(&s->addr, 0, sizeof(struct sockaddr_in)); + 	s->addr.sin_family = AF_INET; diff --git a/debian/rules b/debian/rules index 582b3c1..5d96d9c 100755 --- a/debian/rules +++ b/debian/rules @@ -1,7 +1,6 @@  #!/usr/bin/make -f  #export DH_VERBOSE=1 -export DH_COMPAT=4  export DH_OPTIONS  CFLAGS = -Wall -g @@ -28,8 +27,8 @@ build: build-arch build-indep  build-arch: build-arch-stamp  build-arch-stamp: configure-stamp  - -# Add here commands to compile the arch part of the package. +	 +	# Add here commands to compile the arch part of the package.  	$(MAKE)  	touch build-arch-stamp @@ -37,17 +36,17 @@ build-indep: build-indep-stamp  build-indep-stamp: configure-stamp   	touch build-indep-stamp -# Add here commands to compile the indep part of the package. -#$(MAKE) doc +	# Add here commands to compile the indep part of the package. +	#$(MAKE) doc  clean: unpatch  	dh_testdir  	dh_testroot  	rm -f build-arch-stamp build-indep-stamp configure-stamp - -# Add here commands to clean up after the build process. -	-$(MAKE) distclean - +	 +	# Add here commands to clean up after the build process. +	if [ -f Makefile ]; then $(MAKE) distclean; fi +	  	dh_clean  install: install-arch #install-indep @@ -57,34 +56,33 @@ install-indep:  	dh_clean -k -i  	dh_installdirs -i -# Add here commands to install the indep part of the package into -# debian/<package>-doc. -#INSTALLDOC# -#	$(MAKE) install-doc DESTDIR=$(CURDIR)/debian/tmp/ipmitool-doc -#	dh_movefiles -i +	# Add here commands to install the indep part of the package into +	# debian/<package>-doc. +	#INSTALLDOC# +	#	$(MAKE) install-doc DESTDIR=$(CURDIR)/debian/tmp/ipmitool-doc +	#	dh_movefiles -i  install-arch:  	dh_testdir  	dh_testroot  	dh_clean -k -a  	dh_installdirs -a - -# Add here commands to install the arch part of the package into  -# debian/tmp. +	 +	# Add here commands to install the arch part of the package into  +	# debian/tmp.  	$(MAKE) install DESTDIR=$(CURDIR)/debian/ipmitool - +	  	# No need to have two copies of the license text in the package.  	$(RM) $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/COPYING - +	  	# Move upstream changelog to correct filename. -	mv $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/ChangeLog \ -	  $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog +	#mv $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/ChangeLog \ +	#  $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog  	# Compress to avoid lintian warning.  Not sure why dh_compress  	# isn't fixing this. -	gzip -9 $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog +	#gzip -9 $(CURDIR)/debian/ipmitool/usr/share/doc/ipmitool/changelog -#	dh_movefiles -a  # Must not depend on anything. This is to be called by  # binary-arch/binary-multi  # in another 'make' thread. @@ -92,7 +90,7 @@ binary-common:  	dh_testdir  	dh_testroot  	dh_installdocs -	dh_installchangelogs  +	dh_installchangelogs ChangeLog  	dh_installinit --name ipmievd --error-handler=ipmievd_initd_failed  	dh_link  	dh_strip diff --git a/debian/watch b/debian/watch new file mode 100644 index 0000000..d6990ab --- /dev/null +++ b/debian/watch @@ -0,0 +1,3 @@ +version=3 +opts=uversionmangle=s/\.(tar.*|tgz|zip|gz|bz2)$// \ +http://sf.net/ipmitool/ipmitool-?_?([\d+\.]+|\d+)\.(tar.*|tgz|zip|gz|bz2) debian uupdate | 
