diff --git a/Makefile.target b/Makefile.target
index 27de4b9..7eb84ad 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -734,7 +734,7 @@ vl.o: qemu-options.h
 
 monitor.o: qemu-monitor.h
 
-$(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) $(CURL_LIBS)
+$(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) $(CURL_LIBS) $(PCAP_LIBS)
 $(QEMU_PROG): ARLIBS=../libqemu_common.a libqemu.a $(HWLIB)
 $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a $(HWLIB)
 	$(call LINK,$(OBJS))
diff --git a/configure b/configure
index 42d46f2..169f8bc 100755
--- a/configure
+++ b/configure
@@ -165,6 +165,7 @@ mingw32="no"
 EXESUF=""
 slirp="yes"
 vde="yes"
+pcap="yes"
 fmod_lib=""
 fmod_inc=""
 oss_lib=""
@@ -432,6 +433,8 @@ for opt do
   ;;
   --disable-vde) vde="no"
   ;;
+  --disable-pcap) pcap="no"
+  ;;
   --disable-kqemu) kqemu="no"
   ;;
   --disable-xen) xen="no"
@@ -634,6 +637,7 @@ echo "  --oss-lib                path to OSS library"
 echo "  --enable-uname-release=R Return R for uname -r in usermode emulation"
 echo "  --sparc_cpu=V            Build qemu for Sparc architecture v7, v8, v8plus, v8plusa, v9"
 echo "  --disable-vde            disable support for vde network"
+echo "  --disable-pcap           disable support for pcap-based network"
 echo "  --disable-pthread        disable pthread support"
 echo "  --disable-aio            disable AIO support"
 echo "  --enable-io-thread       enable IO thread"
@@ -981,6 +985,31 @@ EOF
 fi
 
 ##########################################
+# pcap libraries probe
+if test "$pcap" = "yes" ; then
+  cat > $TMPC << EOF
+#include <pcap.h>
+int main(void)
+{
+    char errbuf[PCAP_ERRBUF_SIZE];
+
+    pcap_lookupdev(errbuf);
+    return 0;
+}
+EOF
+    if test "$mingw32" = "yes" ; then
+        PCAP_LIBS=-lwpcap
+    else
+        PCAP_LIBS=-lpcap
+    fi
+    if $cc $ARCH_CFLAGS -o $TMPE $TMPC $PCAP_LIBS > /dev/null 2> /dev/null ; then
+        :
+    else
+        pcap="no"
+    fi
+fi
+
+##########################################
 # Sound support libraries probe
 
 audio_drv_probe()
@@ -1374,6 +1403,7 @@ echo "Documentation     $build_docs"
 echo "uname -r          $uname_release"
 echo "NPTL support      $nptl"
 echo "vde support       $vde"
+echo "pcap net support  $pcap"
 echo "AIO support       $aio"
 echo "IO thread         $io_thread"
 echo "Install blobs     $blobs"
@@ -1587,6 +1617,11 @@ if test "$vde" = "yes" ; then
   echo "#define CONFIG_VDE 1" >> $config_h
   echo "VDE_LIBS=-lvdeplug" >> $config_mak
 fi
+if test "$pcap" = "yes" ; then
+  echo "CONFIG_PCAP=yes" >> $config_mak
+  echo "#define CONFIG_PCAP 1" >> $config_h
+  echo "PCAP_LIBS="$PCAP_LIBS >> $config_mak
+fi
 for card in $audio_card_list; do
     def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
     echo "$def=yes" >> $config_mak
diff --git a/net.c b/net.c
index 2d24a7c..e4b3740 100644
--- a/net.c
+++ b/net.c
@@ -93,6 +93,13 @@
 #endif
 #endif
 
+#if defined(CONFIG_PCAP)
+#include <pcap.h>
+#ifdef _WIN32
+#include <remote-ext.h>
+#endif /* _WIN32 */
+#endif /* CONFIG_PCAP */
+
 #if defined(__OpenBSD__)
 #include <util.h>
 #endif
@@ -1176,6 +1183,268 @@ static int net_tap_init(VLANState *vlan, const char *model,
 
 #endif /* !_WIN32 */
 
+#if defined(CONFIG_PCAP)
+
+#ifdef _WIN32
+#define ADAPTER_KEY             "SYSTEM\\CurrentControlSet\\Control\\Class" \
+                                "\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network" \
+                                "\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#endif
+
+typedef struct PCAPState {
+    VLANClientState *vc;
+    pcap_t *handle;
+} PCAPState;
+
+static void pcap_receive(void *opaque, const uint8_t *buf, int size)
+{
+    PCAPState *s = (PCAPState *)opaque;
+
+    pcap_sendpacket(s->handle, (u_char*)buf, size);
+}
+
+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata)
+{
+    VLANClientState *vc = (VLANClientState *)user;
+
+    qemu_send_packet(vc, pdata, phdr->len);
+}
+
+static void pcap_send(void *opaque)
+{
+    PCAPState *s = (PCAPState *)opaque;
+
+    pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_char *)s->vc);
+}
+
+static void pcap_cleanup(VLANClientState *vc)
+{
+    PCAPState *s = vc->opaque;
+
+#ifndef _WIN32
+    int fd;
+
+    if ((fd = pcap_get_selectable_fd(s->handle)) < 0) {
+        fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n");
+	return;
+    }
+    qemu_set_fd_handler(fd, NULL, NULL, NULL);
+#else
+    HANDLE hand;
+
+    hand = pcap_getevent(s->handle);
+    if ((hand = pcap_getevent(s->handle)) == 0) {
+        fprintf(stderr, "qemu: pcap_getevent failed\n");
+        return;
+    }
+    qemu_del_wait_object(hand, NULL, NULL);
+#endif
+
+    pcap_close(s->handle);
+    qemu_free(s);
+}
+
+#ifdef _WIN32
+static int get_windows_device_name(char *name, int name_size,
+                                   char *actual_name, int actual_name_size)
+{
+    const char name_string[] = "Name";
+    char connection_string[256];
+    HKEY connection_key;
+    char name_data[256];
+    DWORD name_type;
+    LONG status;
+    DWORD len;
+
+    snprintf(connection_string, sizeof(connection_string),
+             "%s\\%s\\Connection", NETWORK_CONNECTIONS_KEY, name);
+
+    status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ,
+                          &connection_key);
+
+    if (status == ERROR_SUCCESS) {
+        len = sizeof(name_data);
+        status = RegQueryValueEx(connection_key, name_string, NULL,
+                                 &name_type, (PBYTE)name_data, &len);
+        if (status != ERROR_SUCCESS || name_type != REG_SZ) {
+            fprintf(stderr, "qemu: error opening registry key: %s\\%s\\%s",
+                    NETWORK_CONNECTIONS_KEY, connection_string, name_string);
+            return -1;
+        } else {
+            snprintf(actual_name, actual_name_size, "%s", name_data);
+        }
+
+        RegCloseKey(connection_key);
+
+    }
+    return 0;
+}
+#endif
+
+static int net_pcap_init(VLANState *vlan, const char *model, const char *name,
+                         char *ifname)
+{
+    PCAPState *s;
+    char errbuf[PCAP_ERRBUF_SIZE];
+    int fd;
+
+    s = qemu_mallocz(sizeof(PCAPState));
+    if (!s)
+        return -1;
+
+#ifndef _WIN32
+    if (!ifname && !(ifname = pcap_lookupdev(errbuf))) {
+        fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf);
+        goto fail;
+    }
+
+    s->handle = (void*)pcap_open_live(ifname, 65535, 1, 0, errbuf);
+#else
+    {
+        pcap_if_t *found_device = NULL;
+        pcap_if_t *alldevs = NULL;
+        pcap_if_t *device;
+        char errbuf[PCAP_ERRBUF_SIZE];
+        char connection_name_data[256];
+        char name_data[256];
+        char *code_strt;
+
+        /* Retrieve the device list */
+        if (pcap_findalldevs(&alldevs, errbuf) == -1) {
+            fprintf(stderr, "qemu: error in pcap_findalldevs: %s\n", errbuf);
+            goto fail;
+        }
+
+        device = alldevs;
+
+        while (device) {
+            memset(connection_name_data, 0, sizeof(connection_name_data));
+
+            code_strt = strchr(device->name, '{');
+            if (code_strt) {
+                snprintf(name_data, sizeof(name_data), "%s", code_strt);
+
+                get_windows_device_name(name_data, sizeof(name_data),
+                                        connection_name_data,
+                                        sizeof(connection_name_data));
+            }
+
+            if (*connection_name_data != 0) {
+                if (ifname) {
+                    /*
+                     * If an exact match exists, over-ride any found device,
+                     * setting exact match device to it.
+                     */
+                    if (strcmp(connection_name_data, ifname) == 0) {
+                        found_device = device;
+                        break;
+                    }
+
+                    /*
+                     * Do a partial search, if successful, set this device as
+                     * the found one, but continue looping through devices.
+                     */
+                    if (found_device && strstr(connection_name_data, ifname))
+                        found_device = device;
+                } else {
+                    /*
+                     * If no name specified and network has an address,
+                     * autoselect the first device.
+                     */
+                    if (device->addresses) {
+                        found_device = device;
+                        break;
+                    }
+                }
+            }
+
+            device = device->next;
+        }
+
+        if (!found_device)
+            goto fail;
+
+        ifname = found_device->name;
+
+        s->handle = pcap_open(ifname, 65536,
+                              PCAP_OPENFLAG_PROMISCUOUS |
+                              PCAP_OPENFLAG_NOCAPTURE_LOCAL |
+                              PCAP_OPENFLAG_MAX_RESPONSIVENESS,
+                              0, NULL, errbuf);
+    }
+#endif
+    if (!s->handle) {
+        fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
+        goto fail;
+    }
+
+    if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
+        fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf);
+        goto fail;
+    }
+
+#ifndef _WIN32
+#if defined(BIOCSHDRCMPLT)
+    /*
+     * Tell the kernel that the header is fully-formed when it gets it.
+     * This is required in order to fake the src address.
+     */
+    {
+        unsigned int one = 1;
+        ioctl(pcap_fileno(s->handle), BIOCSHDRCMPLT, &one);
+    }
+#endif /* BIOCSHDRCMPLT */
+
+#if defined(BIOCIMMEDIATE)
+    /*
+     * Tell the kernel that the packet has to be processed immediately.
+     */
+    {
+        unsigned int one = 1;
+        ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one);
+    }
+#endif /* BIOCIMMEDIATE */
+#endif
+
+    s->vc = qemu_new_vlan_client(vlan, model, name, pcap_receive, NULL, pcap_cleanup, s);
+    snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector");
+#ifndef _WIN32
+    if ((fd = pcap_get_selectable_fd(s->handle)) < 0) {
+        fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n");
+        goto fail;
+    }
+    qemu_set_fd_handler(fd, pcap_send, NULL, s);
+#else
+    {
+        HANDLE hand;
+
+        hand = pcap_getevent(s->handle);
+        if ((hand = pcap_getevent(s->handle)) == 0) {
+            fprintf(stderr, "qemu: pcap_getevent failed\n");
+            goto fail;
+        }
+        if (qemu_add_wait_object(hand, pcap_send, s) < 0) {
+            fprintf(stderr,
+                    "qemu: qemu_add_wait_object for pcap_send failed\n");
+            goto fail;
+        }
+    }
+#endif
+
+    return 0;
+
+fail:
+    if (s) {
+        if (s->handle)
+            pcap_close(s->handle);
+        qemu_free(s);
+    }
+
+    return -1;
+}
+#endif /* CONFIG_PCAP */
+
 #if defined(CONFIG_VDE)
 typedef struct VDEState {
     VLANClientState *vc;
@@ -2025,6 +2294,16 @@ int net_client_init(const char *device, const char *p)
         }
     } else
 #endif
+#ifdef CONFIG_PCAP
+    if (!strcmp(device, "pcap")) {
+        char ifname[64];
+        vlan->nb_host_devs++;
+        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {
+            ifname[0] = '\0';
+        }
+        ret = net_pcap_init(vlan, device, name, ifname);
+    } else
+#endif
     if (!strcmp(device, "socket")) {
         if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {
             int fd;
diff --git a/qemu-options.hx b/qemu-options.hx
index 87af798..9d24473 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -753,6 +753,10 @@ DEF("net", HAS_ARG, QEMU_OPTION_net, \
     "                Use group 'groupname' and mode 'octalmode' to change default\n"
     "                ownership and permissions for communication port.\n"
 #endif
+#ifdef CONFIG_PCAP
+    "-net pcap[,vlan=n][,name=str][,ifname=name]\n"
+    "                connect the host network interface to VLAN 'n' using PCAP\n"
+#endif
     "-net dump[,vlan=n][,file=f][,len=n]\n"
     "                dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
     "-net none       use it alone to have zero network devices; if no -net option\n"
@@ -875,6 +879,18 @@ vde_switch -F -sock /tmp/myswitch
 qemu linux.img -net nic -net vde,sock=/tmp/myswitch
 @end example
 
+@item -net pcap[,vlan=@var{n}][,name=@var{name}][,ifname=@var{name}]
+Connect VLAN @var{n} to the host network interface @var{name} using the pcap
+interface. This will switch the host's interface to promisc mode, enabling the
+guest to receive all packets on this VLAN that the host sees, too. The pcap
+host interface is a handy alternative to a TAP interface, attached via a
+bridge to a host network interface.
+
+Example:
+@example
+qemu linux.img -net nic -net pcap,ifname=eth0
+@end example
+
 @item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
 Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu-vlan0.pcap} by default).
 At most @var{len} bytes (64k by default) per packet are stored. The file format is
