--- ipmitool-1.8.9.orig/debian/changelog
+++ ipmitool-1.8.9/debian/changelog
@@ -1,3 +1,63 @@
+ipmitool (1.8.9-1~bpo40+1) etch-backports; urgency=low
+
+  * Rebuild for etch.
+
+ -- Norbert Tretkowski <nobse@debian.org>  Thu, 11 Sep 2008 10:51:16 +0200
+
+ipmitool (1.8.9-1) unstable; urgency=low
+
+  * Adopt package (Closes: #432027)
+  * New upstream release
+    - 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 
+  * Bump to dephelper v5
+
+ -- Matthew Johnson <mjj29@debian.org>  Thu, 13 Dec 2007 10:25:22 +0000
+
+ipmitool (1.8.8-3.1) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * High urgency for RC bug fix.
+  * Fix build with linux-libc-dev (closes: #428929).
+  * Fix debian/rules to not rerun configure in the binary target.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri, 20 Jul 2007 16:29:18 +0200
+
+ipmitool (1.8.8-3) unstable; urgency=low
+
+  * Ported fix to ipmievd from upstream version 1.8.9 (Closes: #408536):
+    - fix ipmievd fd closing bug.  Patch from Rupert Hair.
+  * Started using dpatch to apply patches.  Added dpatch to build dependencies.
+  * Add powerpc to the list of supported archs (Closes: #405455)
+
+ -- Petter Reinholdtsen <pere@debian.org>  Tue, 03 Apr 2007 16:37:45 +0200
+
+ipmitool (1.8.8-2) unstable; urgency=low
+
+  * Add handler for the ipmievd init.d script failure during removal and
+    installation.  If it fail during installation, update
+    /etc/default/ipmievd to disable ipmievd.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Sun,  1 Oct 2006 11:21:44 +0200
+
+ipmitool (1.8.8-1) unstable; urgency=low
+
+  * New upstream release.
+    - Daemon now tries to access device before it forks, and thus will
+      report errors to the init.d script if it fail. (Closes: #362425)
+  * Make it possible to disable ipmievd by setting ENABLED=false in
+    /etc/defaults/ipmievd. (Closes: #370511)
+  * Add --oknodo as start-stop-daemon argument when stopping ipmievd,
+    to avoid returning an error if it is not running. (Closes: #370509)
+  * Update standards-version from 3.6.2.1 to 3.7.2.  No changes needed.
+  * Correct dependency and runlevel info in init.d script.
+
+ -- Petter Reinholdtsen <pere@debian.org>  Fri, 29 Sep 2006 19:16:41 +0200
+
 ipmitool (1.8.7-2) unstable; urgency=low
 
   * Fix typo in init.d/ipmievd. (Closes: #361309)
@@ -104,14 +164,14 @@
   * Fix chassis boot parameter support
   * Add support for linear sensors
 
- -- Duncan Laurie <duncan@iceblink.org>  Wed, Mar 16 2005 17:08:12 -0700
+ -- Duncan Laurie <duncan@iceblink.org>  Wed, 16 Mar 2005 17:08:12 -0700
 
 ipmitool (1.7.1) unstable; urgency=low
 
   * Update bmc plugin to work with new Solaris bmc driver (new ioctl
     for interface detection and new STREAMS message-based interface).
 
- -- Seth Goldberg <sethmeisterg@hotmail.com>  Mon, Mar 7 2005 18:03:00 -0800
+ -- Seth Goldberg <sethmeisterg@hotmail.com>  Mon,  7 Mar 2005 18:03:00 -0800
 
 ipmitool (1.7.0) unstable; urgency=low
 
@@ -127,7 +187,7 @@
   * New "bmc" plugin for Solaris 10 x86
   * Many bugfixes and contributed patches
 
- -- Duncan Laurie <duncan@iceblink.org>  Fri, Jan 7 2005 19:58:22 -0700
+ -- Duncan Laurie <duncan@iceblink.org>  Fri,  7 Jan 2005 19:58:22 -0700
 
 ipmitool (1.6.2) unstable; urgency=low
 
@@ -170,7 +230,7 @@
   * Add configure option for changing binary to ipmiadm for Solaris
   * Fix compile problem on Solaris 8
 
- -- Duncan Laurie <duncan@iceblink.org>  Sat, 27 Mar 2004 00:11:37 -0700
+ -- Duncan Laurie <duncan@sun.com>  Sat, 27 Mar 2004 00:11:37 -0700
 
 ipmitool (1.5.8) unstable; urgency=low
 
@@ -184,7 +244,7 @@
   * Add support for Linux kernel panic messages in SEL output
   * Add support for type 3 SDR records
 
- -- Duncan Laurie <duncan@iceblink.org>  Tue, 27 Jan 2004 16:23:25 -0700
+ -- Duncan Laurie <duncan@sun.com>  Tue, 27 Jan 2004 16:23:25 -0700
 
 ipmitool (1.5.7) unstable; urgency=low
 
@@ -193,7 +253,7 @@
   * better handling of SDR printing
   * contrib scripts for creating rrdtool graphs
 
- -- Duncan Laurie <duncan@iceblink.org>  Mon,  5 Jan 2004 17:29:50 -0700
+ -- Duncan Laurie <duncan@sun.com>  Mon,  5 Jan 2004 17:29:50 -0700
 
 ipmitool (1.5.6) unstable; urgency=low
 
@@ -202,40 +262,40 @@
   * Fix sdr handling of sensors that do not return a reading
   * Fix for CSV display of sensor readings/units from Fredrik Öhrn
 
- -- Duncan Laurie <duncan@iceblink.org>  Thu,  4 Dec 2003 14:47:19 -0700
+ -- Duncan Laurie <duncan@sun.com>  Thu,  4 Dec 2003 14:47:19 -0700
 
 ipmitool (1.5.5) unstable; urgency=low
 
   * Add -U option for setting LAN username
   * Fix -v usage for plugin interfaces
 
- -- Duncan Laurie <duncan@iceblink.org>  Tue, 25 Nov 2003 15:10:48 -0700
+ -- Duncan Laurie <duncan@sun.com>  Tue, 25 Nov 2003 15:10:48 -0700
 
 ipmitool (1.5.4) unstable; urgency=low
 
   * Put interface plugin API into library
   * Fix ipmievd
 
- -- Duncan Laurie <duncan@iceblink.org>  Fri, 14 Nov 2003 15:16:34 -0700
+ -- Duncan Laurie <duncan@sun.com>  Fri, 14 Nov 2003 15:16:34 -0700
 
 ipmitool (1.5.3) unstable; urgency=low
 
   * Add -g option to work with grizzly bmc
 
- -- Duncan Laurie <duncan@iceblink.org>  Mon,  3 Nov 2003 18:04:07 -0700
+ -- Duncan Laurie <duncan@sun.com>  Mon,  3 Nov 2003 18:04:07 -0700
 
 ipmitool (1.5.2) unstable; urgency=low
 
   * add support for setting gratuitous arp interval 
 
- -- Duncan Laurie <duncan@iceblink.org>  Fri, 24 Oct 2003 11:00:00 -0700
+ -- Duncan Laurie <duncan@sun.com>  Fri, 24 Oct 2003 11:00:00 -0700
 
 ipmitool (1.5.1) unstable; urgency=low
 
   * better SEL support
   * fix display bug in SDR list
 
- -- Duncan Laurie <duncan@iceblink.org>  Wed,  8 Oct 2003 17:28:51 -0700
+ -- Duncan Laurie <duncan@sun.com>  Wed,  8 Oct 2003 17:28:51 -0700
 
 ipmitool (1.5.0) unstable; urgency=low
 
@@ -243,24 +303,24 @@
   * add Intel IMB driver support
   * use autoconf/automake/libtool
 
- -- Duncan Laurie <duncan@iceblink.org>  Fri,  5 Sep 2003 11:57:32 -0700
+ -- Duncan Laurie <duncan@sun.com>  Fri,  5 Sep 2003 11:57:32 -0700
 
 ipmitool (1.2-1) unstable; urgency=low
 
   * New command line option parsing
   * More chassis commands supported
 
- -- Duncan Laurie <duncan@iceblink.org>  Wed,  2 Apr 2003 17:44:17 -0700
+ -- Duncan Laurie <duncan@sun.com>  Wed,  2 Apr 2003 17:44:17 -0700
 
 ipmitool (1.1-1) unstable; urgency=low
 
   * Minor fixes.
 
- -- Duncan Laurie <duncan@iceblink.org>  Tue,  1 Apr 2003 14:31:10 -0700
+ -- Duncan Laurie <duncan@sun.com>  Tue,  1 Apr 2003 14:31:10 -0700
 
 ipmitool (1.0-1) unstable; urgency=low
 
   * Initial Release.
 
- -- Duncan Laurie <duncan@iceblink.org>  Sun, 30 Mar 2003 21:30:46 -0700
+ -- Duncan Laurie <duncan@sun.com>  Sun, 30 Mar 2003 21:30:46 -0700
 
--- ipmitool-1.8.9.orig/debian/control
+++ ipmitool-1.8.9/debian/control
@@ -1,13 +1,13 @@
 Source: ipmitool
 Section: utils
 Priority: optional
-Maintainer: Petter Reinholdtsen <pere@debian.org>
-Uploaders: Duncan Laurie <duncan@iceblink.org>
-Build-Depends: debhelper (>> 4.0.0), libreadline5-dev | libreadline-dev, libssl-dev
-Standards-Version: 3.6.2.1
+Maintainer: Matthew Johnson <mjj29@debian.org>
+Uploaders:
+Build-Depends: debhelper (>> 5.0.0), libreadline5-dev | libreadline-dev, libssl-dev, dpatch
+Standards-Version: 3.7.2
 
 Package: ipmitool
-Architecture: i386 amd64 ia64
+Architecture: i386 amd64 ia64 powerpc
 Depends: ${shlibs:Depends}, lsb-base
 Suggests: openipmi
 Description: utility for IPMI control with kernel driver or LAN interface
--- ipmitool-1.8.9.orig/debian/rules
+++ ipmitool-1.8.9/debian/rules
@@ -1,7 +1,6 @@
 #!/usr/bin/make -f
 
 #export DH_VERBOSE=1
-export DH_COMPAT=4
 export DH_OPTIONS
 
 CFLAGS = -Wall -g
@@ -16,7 +15,7 @@
 endif
 
 configure: configure-stamp
-configure-stamp:
+configure-stamp: patch-stamp
 	dh_testdir
 	./configure --prefix=/usr \
 		    --with-kerneldir \
@@ -28,24 +27,26 @@
 
 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
 
 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:
+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
@@ -55,34 +56,33 @@
 	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.
@@ -90,8 +90,8 @@
 	dh_testdir
 	dh_testroot
 	dh_installdocs
-	dh_installchangelogs 
-	dh_installinit --name ipmievd
+	dh_installchangelogs ChangeLog
+	dh_installinit --name ipmievd --error-handler=ipmievd_initd_failed
 	dh_link
 	dh_strip
 	dh_compress 
@@ -111,5 +111,6 @@
 	$(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
 
 binary: binary-arch #binary-indep
-.PHONY: build clean binary-indep binary-arch binary install install-indep install-arch configure
+.PHONY: build build-arch build-indep clean binary-indep binary-arch binary install install-indep install-arch configure
 
+include /usr/share/dpatch/dpatch.make
--- ipmitool-1.8.9.orig/debian/compat
+++ ipmitool-1.8.9/debian/compat
@@ -0,0 +1 @@
+5
--- ipmitool-1.8.9.orig/debian/ipmitool.ipmievd.init
+++ ipmitool-1.8.9/debian/ipmitool.ipmievd.init
@@ -0,0 +1,102 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides:          ipmievd
+# Required-Start:    $remote_fs $syslog
+# Required-Stop:     $remote_fs $syslog
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: IPMI event daemon
+# Description:       ipmievd  is a daemon which will listen for events
+#                    from the BMC that are being sent to the SEL and
+#                    also log those messages to syslog.
+### END INIT INFO
+#
+# Author:	Elmar Hoffmann <elho@elho.net>
+# Licence:      This script is public domain using the same
+#               licence as ipmitool itself.
+# Modified by:  Petter Reinholdtsen
+
+set -e
+
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DESC="IPMI event daemon"
+NAME=ipmievd
+DAEMON=/usr/sbin/$NAME
+PIDFILE=/var/run/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+ENABLED=true
+
+# Gracefully exit if the package has been removed.
+test -x $DAEMON || exit 0
+
+. /lib/lsb/init-functions
+. /etc/default/rcS
+
+# Options used by ipmievd.
+#
+# "open" uses the asynchronous event notification from the OpenIPMI
+# kernel driver, "sel" uses active polling of the contents of the SEL
+# for new events.
+#
+# Need to force 'daemon' mode, to make sure messages are sent to
+# syslog and the program forks into the background.
+#
+# Se ipmievd(8) for more info.
+IPMIEVD_OPTIONS="open daemon"
+
+# Read config file if it is present.
+[ -f /etc/default/$NAME ] && . /etc/default/$NAME
+
+test "$ENABLED" != "false" || exit 0
+
+# Backwards compatibility with version 1.8.6-2 and 1.8.6-1.  The
+# variable was renamed to be compatible with upstream, SuSe and RedHat.
+if [ -n "$IPMIEVD_OPTS" ]; then
+    echo "warning: /etc/default/$NAME variable IPMIEVD_OPTS should be renamed to IPMIEVD_OPTIONS"
+    IPMIEVD_OPTIONS="$IPMIEVD_OPTS"
+fi
+
+#
+#	Function that starts the daemon/service.
+#
+d_start() {
+	start-stop-daemon --start --quiet --exec $DAEMON --pidfile $PIDFILE -- $IPMIEVD_OPTIONS
+}
+
+#
+#	Function that stops the daemon/service.
+#
+d_stop() {
+	start-stop-daemon --stop --oknodo --quiet --name $NAME --exec $DAEMON --pidfile $PIDFILE 
+}
+
+CODE=0
+
+case "$1" in
+  start)
+	[ "$VERBOSE" != no ] && log_begin_msg "Starting $DESC" "$NAME"
+	d_start || CODE=$?
+	[ "$VERBOSE" != no ] && log_end_msg $CODE
+	exit $CODE
+	;;
+  stop)
+	log_begin_msg "Stopping $DESC" "$NAME"
+	d_stop || CODE=$?
+	log_end_msg $CODE
+	exit $CODE
+	;;
+  restart|force-reload)
+	log_begin_msg "Restarting $DESC" "$NAME"
+	d_stop || true
+	sleep 1
+	d_start || CODE=$?
+	log_end_msg $CODE
+	exit $CODE
+	;;
+  *)
+	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
+	exit 1
+	;;
+esac
+
+exit 0
--- ipmitool-1.8.9.orig/debian/ipmitool.postinst
+++ ipmitool-1.8.9/debian/ipmitool.postinst
@@ -0,0 +1,14 @@
+#!/bin/sh
+
+ipmievd_initd_failed() {
+	echo "Unable to start ipmievd during installation.  Trying to disable."
+	if [ -f /etc/default/ipmievd ] && \
+           grep -q ^ENABLED=false /etc/default/ipmievd ; then
+	    :
+	else
+	    touch /etc/default/ipmievd
+	    echo "ENABLED=false" >> /etc/default/ipmievd
+	fi
+}
+
+#DEBHELPER#
--- ipmitool-1.8.9.orig/debian/ipmitool.postrm
+++ ipmitool-1.8.9/debian/ipmitool.postrm
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+ipmievd_initd_failed() {
+    :
+}
+
+#DEBHELPER#
--- ipmitool-1.8.9.orig/debian/ipmitool.prerm
+++ ipmitool-1.8.9/debian/ipmitool.prerm
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+ipmievd_initd_failed() {
+    :
+}
+
+#DEBHELPER#
--- ipmitool-1.8.9.orig/debian/patches/00list
+++ ipmitool-1.8.9/debian/patches/00list
@@ -0,0 +1,3 @@
+10_ipmi_lanp.dpatch
+20_ipmi_isol.dpatch
+20_ipmi_impi.dpatch
--- ipmitool-1.8.9.orig/debian/patches/10_ipmi_lanp.dpatch
+++ ipmitool-1.8.9/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) {
--- ipmitool-1.8.9.orig/debian/patches/20_ipmi_impi.dpatch
+++ ipmitool-1.8.9/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");
--- ipmitool-1.8.9.orig/debian/patches/20_ipmi_isol.dpatch
+++ ipmitool-1.8.9/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, &params))
++		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, &params))
++		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, &params))
++		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;
--- ipmitool-1.8.9.orig/debian/watch
+++ ipmitool-1.8.9/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
