diff -urN ipmitool-1.6.0/configure.in ipmitool-1.6.0-tyan/configure.in
--- ipmitool-1.6.0/configure.in	2004-09-10 22:10:29.000000000 +0200
+++ ipmitool-1.6.0-tyan/configure.in	2004-12-23 19:26:34.000000000 +0100
@@ -1,11 +1,10 @@
 dnl
 dnl autoconf for ipmitool
 dnl
-AC_INIT([src/ipmitool.c])
+AC_INIT([ipmitool], [1.6.0])
 AC_CANONICAL_SYSTEM
-AM_INIT_AUTOMAKE([ipmitool], [1.6.0])
+AM_INIT_AUTOMAKE([foreign])
 AM_CONFIG_HEADER(config.h)
-AC_CONFIG_SRCDIR([src/ipmitool.c])
 AC_PREREQ(2.50)
 AC_SUBST(ac_configure_args)
 
diff -urN ipmitool-1.6.0/include/ipmitool/ipmi.h ipmitool-1.6.0-tyan/include/ipmitool/ipmi.h
--- ipmitool-1.6.0/include/ipmitool/ipmi.h	2004-09-10 22:11:59.000000000 +0200
+++ ipmitool-1.6.0-tyan/include/ipmitool/ipmi.h	2004-12-23 19:24:39.000000000 +0100
@@ -238,6 +238,7 @@
 #define IPMI_NETFN_STORAGE		0xa
 #define IPMI_NETFN_TRANSPORT		0xc
 #define IPMI_NETFN_ISOL			0x34
+#define IPMI_NETFN_OEM			0x30
 
 #define IPMI_BMC_SLAVE_ADDR		0x20
 #define IPMI_REMOTE_SWID		0x81
diff -urN ipmitool-1.6.0/include/ipmitool/ipmi_oem_tyan.h ipmitool-1.6.0-tyan/include/ipmitool/ipmi_oem_tyan.h
--- ipmitool-1.6.0/include/ipmitool/ipmi_oem_tyan.h	1970-01-01 01:00:00.000000000 +0100
+++ ipmitool-1.6.0-tyan/include/ipmitool/ipmi_oem_tyan.h	2004-12-23 19:24:39.000000000 +0100
@@ -0,0 +1,15 @@
+#ifndef IPMI_OEM_TYAN_H
+#define IPMI_OEM_TYAN_H
+
+#include <ipmitool/ipmi.h>
+
+#define IPMI_OEM_TYAN_BOOTDEVICE_BIOS		0x1
+
+#define IPMI_OEM_TYAN_COMMAND_CONREDIR_STOP	0x2
+#define IPMI_OEM_TYAN_COMMAND_CONREDIR_STROKE	0x3
+#define IPMI_OEM_TYAN_COMMAND_BOOTDEVICE	0x4
+#define IPMI_OEM_TYAN_COMMAND_CONREDIR_START	0x6
+
+int ipmi_oem_tyan_main(struct ipmi_intf *, int, char **);
+
+#endif /*IPMI_OEM_TYAN_H*/
diff -urN ipmitool-1.6.0/lib/ipmi_oem_tyan.c ipmitool-1.6.0-tyan/lib/ipmi_oem_tyan.c
--- ipmitool-1.6.0/lib/ipmi_oem_tyan.c	1970-01-01 01:00:00.000000000 +0100
+++ ipmitool-1.6.0-tyan/lib/ipmi_oem_tyan.c	2004-12-24 17:22:44.000000000 +0100
@@ -0,0 +1,253 @@
+#include <signal.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/poll.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <ipmitool/helper.h>
+#include <ipmitool/ipmi.h>
+#include <ipmitool/ipmi_intf.h>
+#include <ipmitool/ipmi_oem_tyan.h>
+
+extern int verbose;
+
+static const struct valstr ipmi_oem_tyan_bootdevice_vals[] = {
+	{ 0x01, "BIOS" },
+	{ 0x00, NULL }
+};
+
+static int ipmi_oem_tyan_bootdevice(struct ipmi_intf * intf, unsigned char ctl)
+{
+	struct ipmi_rs * rsp;
+	struct ipmi_rq req;
+	unsigned char data[4];
+
+	ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
+
+	data[0] = ctl;
+	data[1] = 0;
+	data[2] = 0;
+	data[3] = 0;
+
+	memset(&req, 0, sizeof(req));
+	req.msg.netfn = IPMI_NETFN_OEM;
+	req.msg.cmd = IPMI_OEM_TYAN_COMMAND_BOOTDEVICE;
+	req.msg.data = data;
+	req.msg.data_len = sizeof(data);
+
+	rsp = intf->sendrecv(intf, &req);
+
+	if (!rsp || rsp->ccode) {
+		printf("Unable to set Bootdevice to %s\n",
+		       val2str(ctl, ipmi_oem_tyan_bootdevice_vals));
+		return -1;
+	} else {
+		printf("Bootdevice: %s\n",
+		       val2str(ctl, ipmi_oem_tyan_bootdevice_vals));
+	}
+	return 0;
+}
+
+union conredir_data
+{
+	struct
+	{
+		struct in_addr sin_addr;            /* Internet address.  */
+		in_port_t sin_port;                 /* Port number.  */
+	}
+	addr __attribute__((packed));
+	unsigned char data[7];
+};
+
+static bool _in_raw_mode;
+static struct termios _saved_tio;
+
+static int ipmi_oem_tyan_conredir_stop();
+
+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 = false;
+}
+
+static void enter_raw_mode(void)
+{
+	struct termios tio;
+	if (tcgetattr(fileno(stdin), &tio) == -1) {
+		perror("tcgetattr");
+		return;
+	}
+	_saved_tio = tio;
+	tio.c_iflag &= ~(ISTRIP | INLCR | IGNCR | ICRNL | IXON | IXANY | IXOFF);
+	tio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | IEXTEN);
+	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 = true;
+}
+
+static void sighandler(int sig)
+{
+	switch (sig)
+	{
+	}
+}
+
+static int ipmi_oem_tyan_conredir(struct ipmi_intf * intf)
+{
+	struct ipmi_rs *rsp;
+	struct ipmi_rq req;
+	union conredir_data conredir_data;
+	struct sockaddr_in addr;
+	socklen_t len = sizeof(addr);
+	int fd, ret = -1;
+	struct pollfd fds[2] =
+	{
+		{ 0, POLLIN, 0 },
+		{ 0, POLLIN, 0 },
+	};
+	struct sigaction act, oldact;
+
+	ipmi_intf_session_set_privlvl(intf, IPMI_SESSION_PRIV_ADMIN);
+
+        if (!intf->opened)
+		intf->open(intf);
+
+	if (getsockname(intf->fd, (struct sockaddr *)&addr, &len) != 0) {
+		perror("getsockname");
+		return -1;
+	}
+	conredir_data.addr.sin_addr = addr.sin_addr;
+	conredir_data.addr.sin_port = addr.sin_port = htons(6666);
+
+	fd = socket(PF_INET, SOCK_DGRAM, 0);
+	if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
+		perror("bind");
+		return -1;
+	}
+	conredir_data.data[6] = 0;
+
+	memset(&req, 0, sizeof(req));
+	req.msg.netfn = IPMI_NETFN_OEM;
+	req.msg.cmd = IPMI_OEM_TYAN_COMMAND_CONREDIR_START;
+	req.msg.data = conredir_data.data;
+	req.msg.data_len = sizeof(conredir_data.data);
+
+	rsp = intf->sendrecv(intf, &req);
+
+	if (!rsp || rsp->ccode) {
+		printf("Unable to start console redirection\n");
+                goto error;
+	} else {
+		printf("Established console redirection\n");
+	}
+
+	memset(&act, 0, sizeof(act));
+	act.sa_handler = sighandler;
+	act.sa_flags = 0;
+
+	if (sigemptyset(&act.sa_mask) < 0) {
+		psignal(SIGINT, "unable to empty signal set");
+                goto error;
+	}
+
+	if (sigaction(SIGINT, &act, &oldact) < 0) {
+		psignal(SIGINT, "unable to register handler");
+                goto error;
+	}
+
+	enter_raw_mode();
+
+	fds[1].fd = fd;
+
+	while (1) {
+		char buf[1024];
+		int r = poll(fds, 2, -1);
+		if (r < 0)
+			break;
+
+		if (fds[0].revents & POLLIN) {
+			r = read(fds[0].fd, buf + 1, 255);
+			req.msg.cmd = IPMI_OEM_TYAN_COMMAND_CONREDIR_STROKE;
+			req.msg.data = buf;
+			buf[0] = r + 1;
+			req.msg.data_len = r + 1;
+
+			rsp = intf->sendrecv(intf, &req);
+		}
+		else if (fds[1].revents & POLLIN) {
+			char *tmp = buf;
+			r = read(fds[1].fd, buf, sizeof(buf));
+			while (r > 0)
+				if (!*tmp) {
+					tmp++;
+					r--;
+				}
+				else
+					break;
+			if (r > 0)
+				write(1, tmp, r);
+		}
+	}
+
+	leave_raw_mode();
+
+	req.msg.cmd = IPMI_OEM_TYAN_COMMAND_CONREDIR_STOP;
+	req.msg.data = conredir_data.data;
+	req.msg.data_len = sizeof(conredir_data.data);
+
+	rsp = intf->sendrecv(intf, &req);
+
+	ret = 0;
+
+error:
+
+	if (sigaction(SIGINT, &oldact, NULL) < 0)
+		psignal(SIGINT, "unable to reset handler");
+
+	close (fd);
+
+	return ret;
+}
+
+int ipmi_oem_tyan_main(struct ipmi_intf * intf, int argc, char ** argv)
+{
+	if (!argc || !strncmp(argv[0], "help", 4)) {
+		printf("OEM Tyan Commands:  bootdevice\n");
+		return 0;
+	}
+	else if (!strncmp(argv[0], "bootdevice", 10)) {
+		unsigned char ctl = 0;
+
+		if (argc < 2 || !strncmp(argv[1], "help", 4)) {
+			printf("chassis power Commands: status, on, off, cycle, reset, diag, soft\n");
+			return 0;
+		}
+
+		if (!strncmp(argv[1], "bios", 4))
+			ctl = IPMI_OEM_TYAN_BOOTDEVICE_BIOS;
+		else {
+			printf("Invalid chassis power command: %s\n", argv[1]);
+			return -1;
+		}
+		return ipmi_oem_tyan_bootdevice(intf, ctl);
+	}
+	else if (!strncmp(argv[0], "conredir", 0)) {
+		return ipmi_oem_tyan_conredir(intf);
+	}
+	else {
+		printf("Invalid Tyan command: %s\n", argv[0]);
+		return -1;
+	}
+	return 0;
+}
diff -urN ipmitool-1.6.0/lib/Makefile.am ipmitool-1.6.0-tyan/lib/Makefile.am
--- ipmitool-1.6.0/lib/Makefile.am	2004-09-01 01:11:45.000000000 +0200
+++ ipmitool-1.6.0-tyan/lib/Makefile.am	2004-12-23 19:24:39.000000000 +0100
@@ -39,7 +39,8 @@
 libipmitool_la_SOURCES		= helper.c ipmi_sdr.c ipmi_sel.c ipmi_sol.c ipmi_isol.c \
 				  ipmi_lanp.c ipmi_fru.c ipmi_chassis.c ipmi_bmc.c log.c \
 				  dimm_spd.c ipmi_sensor.c ipmi_channel.c ipmi_event.c \
-				  ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c 
+				  ipmi_session.c ipmi_strings.c ipmi_user.c ipmi_raw.c \
+				  ipmi_oem_tyan.c
 libipmitool_la_LDFLAGS		= -export-dynamic
 libipmitool_la_LIBADD		= -lm
 libipmitool_la_DEPENDENCIES	= 
diff -urN ipmitool-1.6.0/lib/test ipmitool-1.6.0-tyan/lib/test
--- ipmitool-1.6.0/lib/test	1970-01-01 01:00:00.000000000 +0100
+++ ipmitool-1.6.0-tyan/lib/test	2004-12-24 15:52:05.000000000 +0100
@@ -0,0 +1,38 @@
+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;
+}
+
+
+
+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;
+}
+
diff -urN ipmitool-1.6.0/src/ipmitool.c ipmitool-1.6.0-tyan/src/ipmitool.c
--- ipmitool-1.6.0/src/ipmitool.c	2004-09-04 00:19:32.000000000 +0200
+++ ipmitool-1.6.0-tyan/src/ipmitool.c	2004-12-24 23:08:37.000000000 +0100
@@ -40,6 +40,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <signal.h>
 
 #include <ipmitool/helper.h>
 #include <ipmitool/log.h>
@@ -60,6 +61,7 @@
 #include <ipmitool/ipmi_event.h>
 #include <ipmitool/ipmi_user.h>
 #include <ipmitool/ipmi_raw.h>
+#include <ipmitool/ipmi_oem_tyan.h>
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -73,6 +75,8 @@
 extern const struct valstr ipmi_privlvl_vals[];
 extern const struct valstr ipmi_authtype_session_vals[];
 
+struct ipmi_intf * intf = NULL;
+
 /* defined in ipmishell.c */
 extern int ipmi_shell_main(struct ipmi_intf * intf, int argc, char ** argv);
 extern int ipmi_set_main(struct ipmi_intf * intf, int argc, char ** argv);
@@ -100,6 +104,7 @@
 	{ ipmi_shell_main,	"shell",	"Launch interactive IPMI shell" },
 	{ ipmi_exec_main,	"exec",		"Run list of commands from file" },
 	{ ipmi_set_main,	"set",		"Set runtime variable for shell and exec" },
+	{ ipmi_oem_tyan_main,	"oem-tyan",	"OEM Tyan" },
 	{ NULL },
 };
 
@@ -195,10 +200,20 @@
 	return pass;
 }
 
+static void sighandler (int sig)
+{
+	switch (sig)
+	{
+		case SIGINT:
+			if (intf)
+				intf->close(intf);
+			exit(EXIT_SUCCESS);
+			break;
+	}
+}
 
 int main(int argc, char ** argv)
 {
-	struct ipmi_intf * intf = NULL;
 	unsigned char privlvl = 0;
 	unsigned char target_addr = 0;
 	unsigned char my_addr = 0;
@@ -326,6 +341,9 @@
 		goto out_free;
 	}
 
+	/* init signal handler */
+	signal_handler(SIGINT, sighandler);
+
 	/* load interface */
 	intf = ipmi_intf_load(intfname);
 	if (!intf) {
