diff -Npru README.macosx.orig README.macosx
--- README.macosx.orig	2005-11-11 17:34:41.000000000 +1100
+++ README.macosx	2006-09-12 02:36:11.000000000 +1000
@@ -1,22 +1,65 @@
-Starting with version 10 upslug2 is compatible with Mac OSX.
+Running upslug2 on Mac OSX
+==========================
+Starting with version 10 upslug2 is compatible with Mac OSX. Upslug2 is
+available both as a binary download and as a source package that you can
+compile yourself. Instructions for both methods are listed below.
+
+Background information
+======================
+Upslug2 requires libpcap to work on OSX. This library is included in OSX by
+default but that version does not support the functionality needed by upslug2.
+This is true for OSX 10.3 (Panther) and possibly also for 10.4 (Tiger) but
+that have not been checked. We need version 0.9.3 or greater of libpcap which
+can be found in DarwinPorts (http://www.darwinports.org) and also from Fink
+(http://fink.sourceforge.net) but that has not been tested. We will describe
+how to install libpcap from DarwinPorts.
+
+Darwinports
+===========
+To use upslug2 you need to have Darwinports installed on your Mac. Obtaining
+Darwinports and instructions for installing can be found here:
+http://darwinports.org/getdp/
+
+Note: There are separate downloads depending on which version of OS X you
+      are running. So make sure that you download the correct version.
+
+Installing libpcap
+==================
+When you have Darwinports installed you need to install 'libpcap' on your
+system. That is done by giving the following command on your terminal:
+
+sudo port install libpcap
+
+If you have downloaded the binary release of upslug2 you are now ready to
+start using upslug2 on your Mac so you can skip the instructions for
+compiling upslug2.
+
+Compile upslug2 on OSX
+======================
+If you want to compile upslug2 yourself you need to do like this.
+
+Note: These instructions are true for a normal installation of DarwinPorts.
+      If you have installed DarwinPorts in another location you need to
+      change the paths for CPPFLAGS and LDFLAGS.
 
-Upslug2 requires libpcap version 0.9.3 or greater to work on OSX. By default,
-libpcap is included in OSX but it doesn't support all needed functions. So you
-will need to install a more recent version of libpcap. Fortunately the library
-is available through DarwinPorts (http://www.darwinports.org). Maybe it is also
-available from Fink (http://fink.sourceforge.net) but that has not been tested.
+CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib ./configure --with-libpcap
+make
 
-If you don't have DarwinPorts installed, go to the website and learn how to
-use it. Just make sure you also install libpcap.
+If you want to install upslug2 permanently on your system:
+sudo make install
 
-Now you are ready to build upslug2:
+If you want upslug2 to be installed to a specific location you need to
+add '--prefix=/<your path>' to the 'configure' command above.
 
-By default, DarwinPorts will be installed in /opt. If you have it installed
-in another location you have to adjust the path's below.
-
-CPPFLAGS=-I/opt/local/include LDFLAGS=-L/opt/local/lib ./configure --with-libpcap
-make
-make install
+If you do not want to install upslug2 you can either copy it manually to
+a suitable directory or just have upslug2 in the build directory.
 
+Using upslug2
+=============
 Using upslug2 requires root access since the bpf-device(s) on OSX are
 configured for read-only access for all other users.
+
+sudo upslug2 <options>
+
+If you are in the same directory as you built upslug2 and upslug2 is not in
+your PATH you need to invoke upslug2 with 'sudo ./upslug2 <options>'.
diff -Npru configure.ac.orig configure.ac
--- configure.ac.orig	2005-11-16 13:57:46.000000000 +1100
+++ configure.ac	2006-09-12 02:36:11.000000000 +1000
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(upslug2, 11, http://sourceforge.net/projects/nslu/)
+AC_INIT(upslug2, 12, http://sourceforge.net/projects/nslu/)
 AM_INIT_AUTOMAKE(1.9)
 AC_CONFIG_SRCDIR([config.h.in])
 AM_CONFIG_HEADER([config.h])
@@ -12,6 +12,10 @@ AC_CANONICAL_HOST
 case "$host" in
   *-linux*)
     AC_DEFINE(BROKEN_PCAP_TIMEOUT, 1, [Define if pcap_open_live timeout does not work])
+    AC_DEFINE(DEFAULT_ETHERNET_IF, "eth0", [Define default ethernet interface])
+    ;;
+  *-darwin*)
+    AC_DEFINE(DEFAULT_ETHERNET_IF, "en0", [Define default ethernet interface])
     ;;
 esac
 
diff -Npru linux_wire.cc.orig linux_wire.cc
--- linux_wire.cc.orig	2005-10-16 02:47:12.000000000 +1000
+++ linux_wire.cc	2006-09-12 02:36:11.000000000 +1000
@@ -194,9 +194,9 @@ NSLU2Upgrade::Wire *NSLU2Upgrade::Wire::
 		if (packet_socket == (-1))
 			throw WireError(errno);
 
-		/* Check the device name.  If not given use 'eth0'. */
+		/* Check the device name.  If not given use 'DEFAULT_ETHERNET_IF'. */
 		if (device == NULL)
-			device = "eth0";
+			device = DEFAULT_ETHERNET_IF;
 
 		/* We are using a level which requires a hardware specific address,
 		 * that's because the NSLU2 doesn't (for reasons which are far from
diff -Npru nslu2_image.cc.orig nslu2_image.cc
--- nslu2_image.cc.orig	2005-10-21 03:10:29.000000000 +1000
+++ nslu2_image.cc	2007-12-27 10:38:19.000000000 +1100
@@ -5,6 +5,7 @@
  */
 #include <stdexcept>
 #include <cstring>
+#include <iostream>
 #include <fstream>
 #include <cerrno>
 
@@ -27,8 +28,8 @@ namespace NSLU2Image {
 		}
 	}
 
-	void SafeSeek(std::ifstream *stream, int offset, const char *name) {
-		stream->seekg(offset, std::ios::beg);
+	void SafeSeek(std::ifstream *stream, int offset, const char *name, std::ios::seekdir dir = std::ios::beg) {
+		stream->seekg(offset, dir);
 		if (!stream->good())
 			throw NSLU2Image::FileError(SizeError, name, errno);
 	}
@@ -72,7 +73,7 @@ namespace NSLU2Image {
 		void Validate(const char *i) {
 			char signature[8];
 
-			SafeSeek(&image, NSLU2Protocol::FlashSize-8, i);
+			SafeSeek(&image, -8, i, std::ios::end);
 			SafeRead(&image, signature, 8, i);
 			if (memcmp(signature, "eRcOmM", 6) != 0)
 				throw NSLU2Image::FileError(DataError, i, 0);
diff -Npru nslu2_upgrade.cc.orig nslu2_upgrade.cc
--- nslu2_upgrade.cc.orig	2005-11-23 17:53:46.000000000 +1100
+++ nslu2_upgrade.cc	2007-12-27 10:38:19.000000000 +1100
@@ -9,8 +9,10 @@
 
 namespace NSLU2Upgrade {
 	/* Hardware ID field, add others as required. */
-	static const unsigned char NSLU2ID0[32] = {
-		4, 112, 49, 149, 88, 16, /* remainder 0 */
+	static const unsigned char NSLU2ID0[][32] = {
+		{4, 112, 49, 149, 88, 16}, /* remainder 0 */
+		{0x44, 0x47, 0x38, 0x33, 0x34, 0x56, 0x33},  /* remainder 0 */
+		0
 	};
 
 	/* Real implementations. */
@@ -52,19 +54,26 @@ namespace NSLU2Upgrade {
 				 */
 				if (receive.TypeOf() == NSLU2Protocol::HardwareInfo &&
 					receive.Sequence() == sequence &&
-					receive.DataLength() == NSLU2Protocol::HardwareInfoLength &&
+					receive.DataLength() == NSLU2Protocol::HardwareInfoLength
 					/* Validate the non-variable parts of the hardware
 					 * info - this stuff is simply copied from the RedBoot
 					 * part of the image, however the data in question is
 					 * not actually from the RedBoot source/build - rather
 					 * it is inserted when the flash image is built.  This
 					 * code checks the 32 byte 'hardware id' for a match.
-					 */
-					memcmp(receive.Data()+4, NSLU2ID0, 32) == 0) {
+					 */) {
+					/* try all IDs */
+					int found = 0, i;
+					const unsigned char *d = receive.Data()+4+32+2;
+					for(i = 0; NSLU2ID0[i][0]; i++)
+						if(memcmp(receive.Data()+4, NSLU2ID0[i], 32) == 0)
+							found = 1;
+					if(found == 0)
+						continue;
+						
 					/* Copy out the ProductID, ProtocolID and
 					 * FirmwareVersion fields.
 					 */
-					const unsigned char *d = receive.Data()+4+32+2;
 					product_id       = (d[0]<<8) + d[1], d += 4;
 					protocol_id      = (d[0]<<8) + d[1], d += 4;
 					/* skip FunctionId */ d += 4;
diff -Npru pcap_wire.cc.orig pcap_wire.cc
--- pcap_wire.cc.orig	2005-11-23 18:13:51.000000000 +1100
+++ pcap_wire.cc	2006-09-12 02:36:11.000000000 +1000
@@ -289,9 +289,9 @@ NSLU2Upgrade::Wire *NSLU2Upgrade::Wire::
 	/* This is used to store the error passed to throw. */
 	static char PCapErrbuf[PCAP_ERRBUF_SIZE];
 
-	/* Check the device name.  If not given use 'eth0'. */
+	/* Check the device name.  If not given use 'DEFAULT_ETHERNET_IF'. */
 	if (device == NULL)
-		device = "eth0";
+		device = DEFAULT_ETHERNET_IF;
 
 	pcap_t *pcap = NULL;
 	{
diff -Npru upslug2.8.orig upslug2.8
--- upslug2.8.orig	1970-01-01 10:00:00.000000000 +1000
+++ upslug2.8	2006-10-18 07:56:51.000000000 +1000
@@ -0,0 +1,220 @@
+.\" $Id$
+.\"
+.\" Copyright (C) 2006  Martin Michlmayr <tbm@cyrius.com>
+.\"
+.\" Permission is hereby granted, free of charge, to any person
+.\" obtaining a copy of this software and associated documentation files
+.\" (the "Software"), to deal in the Software without restriction,
+.\" including without limitation the rights to use, copy, modify,
+.\" merge, publish, distribute, sublicense, and/or sell copies of the
+.\" Software, and to permit persons to whom the Software is furnished
+.\" to do so, subject to the following conditions:
+.\"
+.\" The above copyright notice and this permission notice shall be
+.\" included in all copies or substantial portions of the Software.
+.\"
+
+.TH UPSLUG2 8 "January 2006"
+.SH NAME
+upslug2 \- utility to upgrade the firmware of a NSLU2 via the network
+
+
+.SH SYNOPSIS
+.B upslug2
+[options]
+
+
+.SH DESCRIPTION
+
+.B upslug2
+is a command line program intended to allow the upgrade the firmware of a
+LinkSys NSLU2 (Network Storage Link for USB 2.0 Disk Drives) to new or
+different versions.  When a NSLU2 in the local network is put in upgrade
+mode,
+.B upslug2
+can connect to it and upload a new firmware.
+
+.B upslug2
+will accept a full firmware image but it can also upgrade the
+flash from individual files holding the kernel, ramdisk and root
+filesystem.
+.B upslug2
+provides status information during the upgrade process and verifies the
+written image after the upgrade.
+
+
+.SH OPTIONS
+
+.TP
+\fB\-C\fR, \fB\-\-Complete\-reprogram\fR
+Reprogram the complete flash, including the RedBoot boot loader and the
+SysConf partition holding configuration information.  Using this option
+may result in the NSLU2 becoming permanently unusable!  By default,
+.B upslug2
+will not touch these two partitions since this allows flashing a new
+firmware if an uploaded firmware does not work.  This is not possible if
+RedBoot itself is damaged.  Use with caution.
+
+.TP
+\fB\-d\fR, \fB\-\-device\fR
+The network device on the host machine connected to the network on which
+the NSLU2 is located. (Default: eth0).
+
+.TP
+\fB\-e\fR, \fB\-\-endian\fR
+The endianness of the files to be uploaded.
+.B upslug2
+will usually detected the endianness automatically but this option can be
+used to force byte swapping to occur.  This option accepts three values,
+separated by comma: endianness of kernel, data and RedBoot FIS directory.
+Valid values are \fBl\fR (little endian), \fBp\fR (pdp endian) and \fBb\fR
+(big endian). (Default: ,b,b)
+
+.TP
+\fB\-f\fR, \fB\-\-from\fR
+The MAC address of the host system.
+
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Show summary of options.
+
+.TP
+\fB\-i\fR, \fB\-\-image\fR
+The flash image to use.
+
+.TP
+\fB\-j\fR, \fB\-\-rootfs\fR
+A root filesystem, usually of type jffs.
+
+.TP
+\fB\-k\fR, \fB\-\-kernel\fR
+A compressed kernel zImage image.
+
+.TP
+\fB\-n\fR, \fB\-\-no\-reboot\fR
+Do not reboot after upgrade
+
+.TP
+\fB\-p\fR, \fB\-\-payload\fR
+FIS directory payload.  There are about 140 Kb in the last block (between
+the FIS dir and the trailer at the end) which can be used for data.
+
+.TP
+\fB\-r\fR, \fB\-\-ramdisk\fR
+A compressed ramdisk image.
+
+.TP
+\fB\-R\fR, \fB\-\-ram\-payload\fR
+A ram paylod (replaced ramdisk).
+(FIXME: if it replaced the ramdisk, why cannot you just use the -r option?
+What's the difference)
+
+.TP
+\fB\-t\fR, \fB\-\-target\fR
+The MAC address of the NSLU2 to upgrade.  Without this option,
+.B upslug2
+will only perform an upgrade if there is just one NSLU2 in upgrade mode.
+
+.TP
+\fB\-U\fR, \fB\-\-no\-verify\fR
+Do not verify the image, only upgrade.
+
+.TP
+\fB\-v\fR, \fB\-\-verify\fR
+Do not write to flash, only verify the image.
+
+
+.SS Options to specify firmware information
+
+The following options should be used when individual kernel, ramdisk and
+root filesystem files are specified rather than a firmware image.
+
+.TP
+\fB\-E\fR, \fB\-\-extra\-version\fR
+Extra version information, a 2 byte value. (Default: 0x90f7)
+
+.TP
+\fB\-F\fR, \fB\-\-firmware\-version\fR
+The firmware version, a 2 byte value. (Default: 0x2329)
+
+.TP
+\fB\-P\fR, \fB\-\-product\-id\fR
+The product ID, a 2 byte value. (Default: 1)
+
+.TP
+\fB\-T\fR, \fB\-\-protocol\-id\fR
+The protocol ID, a 2 byte value. (Default: 0)
+
+
+.SH USING UPSLUG2
+
+In order to use
+.B upslug2
+the NSLU2 which is to be upgraded has to be put in upgrade mode:
+
+1. Disconnect any disks and/or devices from the USB ports.
+
+2. Power off the NSLU2
+
+3. Press and hold the reset button (accessible through the small hole on
+the back just above the power input).
+
+4. Press and release the power button to power on the NSLU2.
+
+5. Wait for 10 seconds watching the ready/status LED. After 10 seconds it
+will change from amber to red. Immediately release the reset button.
+
+6. The NSLU2 ready/status LED will flash alternately red/green (there is a
+1 second delay before the first green). The NSLU2 is now in upgrade mode.
+
+If you decide not to flash the image the NSLU2 can be rebooted by
+disconnecting the power.  If the ready/status LED does not turn green after
+step four it will remain red for several seconds then flash amber. This
+happens if you do not release the reset button in time - pull the power,
+reconnect it and repeat from the second step.
+
+Once the NSLU2 is in upgrade mode it will remain in this state until either
+the power is connected or a new image has been flashed. If the flash fails
+the NSLU2 will (eventually) return to upgrade mode
+
+.SH EXAMPLES
+
+The most common use of
+.B upslug2
+is the following:
+.RS
+upslug2 \-\-image NSLU2_V23R63.bin
+.RE
+This specifies a firmware image which will be written to flash (with
+the exception of the RedBoot and SysConf partitions).
+
+Alternatively, kernel, ramdisk and root filesystem can be specified
+individually:
+.RS
+upslug2 \-k nslu2-zImage \-r ramdisk -\j root.jffs
+.RE
+In this case, the options \fB\-E\fR, \fB\-F\fR, \fB\-P\fR and \fB\-T\fR
+should typically be specified as well.
+
+By default,
+.B upslug2
+will search for the NSLU2 on the network on your eth0 network interface.
+If the network is on a different interface, you can easily specify it:
+.RS
+upslug2 \-d eth1 \-\-image NSLU2_V23R63.bin
+.RE
+
+If there are potentially more than one NSLU2 in your network which may be
+in upgrade mode, you can specify its MAC address:
+.RS
+upslug2 \-t 00:11:85:12:34:56 \-\-image NSLU2_V23R63.bin
+.RE
+
+.SH SEE ALSO
+.PP
+.BR slugimage (1)
+
+.SH AUTHOR
+.PP
+John Bowler <jbowler@acm.org>
+
diff -Npru upslug2.cc.orig upslug2.cc
--- upslug2.cc.orig	2005-11-23 17:54:08.000000000 +1100
+++ upslug2.cc	2006-09-12 02:36:11.000000000 +1000
@@ -3,6 +3,8 @@
  *
  * The upslug2 main program for the command line implementation.
  */
+#include "config.h"
+
 #include <cstdio>
 #include <cstring>
 #include <cstdlib>
@@ -38,7 +40,7 @@ public:
 			"  Display:\n"
 			"    <status> <address completed>+<bytes transmitted but not completed>\n"
 			"  Status:\n"
-			"    * timeout occured          + sequence error detected\n\n",
+			"    * timeout occurred         + sequence error detected\n\n",
 			target[3], target[4], target[5],
 			target[0], target[1], target[2], target[3], target[4], target[5],
 			Indicator(UpSlug2::ProgressBar::Init),
@@ -182,7 +184,7 @@ void Reboot(NSLU2Upgrade::DoUpgrade *upg
 }
 
 void help(struct option *options) {
-	std::fprintf(stderr, "upslug2: usage: upslug2 {options}\n options:\n");
+	std::fprintf(stderr, "Usage: upslug2 {options}\n options:\n");
 	while (options->name) {
 		std::fprintf(stderr, "  -%c --%s\n", options->val, options->name);
 		++options;
@@ -190,13 +192,13 @@ void help(struct option *options) {
 	std::fprintf(stderr, "\n"
 " Specify --target to upgrade an NSLU2 (or to verify a previous upgrade)\n"
 " without no arguments upslug2 will list the NSLU2 machines which are currently\n"
-" in upgrade mode (and do nothing else).  Without --targeet upslug2 will only\n"
+" in upgrade mode (and do nothing else).  Without --target upslug2 will only\n"
 " perform an upgrade if there is just one NSLU2 in upgrade mode.\n"
 "\n"
 " Specify --image=<file> if a complete NSLU2 flash image is available, if\n"
 " --Complete-reprogram is specified the whole flash image will be overwritten\n"
 " (the NSLU2 may become permanently unuseable if this is done), otherwise the\n"
-" RedBoot boot loader and currently 'SysConf' configuration is not changed.\n"
+" RedBoot boot loader and the current 'SysConf' configuration is not changed.\n"
 "\n"
 " Alternatively specify --kernel and --rootfs to build the image which will be\n"
 " used to upgrade the NSLU2.  In this case --product-id, --protocol-id and\n"
@@ -369,7 +371,7 @@ int main(int argc, char **argv) {
 	char                kernel_sex(0);        /* Byte sex of kernel */
 	char                data_sex('b');        /* Byte sex of data */
 	char                directory_sex('b');   /* Byte sex of FIS directory entries */
-	const char*         device = "eth0";      /* Hardware device to use */
+	const char*         device = DEFAULT_ETHERNET_IF;      /* Hardware device to use */
 	const char*         target = "broadcast"; /* User specified target name */
 	const unsigned char*mac = 0;              /* Ethernet address to upgrade. */
 	unsigned char       macBuffer[6];         /* To store the command line address */
@@ -396,7 +398,7 @@ int main(int argc, char **argv) {
 	/* The list of options, I combine the help text with the option name. */
 	struct option options[] = {
 { "help:                     output this help message",         no_argument,       0, 'h' },
-{ "device[eth0]:             local ethernet device to use",     required_argument, 0, 'd' },
+{ "device[" DEFAULT_ETHERNET_IF "]:             local ethernet device to use",     required_argument, 0, 'd' },
 { "target:                   NSLU2 to upgrade (MAC address)",   required_argument, 0, 't' },
 { "from:                     MAC of host (this machine)",       required_argument, 0, 'f' },
 { "verify:                   verify only (do not write flash)", no_argument,       0, 'v' },
