@@ -0,0 +1,183 @@
+Index: Makefile.target
+================================================================================
+--- Makefile.target
++++ Makefile.target
+@@ -690,6 +690,9 @@
+ ifdef CONFIG_SLIRP
+ CPPFLAGS+=-I$(SRC_PATH)/slirp
+ endif
++ifdef CONFIG_PCAP
++LIBS+=-lpcap
++endif
+
+ LIBS+=$(AIOLIBS)
+ # specific flags are needed for non soft mmu emulator
+--- configure
++++ configure
+@@ -160,6 +160,7 @@
+ gdbstub="yes"
+ slirp="yes"
+ vde="yes"
++pcap="yes"
+ fmod_lib=""
+ fmod_inc=""
+ oss_lib=""
+@@ -392,6 +393,8 @@
+ ;;
+ --disable-vde) vde="no"
+ ;;
++ --disable-pcap) pcap="no"
++ ;;
+ --disable-kqemu) kqemu="no"
+ ;;
+ --disable-brlapi) brlapi="no"
+@@ -1353,6 +1356,10 @@
+ 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
++fi
+ for card in $audio_card_list; do
+ def=CONFIG_`echo $card | tr '[:lower:]' '[:upper:]'`
+ echo "$def=yes" >> $config_mak
+--- net.c
++++ net.c
+@@ -689,6 +689,104 @@
+
+ #endif /* CONFIG_SLIRP */
+
++#if defined(CONFIG_PCAP)
++#include <pcap.h>
++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 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;
++
++ if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) {
++ fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf);
++ goto fail;
++ }
++
++ /* Attempt to connect device. */
++ s->handle = (void*)pcap_open_live(ifname, 65535, 1, 0, errbuf);
++ if (!s->handle) {
++ fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
++ goto fail;
++ }
++
++ /* Check non-blocking mode. */
++ if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
++ fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf);
++ goto fail;
++ }
++
++#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 */
++
++ s->vc = qemu_new_vlan_client(vlan, model, name, pcap_receive, NULL, s);
++ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector");
++ 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);
++
++ return 0;
++
++fail:
++ if (s) {
++ if (s->handle)
++ pcap_close(s->handle);
++ qemu_free(s);
++ }
++
++ return -1;
++}
++#endif /* CONFIG_PCAP */
++
+ #if !defined(_WIN32)
+
+ typedef struct TAPState {
+@@ -1656,7 +1754,17 @@
+ }
+ vlan->nb_host_devs++;
+ ret = net_slirp_init(vlan, device, name);
+- } else if (!strcmp(device, "channel")) {
++ } else
++#ifdef CONFIG_PCAP
++ if (!strcmp(device, "pcap")) {
++ char ifname[64];
++ if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0)
++ ret = net_pcap_init(vlan, device, name, NULL);
++ else
++ ret = net_pcap_init(vlan, device, name, ifname);
++ } else
++#endif
++ if (!strcmp(device, "channel")) {
+ long port;
+ char name[20], *devname;
+ struct VMChannel *vmc;
+--- vl.c
++++ vl.c
+@@ -3990,6 +3994,10 @@
+ " use '[down]script=no' to disable script execution;\n"
+ " use 'fd=h' to connect to an already opened TAP interface\n"
+ #endif
++#ifdef CONFIG_PCAP
++ "-net pcap[,vlan=n][,ifname=name]\n"
++ " connect the host network interface using PCAP to VLAN 'n'\n"
++#endif
+ "-net socket[,vlan=n][,name=str][,fd=h][,listen=[host]:port][,connect=host:port]\n"
+ " connect the vlan 'n' to another VLAN using a socket connection\n"
+ "-net socket[,vlan=n][,name=str][,fd=h][,mcast=maddr:port]\n"
|