File qemu-svn-pcap.patch of Package qemu

Index: Makefile.target
================================================================================
--- Makefile.target
+++ Makefile.target
@@ -644,6 +644,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
@@ -92,6 +92,7 @@
 gdbstub="yes"
 slirp="yes"
 vde="yes"
+pcap="yes"
 fmod_lib=""
 fmod_inc=""
 oss_lib=""
@@ -296,6 +297,8 @@
   ;;
   --disable-vde) vde="no"
   ;;
+  --disable-pcap) pcap="no"
+  ;;
   --disable-kqemu) kqemu="no"
   ;;
   --disable-brlapi) brlapi="no"
@@ -1204,6 +1207,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
--- vl.c
+++ vl.c
@@ -106,6 +106,10 @@
 
 #include "qemu_socket.h"
 
+#if defined(CONFIG_PCAP)
+#include <pcap.h>
+#endif
+
 #if defined(CONFIG_SLIRP)
 #include "libslirp.h"
 #endif
@@ -4305,6 +4309,104 @@
 
 #endif /* CONFIG_SLIRP */
 
+#if defined(CONFIG_PCAP)
+
+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, 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, 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 {
@@ -5235,6 +5337,15 @@
         ret = net_slirp_init(vlan);
     } else
 #endif
+#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, NULL);
+	else
+	    ret = net_pcap_init(vlan, ifname);
+    } else
+#endif
 #ifdef _WIN32
     if (!strcmp(device, "tap")) {
         char ifname[64];
@@ -8108,6 +8219,10 @@
            "                connect the user mode network stack to VLAN 'n' and send\n"
            "                hostname 'host' to DHCP clients\n"
 #endif
+#ifdef CONFIG_PCAP
+           "-net pcap[,vlan=n][,ifname=name]\n"
+           "                connect the host network interface using PCAP to VLAN 'n'\n"
+#endif
 #ifdef _WIN32
            "-net tap[,vlan=n],ifname=name\n"
            "                connect the host TAP network interface to VLAN 'n'\n"
openSUSE Build Service is sponsored by