diff --git a/Makefile.target b/Makefile.target
index acd6cda..6e88704 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -393,7 +393,7 @@ ifeq ($(ARCH),alpha)
 endif
 
 # must use static linking to avoid leaving stuff in virtual address space
-VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o
+VL_OBJS=vl.o osdep.o monitor.o pci.o loader.o isa_mmio.o pcap.o
 # XXX: suppress QEMU_TOOL tests
 ifdef CONFIG_WIN32
 VL_OBJS+=block-raw-win32.o
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 84d1e52..cfc9162 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -74,10 +74,12 @@
 #define KiB 1024
 
 /* debug EEPRO100 card */
-//~ #define DEBUG_EEPRO100
+#define DEBUG_EEPRO100
+
+int e100_debug = 0;
 
 #ifdef DEBUG_EEPRO100
-#define logout(fmt, args...) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ##args)
+#define logout(fmt, args...) {if (e100_debug) fprintf(stderr, "EE100\t%-24s" fmt, __func__, ##args);}
 #else
 #define logout(fmt, args...) ((void)0)
 #endif
@@ -173,6 +175,15 @@ typedef struct {
 } eepro100_rx_t;
 
 typedef struct {
+    uint16_t count;
+    uint16_t pad0;
+    uint32_t link;
+    uint32_t buf_addr;
+    uint16_t size;
+    uint16_t pad1;
+} eepro100_rbd_t;
+
+typedef struct {
     uint32_t tx_good_frames, tx_max_collisions, tx_late_collisions,
         tx_underruns, tx_lost_crs, tx_deferred, tx_single_collisions,
         tx_multiple_collisions, tx_total_collisions;
@@ -243,6 +254,7 @@ typedef struct {
     /* (ru_base + ru_offset) address the RFD in the Receive Frame Area. */
     uint32_t ru_base;           /* RU base address */
     uint32_t ru_offset;         /* RU address offset */
+    uint32_t rbd_offset;         /* RBD address offset */
     uint32_t statsaddr;         /* pointer to eepro100_stats_t */
     eepro100_stats_t statistics;        /* statistical counters */
 #if 0
@@ -724,20 +736,13 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
             uint16_t size = 0;
             uint32_t tbd_address = cb_address + 0x10;
             assert(tcb_bytes <= sizeof(buf));
-            while (size < tcb_bytes) {
-                uint32_t tx_buffer_address = ldl_phys(tbd_address);
-                uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
-                //~ uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
-                tbd_address += 8;
+            if (tbd_array == 0xffffffff) {
+                /* Simplified mode. */
                 logout
                     ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
-                     tx_buffer_address, tx_buffer_size);
-                cpu_physical_memory_read(tx_buffer_address, &buf[size],
-                                         tx_buffer_size);
-                size += tx_buffer_size;
-            }
-            if (tbd_array == 0xffffffff) {
-                /* Simplified mode. Was already handled by code above. */
+                     tbd_address, tcb_bytes);
+                cpu_physical_memory_read(tbd_address, buf, tcb_bytes);
+		size = tcb_bytes;
             } else {
                 /* Flexible mode. */
                 uint8_t tbd_count = 0;
@@ -746,7 +751,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
                     assert(tcb_bytes == 0);
                     for (; tbd_count < 2; tbd_count++) {
                         uint32_t tx_buffer_address = ldl_phys(tbd_address);
-                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4);
+                        uint16_t tx_buffer_size = lduw_phys(tbd_address + 4) & 0x3fff;
                         uint16_t tx_buffer_el = lduw_phys(tbd_address + 6);
                         tbd_address += 8;
                         logout
@@ -869,6 +874,16 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
         }
         set_ru_state(s, ru_ready);
         s->ru_offset = s->pointer;
+
+        eepro100_rx_t rx;
+        cpu_physical_memory_read(s->ru_base + s->ru_offset, (uint8_t *) & rx,
+                                 offsetof(eepro100_rx_t, packet));
+        uint16_t rfd_command = le16_to_cpu(rx.command);
+
+        /* If the SF bit is set, then use flexible mode. */
+        if (rfd_command & 0x0008)
+            s->rbd_offset = le32_to_cpu(rx.rx_buf_addr);
+
         logout("val=0x%02x (rx start)\n", val);
         break;
     case RX_RESUME:
@@ -885,6 +900,10 @@ static void eepro100_ru_command(EEPRO100State * s, uint8_t val)
         logout("val=0x%02x (RU base address)\n", val);
         s->ru_base = s->pointer;
         break;
+    case RX_ABORT:      
+        /* TODO XXX _AP_ need to generate interrupts and halt all activity. */
+        set_ru_state(s, ru_idle);
+        break;
     default:
         logout("val=0x%02x (undefined RU command)\n", val);
         missing("Undefined SU command");
@@ -1545,7 +1564,7 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
                              offsetof(eepro100_rx_t, packet));
     uint16_t rfd_command = le16_to_cpu(rx.command);
     uint16_t rfd_size = le16_to_cpu(rx.size);
-    assert(size <= rfd_size);
+
     if (size < 64) {
         rfd_status |= 0x0080;
     }
@@ -1553,15 +1572,33 @@ static void nic_receive(void *opaque, const uint8_t * buf, int size)
            rx.link, rx.rx_buf_addr, rfd_size);
     stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, status),
              rfd_status);
-    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size);
     /* Early receive interrupt not supported. */
     //~ eepro100_er_interrupt(s);
     /* Receive CRC Transfer not supported. */
     assert(!(s->configuration[18] & 4));
     /* TODO: check stripping enable bit. */
     //~ assert(!(s->configuration[17] & 1));
-    cpu_physical_memory_write(s->ru_base + s->ru_offset +
-                              offsetof(eepro100_rx_t, packet), buf, size);
+
+    if (rfd_command & 0x0008) {
+	/* XXX TODO _AP_ support more links */
+	eepro100_rbd_t rbd;
+	int wrote = 0;
+	do {
+            cpu_physical_memory_read(s->ru_base + s->rbd_offset, (uint8_t *) &rbd, sizeof(rbd));
+            int w = (size - wrote) > rbd.size ? rbd.size : (size - wrote);
+            cpu_physical_memory_write(s->ru_base + rbd.buf_addr, buf + wrote, w);
+            stw_phys(s->ru_base + s->rbd_offset, w | 0x8000 | 0x4000);
+            wrote += w;
+            s->rbd_offset = le32_to_cpu(rbd.link);
+	} while(wrote < size);
+    } else {
+        /* Simplified mode. */
+        assert(size <= rfd_size);
+        cpu_physical_memory_write(s->ru_base + s->ru_offset +
+                                  offsetof(eepro100_rx_t, packet), buf, size);
+    }
+    /* Update the EOF and F bits in addition to setting the size. */
+    stw_phys(s->ru_base + s->ru_offset + offsetof(eepro100_rx_t, count), size | 0x8000 | 0x4000);
     s->statistics.rx_good_frames++;
     eepro100_fr_interrupt(s);
     s->ru_offset = le32_to_cpu(rx.link);
@@ -1631,6 +1668,7 @@ static int nic_load(QEMUFile * f, void *opaque, int version_id)
     qemu_get_be32s(f, &s->cu_offset);
     qemu_get_be32s(f, &s->ru_base);
     qemu_get_be32s(f, &s->ru_offset);
+    qemu_get_be32s(f, &s->rbd_offset);
     qemu_get_be32s(f, &s->statsaddr);
     /* Restore epro100_stats_t statistics */
     qemu_get_be32s(f, &s->statistics.tx_good_frames);
@@ -1710,6 +1748,7 @@ static void nic_save(QEMUFile * f, void *opaque)
     qemu_put_be32s(f, &s->cu_offset);
     qemu_put_be32s(f, &s->ru_base);
     qemu_put_be32s(f, &s->ru_offset);
+    qemu_put_be32s(f, &s->rbd_offset);
     qemu_put_be32s(f, &s->statsaddr);
     /* Save epro100_stats_t statistics */
     qemu_put_be32s(f, &s->statistics.tx_good_frames);
diff --git a/pcap.c b/pcap.c
new file mode 100644
index 0000000..6585dba
--- /dev/null
+++ b/pcap.c
@@ -0,0 +1,62 @@
+#include <assert.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <time.h>
+
+#include "pcap.h"
+
+static int started = 0;
+static FILE *cap_file;
+
+static void
+pcap_write(const char *b, int l) {
+	size_t c = fwrite(b, 1, l, cap_file);
+	assert(c == l);
+	fflush(cap_file);
+}
+
+void
+pcap_dump_init(const char *fname) {
+	pcap_hdr_t pcap_hdr;
+
+	if (!fname)
+		fname = "slirp.cap";
+
+	cap_file = fopen(fname, "wb");
+	if (!cap_file) {
+		perror("pcap_dump_init:");
+		return;
+	}
+
+	pcap_hdr.magic_number = PCAP_MAGIC;
+	pcap_hdr.version_major = PCAP_VMAJOR;
+	pcap_hdr.version_minor = PCAP_VMINOR;
+	pcap_hdr.thiszone = 0;
+	pcap_hdr.sigfigs = 0;
+	pcap_hdr.snaplen = 65535;
+	pcap_hdr.network = 1; // Ethernet
+
+	pcap_write((char *)&pcap_hdr, sizeof(pcap_hdr));
+
+	started = 1;
+}
+
+void
+pcap_dump(const char *pkt, int len) {
+	pcaprec_hdr_t pkt_hdr;
+	struct timeval tv;
+
+	if (!started)
+		return;
+
+	gettimeofday(&tv, 0);
+
+	pkt_hdr.ts_sec = tv.tv_sec;
+	pkt_hdr.ts_usec = tv.tv_usec;
+	pkt_hdr.incl_len = len;
+	pkt_hdr.orig_len = len;
+
+	pcap_write((char *)&pkt_hdr, sizeof(pkt_hdr));
+	pcap_write(pkt, len);
+}
+
diff --git a/pcap.h b/pcap.h
new file mode 100644
index 0000000..e801d29
--- /dev/null
+++ b/pcap.h
@@ -0,0 +1,34 @@
+#ifndef _PCAP_H_
+#define _PCAP_H_
+
+#include "qemu-common.h"
+
+/*
+ * Used http://wiki.wireshark.org/Development/LibpcapFileFormat to get the pcap file format
+ */
+
+#define PCAP_MAGIC	0xa1b2c3d4
+#define PCAP_VMAJOR	2
+#define PCAP_VMINOR	4
+
+typedef struct pcap_hdr_s {
+	uint32_t magic_number;   /* magic number */
+	uint16_t version_major;  /* major version number */
+	uint16_t version_minor;  /* minor version number */
+	int32_t  thiszone;       /* GMT to local correction */
+	uint32_t sigfigs;        /* accuracy of timestamps */
+	uint32_t snaplen;        /* max length of captured packets, in octets */
+	uint32_t network;        /* data link type */
+} pcap_hdr_t;
+
+typedef struct pcaprec_hdr_s {
+	uint32_t ts_sec;         /* timestamp seconds */
+	uint32_t ts_usec;        /* timestamp microseconds */
+	uint32_t incl_len;       /* number of octets of packet saved in file */
+	uint32_t orig_len;       /* actual length of packet */
+} pcaprec_hdr_t;
+
+void pcap_dump_init(const char *fname);
+void pcap_dump(const char *pkt, int len);
+
+#endif //_PCAP_H_
diff --git a/vl.c b/vl.c
index a04edbc..dac4cce 100644
--- a/vl.c
+++ b/vl.c
@@ -37,6 +37,7 @@
 #include "qemu-char.h"
 #include "block.h"
 #include "audio/audio.h"
+#include "pcap.h"
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -158,6 +159,8 @@ int inet_aton(const char *cp, struct in_addr *ia);
 /* XXX: use a two level table to limit memory usage */
 #define MAX_IOPORTS 65536
 
+extern int e100_debug;
+
 const char *bios_dir = CONFIG_QEMU_SHAREDIR;
 const char *bios_name = NULL;
 void *ioport_opaque[MAX_IOPORTS];
@@ -3686,6 +3689,7 @@ int slirp_can_output(void)
 
 void slirp_output(const uint8_t *pkt, int pkt_len)
 {
+    pcap_dump(pkt, pkt_len);
 #if 0
     printf("slirp output:\n");
     hex_dump(stdout, pkt, pkt_len);
@@ -3697,6 +3701,7 @@ void slirp_output(const uint8_t *pkt, int pkt_len)
 
 static void slirp_receive(void *opaque, const uint8_t *buf, int size)
 {
+    pcap_dump(buf, size);
 #if 0
     printf("slirp input:\n");
     hex_dump(stdout, buf, size);
@@ -7617,6 +7622,9 @@ static void help(int exitcode)
 #endif
            "-clock          force the use of the given methods for timer alarm.\n"
            "                To see what timers are available use -clock help\n"
+           "-pcap file_name\n"
+	   "                when -net user is enabled, dump packets to file_name,\n"
+           "-debug-e100     print E100 debug statments\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -7719,6 +7727,9 @@ enum {
     QEMU_OPTION_old_param,
     QEMU_OPTION_clock,
     QEMU_OPTION_startdate,
+
+    QEMU_OPTION_pcap,
+    QEMU_OPTION_debug_e100,
 };
 
 typedef struct QEMUOption {
@@ -7826,6 +7837,8 @@ const QEMUOption qemu_options[] = {
     { "old-param", 0, QEMU_OPTION_old_param },
 #endif
     { "clock", HAS_ARG, QEMU_OPTION_clock },
+    { "pcap", HAS_ARG, QEMU_OPTION_pcap },
+    { "debug-e100", 0, QEMU_OPTION_debug_e100 },
     { "startdate", HAS_ARG, QEMU_OPTION_startdate },
     { NULL },
 };
@@ -8661,6 +8674,12 @@ int main(int argc, char **argv)
                     }
                 }
                 break;
+	    case QEMU_OPTION_pcap:
+                pcap_dump_init(optarg);
+                break;
+	    case QEMU_OPTION_debug_e100:
+		e100_debug = 1;
+                break;
             }
         }
     }
