qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] Add pcap-based host network bridge
@ 2009-03-18  9:33 Jan Kiszka
  2009-03-22 20:38 ` Robert Riebisch
                   ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Jan Kiszka @ 2009-03-18  9:33 UTC (permalink / raw)
  To: qemu-devel

This introduces bridged networking via pcap. Both Unix and Windows
platforms are supported.

While tap-based bridging provides basically the same support pcap does,
the latter is often more handy to set up. Under Linux, it doesn't
require to configure a bridge and it is able to bypass the ebtables if
this is desired. Also under Windows, the bridge setup can be lengthy
procedure compared to using the pcap interface.

Signed-off-by: Klaus Wenninger <klaus.wenninger@siemens-enterprise.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

 Makefile.target |    2 
 configure       |   35 ++++++++
 net.c           |  252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 qemu-doc.texi   |   14 +++
 vl.c            |    4 +
 5 files changed, 305 insertions(+), 2 deletions(-)

diff --git a/Makefile.target b/Makefile.target
index 47a4ada..395fb15 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -729,7 +729,7 @@ LDFLAGS+=-p
 main.o: CFLAGS+=-p
 endif
 
-$(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS)
+$(QEMU_PROG): LIBS += $(SDL_LIBS) $(COCOA_LIBS) $(CURSES_LIBS) $(BRLAPI_LIBS) $(VDE_LIBS) $(PCAP_LIBS)
 
 $(QEMU_PROG): $(OBJS) ../libqemu_common.a libqemu.a
 	$(LINK)
diff --git a/configure b/configure
index 8899030..7d77f32 100755
--- a/configure
+++ b/configure
@@ -160,6 +160,7 @@ EXESUF=""
 gdbstub="yes"
 slirp="yes"
 vde="yes"
+pcap="yes"
 fmod_lib=""
 fmod_inc=""
 oss_lib=""
@@ -404,6 +405,8 @@ for opt do
   ;;
   --disable-vde) vde="no"
   ;;
+  --disable-pcap) pcap="no"
+  ;;
   --disable-kqemu) kqemu="no"
   ;;
   --disable-brlapi) brlapi="no"
@@ -576,6 +579,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-aio            disable AIO support"
 echo "  --disable-blobs          disable installing provided firmware blobs"
 echo "  --kerneldir=PATH         look for kernel includes in PATH"
@@ -906,6 +910,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()
@@ -1209,6 +1238,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 "Install blobs     $blobs"
 echo "KVM support       $kvm"
@@ -1412,6 +1442,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 c853daf..3cf372d 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
@@ -1033,6 +1040,241 @@ 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);
+}
+
+#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, 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;
@@ -1723,6 +1965,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-doc.texi b/qemu-doc.texi
index 8efc943..faed31a 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -770,6 +770,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 none
 Indicate that no network devices should be configured. It is used to
 override the default configuration (@option{-net nic -net user}) which
@@ -3114,7 +3126,7 @@ MV88W8xx8 Ethernet controller
 @item
 MV88W8618 audio controller, WM8750 CODEC and mixer
 @item
-128??64 display with brightness control
+128?64 display with brightness control
 @item
 2 buttons, 2 navigation wheels with button function
 @end itemize
diff --git a/vl.c b/vl.c
index 41012a8..4e6e7ee 100644
--- a/vl.c
+++ b/vl.c
@@ -4018,6 +4018,10 @@ static void help(int exitcode)
            "                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][,name=str][,ifname=name]\n"
+           "                connect the host network interface to VLAN 'n' using PCAP\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"

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCH] Add pcap-based host network bridge
  2009-03-18  9:33 [Qemu-devel] [PATCH] Add pcap-based host network bridge Jan Kiszka
@ 2009-03-22 20:38 ` Robert Riebisch
  2009-03-22 21:38 ` [Qemu-devel] " Sebastian Herbszt
  2009-03-23  2:23 ` [Qemu-devel] " Anthony Liguori
  2 siblings, 0 replies; 23+ messages in thread
From: Robert Riebisch @ 2009-03-22 20:38 UTC (permalink / raw)
  To: qemu-devel

Jan Kiszka wrote:

> This introduces bridged networking via pcap. Both Unix and Windows
> platforms are supported.

Tested on host Windows 2000, guest DOS: works nice :-) This is great,
because Windows 2000 doesn't support built-in bridging like in XP.

Robert Riebisch
-- 
BTTR Software
http://www.bttr-software.de/

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-03-18  9:33 [Qemu-devel] [PATCH] Add pcap-based host network bridge Jan Kiszka
  2009-03-22 20:38 ` Robert Riebisch
@ 2009-03-22 21:38 ` Sebastian Herbszt
  2009-03-24 17:21   ` Jan Kiszka
  2009-03-23  2:23 ` [Qemu-devel] " Anthony Liguori
  2 siblings, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-03-22 21:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jung-uk Kim

Jan Kiszka wrote:
> This introduces bridged networking via pcap. Both Unix and Windows
> platforms are supported.
> 
> While tap-based bridging provides basically the same support pcap does,
> the latter is often more handy to set up. Under Linux, it doesn't
> require to configure a bridge and it is able to bypass the ebtables if
> this is desired. Also under Windows, the bridge setup can be lengthy
> procedure compared to using the pcap interface.

This looks like the pcap approach by Jung-uk Kim [1]. It was reported that
guest <-> host communication didn't work on Linux [2]. Is this also true for
this patch?

[1] http://article.gmane.org/gmane.comp.emulators.qemu/27304
[2] http://article.gmane.org/gmane.comp.emulators.qemu/27553

> Signed-off-by: Klaus Wenninger <klaus.wenninger@siemens-enterprise.com>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
> ---
> 
> Makefile.target |    2 
> configure       |   35 ++++++++
> net.c           |  252 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
> qemu-doc.texi   |   14 +++
> vl.c            |    4 +
> 5 files changed, 305 insertions(+), 2 deletions(-)
> 

[snip]

> diff --git a/net.c b/net.c
> index c853daf..3cf372d 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
> @@ -1033,6 +1040,241 @@ 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

ADAPTER_KEY doesn't seem to be used.

- Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] [PATCH] Add pcap-based host network bridge
  2009-03-18  9:33 [Qemu-devel] [PATCH] Add pcap-based host network bridge Jan Kiszka
  2009-03-22 20:38 ` Robert Riebisch
  2009-03-22 21:38 ` [Qemu-devel] " Sebastian Herbszt
@ 2009-03-23  2:23 ` Anthony Liguori
  2009-03-24 17:28   ` [Qemu-devel] " Jan Kiszka
  2 siblings, 1 reply; 23+ messages in thread
From: Anthony Liguori @ 2009-03-23  2:23 UTC (permalink / raw)
  To: qemu-devel

Jan Kiszka wrote:
> This introduces bridged networking via pcap. Both Unix and Windows
> platforms are supported.
>
> While tap-based bridging provides basically the same support pcap does,
> the latter is often more handy to set up. Under Linux, it doesn't
> require to configure a bridge and it is able to bypass the ebtables if
> this is desired. Also under Windows, the bridge setup can be lengthy
> procedure compared to using the pcap interface.
>
> Signed-off-by: Klaus Wenninger <klaus.wenninger@siemens-enterprise.com>
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>   

The previous version of this had a fundamental flaw wrt guest->host 
communication on Linux.  My understanding was that this was an intrinsic 
limitation of pcap.

That's a blocker IMHO because it will invariably lead to many folks 
asking why ping to the host doesn't work (just like slirp).  Since it 
still requires root privileges, I don't think it improves a lot on tap.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-03-22 21:38 ` [Qemu-devel] " Sebastian Herbszt
@ 2009-03-24 17:21   ` Jan Kiszka
  0 siblings, 0 replies; 23+ messages in thread
From: Jan Kiszka @ 2009-03-24 17:21 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jung-uk Kim

Sebastian Herbszt wrote:
> Jan Kiszka wrote:
>> This introduces bridged networking via pcap. Both Unix and Windows
>> platforms are supported.
>>
>> While tap-based bridging provides basically the same support pcap does,
>> the latter is often more handy to set up. Under Linux, it doesn't
>> require to configure a bridge and it is able to bypass the ebtables if
>> this is desired. Also under Windows, the bridge setup can be lengthy
>> procedure compared to using the pcap interface.
> 
> This looks like the pcap approach by Jung-uk Kim [1]. It was reported that
> guest <-> host communication didn't work on Linux [2]. Is this also true
> for
> this patch?

Yes, it is, see my reply to Anthony.

> 
> [1] http://article.gmane.org/gmane.comp.emulators.qemu/27304
> [2] http://article.gmane.org/gmane.comp.emulators.qemu/27553
> 
>> Signed-off-by: Klaus Wenninger <klaus.wenninger@siemens-enterprise.com>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>> ---
>>
>> Makefile.target |    2 configure       |   35 ++++++++
>> net.c           |  252
>> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>> qemu-doc.texi   |   14 +++
>> vl.c            |    4 +
>> 5 files changed, 305 insertions(+), 2 deletions(-)
>>
> 
> [snip]
> 
>> diff --git a/net.c b/net.c
>> index c853daf..3cf372d 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
>> @@ -1033,6 +1040,241 @@ 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
> 
> ADAPTER_KEY doesn't seem to be used.
> 

Thanks, will drop it when posting an update.

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-03-23  2:23 ` [Qemu-devel] " Anthony Liguori
@ 2009-03-24 17:28   ` Jan Kiszka
  2009-03-28 17:26     ` Anthony Liguori
  0 siblings, 1 reply; 23+ messages in thread
From: Jan Kiszka @ 2009-03-24 17:28 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> Jan Kiszka wrote:
>> This introduces bridged networking via pcap. Both Unix and Windows
>> platforms are supported.
>>
>> While tap-based bridging provides basically the same support pcap does,
>> the latter is often more handy to set up. Under Linux, it doesn't
>> require to configure a bridge and it is able to bypass the ebtables if
>> this is desired. Also under Windows, the bridge setup can be lengthy
>> procedure compared to using the pcap interface.
>>
>> Signed-off-by: Klaus Wenninger <klaus.wenninger@siemens-enterprise.com>
>> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
>>   
> 
> The previous version of this had a fundamental flaw wrt guest->host
> communication on Linux.  My understanding was that this was an intrinsic
> limitation of pcap.

To my understanding too. We will try to look closer at this, maybe there
are smarter alternatives at least on some platforms (PF_PACKET under
Linux...?).

Klaus explained to me that there is some switch in winpcap to support
this, but it caused troubles due to weird packet loops. I don't have a
Windows platform to test, but I will see if we can clarify this in some
other way.

> 
> That's a blocker IMHO because it will invariably lead to many folks
> asking why ping to the host doesn't work (just like slirp).  Since it
> still requires root privileges, I don't think it improves a lot on tap.
> 

Well, in case we do not find a workaround for host<->guest
communication, would the patch remain unacceptable even with proper,
prominent documentation of this shortcoming?

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-03-24 17:28   ` [Qemu-devel] " Jan Kiszka
@ 2009-03-28 17:26     ` Anthony Liguori
  2009-05-11 21:30       ` [Qemu-devel] " Sebastian Herbszt
  0 siblings, 1 reply; 23+ messages in thread
From: Anthony Liguori @ 2009-03-28 17:26 UTC (permalink / raw)
  To: qemu-devel

Jan Kiszka wrote:
> To my understanding too. We will try to look closer at this, maybe there
> are smarter alternatives at least on some platforms (PF_PACKET under
> Linux...?).
>
> Klaus explained to me that there is some switch in winpcap to support
> this, but it caused troubles due to weird packet loops. I don't have a
> Windows platform to test, but I will see if we can clarify this in some
> other way.
>
>   
>> That's a blocker IMHO because it will invariably lead to many folks
>> asking why ping to the host doesn't work (just like slirp).  Since it
>> still requires root privileges, I don't think it improves a lot on tap.
>>
>>     
>
> Well, in case we do not find a workaround for host<->guest
> communication, would the patch remain unacceptable even with proper,
> prominent documentation of this shortcoming?
>   

What's the use-case you're trying to address?  Who do you expect to use 
this functionality?

Setting up bridging isn't really that bad on Linux.  Is this primarily 
targeted at Windows?  libpcap requires a kernel driver on Windows so I 
don't know that I believe it's a great general solution for Windows either.

Regards,

Anthony Liguori

> Jan
>
>   

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: Re: [PATCH] Add pcap-based host network bridge
  2009-03-28 17:26     ` Anthony Liguori
@ 2009-05-11 21:30       ` Sebastian Herbszt
  2009-05-12  8:23         ` [Qemu-devel] " Jan Kiszka
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-05-11 21:30 UTC (permalink / raw)
  To: qemu-devel

Anthony Liguori wrote:
> Jan Kiszka wrote:
>> Well, in case we do not find a workaround for host<->guest
>> communication, would the patch remain unacceptable even with proper,
>> prominent documentation of this shortcoming?
>>   
> 
> What's the use-case you're trying to address?  Who do you expect to use 
> this functionality?
> 
> Setting up bridging isn't really that bad on Linux.  Is this primarily 
> targeted at Windows?  libpcap requires a kernel driver on Windows so I 
> don't know that I believe it's a great general solution for Windows either.

I would really like to see pcap support in mainline (even as a windows only
feature). Qemu networking with pcap is trivial on windows. No need to
configure tap bridges, but just specify "ifname" and there you go.

- Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-11 21:30       ` [Qemu-devel] " Sebastian Herbszt
@ 2009-05-12  8:23         ` Jan Kiszka
  2009-05-12 15:48           ` Lennart Sorensen
  2009-05-12 21:17           ` Sebastian Herbszt
  0 siblings, 2 replies; 23+ messages in thread
From: Jan Kiszka @ 2009-05-12  8:23 UTC (permalink / raw)
  To: Sebastian Herbszt; +Cc: qemu-devel

Sebastian Herbszt wrote:
> Anthony Liguori wrote:
>> Jan Kiszka wrote:
>>> Well, in case we do not find a workaround for host<->guest
>>> communication, would the patch remain unacceptable even with proper,
>>> prominent documentation of this shortcoming?
>>>   
>>
>> What's the use-case you're trying to address?  Who do you expect to
>> use this functionality?
>>
>> Setting up bridging isn't really that bad on Linux.  Is this primarily
>> targeted at Windows?  libpcap requires a kernel driver on Windows so I
>> don't know that I believe it's a great general solution for Windows
>> either.
> 
> I would really like to see pcap support in mainline (even as a windows only
> feature). Qemu networking with pcap is trivial on windows. No need to
> configure tap bridges, but just specify "ifname" and there you go.

We basically dropped the idea as it turned out that - at least under
Linux - there is no host<->guest link realizable with reasonable effort.

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12  8:23         ` [Qemu-devel] " Jan Kiszka
@ 2009-05-12 15:48           ` Lennart Sorensen
  2009-05-12 16:34             ` Jan Kiszka
  2009-05-12 21:45             ` Paul Brook
  2009-05-12 21:17           ` Sebastian Herbszt
  1 sibling, 2 replies; 23+ messages in thread
From: Lennart Sorensen @ 2009-05-12 15:48 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: qemu-devel, Sebastian Herbszt

On Tue, May 12, 2009 at 10:23:43AM +0200, Jan Kiszka wrote:
> We basically dropped the idea as it turned out that - at least under
> Linux - there is no host<->guest link realizable with reasonable effort.

Has anyone ever looked at how vmware's vmnet does it?

-- 
Len Sorensen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12 15:48           ` Lennart Sorensen
@ 2009-05-12 16:34             ` Jan Kiszka
  2009-05-12 17:09               ` Lennart Sorensen
  2009-05-12 21:45             ` Paul Brook
  1 sibling, 1 reply; 23+ messages in thread
From: Jan Kiszka @ 2009-05-12 16:34 UTC (permalink / raw)
  To: Lennart Sorensen; +Cc: qemu-devel, Sebastian Herbszt

Lennart Sorensen wrote:
> On Tue, May 12, 2009 at 10:23:43AM +0200, Jan Kiszka wrote:
>> We basically dropped the idea as it turned out that - at least under
>> Linux - there is no host<->guest link realizable with reasonable effort.
> 
> Has anyone ever looked at how vmware's vmnet does it?

Whatever they do (I bet it's nothing trivial): Everything that
complicates the pcap-based approach beyond a certain level (roughly the
one that is required for tap-based bridges) makes it unattractive. There
are alternatives (except for ancient Win2k IIRC), pcap just appeared to
be a cheap shortcut. But that turned out to be not true.

Jan

-- 
Siemens AG, Corporate Technology, CT SE 2
Corporate Competence Center Embedded Linux

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12 16:34             ` Jan Kiszka
@ 2009-05-12 17:09               ` Lennart Sorensen
  0 siblings, 0 replies; 23+ messages in thread
From: Lennart Sorensen @ 2009-05-12 17:09 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: qemu-devel, Sebastian Herbszt

On Tue, May 12, 2009 at 06:34:04PM +0200, Jan Kiszka wrote:
> Lennart Sorensen wrote:
> > On Tue, May 12, 2009 at 10:23:43AM +0200, Jan Kiszka wrote:
> >> We basically dropped the idea as it turned out that - at least under
> >> Linux - there is no host<->guest link realizable with reasonable effort.
> > 
> > Has anyone ever looked at how vmware's vmnet does it?
> 
> Whatever they do (I bet it's nothing trivial): Everything that
> complicates the pcap-based approach beyond a certain level (roughly the
> one that is required for tap-based bridges) makes it unattractive. There
> are alternatives (except for ancient Win2k IIRC), pcap just appeared to
> be a cheap shortcut. But that turned out to be not true.

Not sure.  I just know with the vmware approache, the guest can be
bridged to the network in a way that allows the guest to talk to the
host as well as anything else on the external network, which to me is
by far the nicest setup.  I still haven't clued in to how to make vmware
talk to the host system and allow incoming connections on a real IP yet.
Guest to host works through 10.2.2.2 or something like that, but nothing
else ever has for me.  Maybe I just haven't managed to make sense of the
-net documentation to figure out which of the very many options would
do what I want.

Vmware's vmnet does look like a lot of code (somewhere near 400k) and
has some binary only code included, so who knows.  Certainly involves
bridging though.

-- 
Len Sorensen

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12  8:23         ` [Qemu-devel] " Jan Kiszka
  2009-05-12 15:48           ` Lennart Sorensen
@ 2009-05-12 21:17           ` Sebastian Herbszt
  2009-05-20 17:43             ` Consul
  1 sibling, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-05-12 21:17 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: qemu-devel

Jan Kiszka wrote:
> Sebastian Herbszt wrote:
>> Anthony Liguori wrote:
>>> Jan Kiszka wrote:
>>>> Well, in case we do not find a workaround for host<->guest
>>>> communication, would the patch remain unacceptable even with proper,
>>>> prominent documentation of this shortcoming?
>>>>   
>>>
>>> What's the use-case you're trying to address?  Who do you expect to
>>> use this functionality?
>>>
>>> Setting up bridging isn't really that bad on Linux.  Is this primarily
>>> targeted at Windows?  libpcap requires a kernel driver on Windows so I
>>> don't know that I believe it's a great general solution for Windows
>>> either.
>> 
>> I would really like to see pcap support in mainline (even as a windows only
>> feature). Qemu networking with pcap is trivial on windows. No need to
>> configure tap bridges, but just specify "ifname" and there you go.
> 
> We basically dropped the idea as it turned out that - at least under
> Linux - there is no host<->guest link realizable with reasonable effort.

That's really too bad. pcap-based networking works flawless on windows.
Guest <-> host and guest <-> world communication works just fine.
According to the previous threads about pcap-based networking it also
should work fine on FreeBSD.

- Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12 15:48           ` Lennart Sorensen
  2009-05-12 16:34             ` Jan Kiszka
@ 2009-05-12 21:45             ` Paul Brook
  1 sibling, 0 replies; 23+ messages in thread
From: Paul Brook @ 2009-05-12 21:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Jan Kiszka, Sebastian Herbszt, Lennart Sorensen

On Tuesday 12 May 2009, Lennart Sorensen wrote:
> On Tue, May 12, 2009 at 10:23:43AM +0200, Jan Kiszka wrote:
> > We basically dropped the idea as it turned out that - at least under
> > Linux - there is no host<->guest link realizable with reasonable effort.
>
> Has anyone ever looked at how vmware's vmnet does it?

I haven't actually looked at it, but my understanding was it involves a kernel 
module that effectively duplicates the existing bridge functionality.

Paul

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-12 21:17           ` Sebastian Herbszt
@ 2009-05-20 17:43             ` Consul
  2009-05-28 20:50               ` Sebastian Herbszt
  0 siblings, 1 reply; 23+ messages in thread
From: Consul @ 2009-05-20 17:43 UTC (permalink / raw)
  To: qemu-devel

Sebastian Herbszt wrote:
> That's really too bad. pcap-based networking works flawless on windows.
> Guest <-> host and guest <-> world communication works just fine.
> According to the previous threads about pcap-based networking it also
> should work fine on FreeBSD.
> 

Maybe make it compile conditionally for Windows only? Would you consider such patch?
It would really be a valuable feature.

Alex.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-20 17:43             ` Consul
@ 2009-05-28 20:50               ` Sebastian Herbszt
  2009-05-28 21:52                 ` Consul
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-05-28 20:50 UTC (permalink / raw)
  To: Consul, qemu-devel

Consul wrote:
> Sebastian Herbszt wrote:
>> That's really too bad. pcap-based networking works flawless on windows.
>> Guest <-> host and guest <-> world communication works just fine.
>> According to the previous threads about pcap-based networking it also
>> should work fine on FreeBSD.
>> 
> 
> Maybe make it compile conditionally for Windows only? Would you consider such patch?
> It would really be a valuable feature.

I did rebase the patch against git master and it still seems to work. I can post it if there
is any interest.

- Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-28 20:50               ` Sebastian Herbszt
@ 2009-05-28 21:52                 ` Consul
  2009-06-06 17:13                   ` Sebastian Herbszt
  0 siblings, 1 reply; 23+ messages in thread
From: Consul @ 2009-05-28 21:52 UTC (permalink / raw)
  To: qemu-devel

Sebastian Herbszt wrote:
> Consul wrote:
>> Sebastian Herbszt wrote:
>>> That's really too bad. pcap-based networking works flawless on windows.
>>> Guest <-> host and guest <-> world communication works just fine.
>>> According to the previous threads about pcap-based networking it also
>>> should work fine on FreeBSD.
>>>
>>
>> Maybe make it compile conditionally for Windows only? Would you 
>> consider such patch?
>> It would really be a valuable feature.
> 
> I did rebase the patch against git master and it still seems to work. I 
> can post it if there
> is any interest.
> 
> - Sebastian
> 

Yes, please post. I also have it rebased in my tree and it still works great.
Easier to configure than TAP for sure. Maybe if we'll bug the list often
enough and loud enough, it finally gets through.

Alex.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-05-28 21:52                 ` Consul
@ 2009-06-06 17:13                   ` Sebastian Herbszt
  2009-06-06 18:40                     ` Alex
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-06-06 17:13 UTC (permalink / raw)
  To: Consul, qemu-devel

[-- Attachment #1: Type: text/plain, Size: 942 bytes --]

Consul wrote:
> Sebastian Herbszt wrote:
>> Consul wrote:
>>> Sebastian Herbszt wrote:
>>>> That's really too bad. pcap-based networking works flawless on windows.
>>>> Guest <-> host and guest <-> world communication works just fine.
>>>> According to the previous threads about pcap-based networking it also
>>>> should work fine on FreeBSD.
>>>>
>>>
>>> Maybe make it compile conditionally for Windows only? Would you 
>>> consider such patch?
>>> It would really be a valuable feature.
>> 
>> I did rebase the patch against git master and it still seems to work. I 
>> can post it if there
>> is any interest.
>> 
>> - Sebastian
>> 
> 
> Yes, please post.

Find jan-pcap-updated-qdev3.diff attached.

> I also have it rebased in my tree and it still works great.

Is your tree available somewhere?

> Easier to configure than TAP for sure. Maybe if we'll bug the list often
> enough and loud enough, it finally gets through.

- Sebastian

[-- Attachment #2: jan-pcap-updated-qdev3.diff --]
[-- Type: application/octet-stream, Size: 13707 bytes --]

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

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-06-06 17:13                   ` Sebastian Herbszt
@ 2009-06-06 18:40                     ` Alex
  2009-06-08 21:27                       ` Consul
  0 siblings, 1 reply; 23+ messages in thread
From: Alex @ 2009-06-06 18:40 UTC (permalink / raw)
  To: qemu-devel

"Sebastian Herbszt" <herbszt@gmx.de> wrote in message 
news:C0648AF8B9CD4DE5A37965D11776A215@FSCPC...

>
> Find jan-pcap-updated-qdev3.diff attached.
>

Thanks. I'll give it a shot next Monday.

>
> Is your tree available somewhere?
>

No, it's private.

Alex 

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-06-06 18:40                     ` Alex
@ 2009-06-08 21:27                       ` Consul
  2009-06-09 20:13                         ` Sebastian Herbszt
  0 siblings, 1 reply; 23+ messages in thread
From: Consul @ 2009-06-08 21:27 UTC (permalink / raw)
  To: qemu-devel

Alex wrote:
> "Sebastian Herbszt" <herbszt@gmx.de> wrote in message 
> news:C0648AF8B9CD4DE5A37965D11776A215@FSCPC...
> 
>> Find jan-pcap-updated-qdev3.diff attached.
>>
> 
> Thanks. I'll give it a shot next Monday.
> 
>> Is your tree available somewhere?
>>
> 
> No, it's private.
> 
> Alex 
> 

This small patch was needed to compile it. Otherwise it appears to work...
At least XP guest dot authenticated on the network ok.
The message box "Loading your personal settings..." appears to be sitting on
the screen forever, but this is probably unrelated to your pcap patch.

$ git diff
diff --git a/net.c b/net.c
index e4b3740..ff2cc14 100644
--- a/net.c
+++ b/net.c
@@ -94,10 +94,10 @@
  #endif

  #if defined(CONFIG_PCAP)
-#include <pcap.h>
  #ifdef _WIN32
-#include <remote-ext.h>
+#define HAVE_REMOTE
  #endif /* _WIN32 */
+#include <pcap.h>
  #endif /* CONFIG_PCAP */

  #if defined(__OpenBSD__)

^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-06-08 21:27                       ` Consul
@ 2009-06-09 20:13                         ` Sebastian Herbszt
  2009-06-09 21:49                           ` Consul
  0 siblings, 1 reply; 23+ messages in thread
From: Sebastian Herbszt @ 2009-06-09 20:13 UTC (permalink / raw)
  To: Consul, qemu-devel

Consul wrote:
> This small patch was needed to compile it. Otherwise it appears to work...

Odd. It compiles here fine. Can you post the error please?
Which wpdpack version are you using?

- Sebastian

> At least XP guest dot authenticated on the network ok.
> The message box "Loading your personal settings..." appears to be sitting on
> the screen forever, but this is probably unrelated to your pcap patch.
> 
> $ git diff
> diff --git a/net.c b/net.c
> index e4b3740..ff2cc14 100644
> --- a/net.c
> +++ b/net.c
> @@ -94,10 +94,10 @@
>  #endif
> 
>  #if defined(CONFIG_PCAP)
> -#include <pcap.h>
>  #ifdef _WIN32
> -#include <remote-ext.h>
> +#define HAVE_REMOTE
>  #endif /* _WIN32 */
> +#include <pcap.h>
>  #endif /* CONFIG_PCAP */
> 
>  #if defined(__OpenBSD__)
> 
> 
> 
>

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-06-09 20:13                         ` Sebastian Herbszt
@ 2009-06-09 21:49                           ` Consul
  2009-06-10 21:39                             ` Sebastian Herbszt
  0 siblings, 1 reply; 23+ messages in thread
From: Consul @ 2009-06-09 21:49 UTC (permalink / raw)
  To: qemu-devel

Sebastian Herbszt wrote:
> Consul wrote:
>> This small patch was needed to compile it. Otherwise it appears to 
>> work...
> 
> Odd. It compiles here fine. Can you post the error please?
> Which wpdpack version are you using?
> 

   CC    net.o
In file included from net.c:99:
c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/remote-ext.h:39:2: #error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
In file included from qemu-common.h:74,
                  from net.c:120:
osdep.h:56:1: warning: "inline" redefined
In file included from c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/pcap/pcap.h:41,
                  from c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/pcap.h:45,
                  from net.c:97:
c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/pcap-stdinc.h:66:1: warning: this is the location of the previous definition
net.c: In function `pcap_cleanup':
net.c:1236: warning: implicit declaration of function `pcap_getevent'
net.c:1236: warning: assignment makes pointer from integer without a cast
net.c:1237: warning: assignment makes pointer from integer without a cast
net.c: In function `net_pcap_init':
net.c:1236: warning: redundant redeclaration of 'pcap_getevent'
net.c:1236: warning: previous implicit declaration of 'pcap_getevent' was here
net.c:1422: warning: assignment makes pointer from integer without a cast
net.c:1423: warning: assignment makes pointer from integer without a cast

^ permalink raw reply	[flat|nested] 23+ messages in thread

* [Qemu-devel] Re: [PATCH] Add pcap-based host network bridge
  2009-06-09 21:49                           ` Consul
@ 2009-06-10 21:39                             ` Sebastian Herbszt
  0 siblings, 0 replies; 23+ messages in thread
From: Sebastian Herbszt @ 2009-06-10 21:39 UTC (permalink / raw)
  To: Consul, qemu-devel

Consul wrote:
> Sebastian Herbszt wrote:
>> Consul wrote:
>>> This small patch was needed to compile it. Otherwise it appears to work...
>>
>> Odd. It compiles here fine. Can you post the error please?
>> Which wpdpack version are you using?
>>
>
>   CC    net.o
> In file included from net.c:99:
> c:/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/remote-ext.h:39:2: #error Please do not include this file 
> directly. Just define HAVE_REMOTE and then include pcap.h

Looks like this error is introduced by wpdpack 4.1 beta. Version 4.0, which i am using, doesn't include it. Thanks for 
the patch.

- Sebastian

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2009-06-10 21:41 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-03-18  9:33 [Qemu-devel] [PATCH] Add pcap-based host network bridge Jan Kiszka
2009-03-22 20:38 ` Robert Riebisch
2009-03-22 21:38 ` [Qemu-devel] " Sebastian Herbszt
2009-03-24 17:21   ` Jan Kiszka
2009-03-23  2:23 ` [Qemu-devel] " Anthony Liguori
2009-03-24 17:28   ` [Qemu-devel] " Jan Kiszka
2009-03-28 17:26     ` Anthony Liguori
2009-05-11 21:30       ` [Qemu-devel] " Sebastian Herbszt
2009-05-12  8:23         ` [Qemu-devel] " Jan Kiszka
2009-05-12 15:48           ` Lennart Sorensen
2009-05-12 16:34             ` Jan Kiszka
2009-05-12 17:09               ` Lennart Sorensen
2009-05-12 21:45             ` Paul Brook
2009-05-12 21:17           ` Sebastian Herbszt
2009-05-20 17:43             ` Consul
2009-05-28 20:50               ` Sebastian Herbszt
2009-05-28 21:52                 ` Consul
2009-06-06 17:13                   ` Sebastian Herbszt
2009-06-06 18:40                     ` Alex
2009-06-08 21:27                       ` Consul
2009-06-09 20:13                         ` Sebastian Herbszt
2009-06-09 21:49                           ` Consul
2009-06-10 21:39                             ` Sebastian Herbszt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).