networking using libpcap
PATCH 1/1 networking using libpcap
Hi!
I just discovered this patch
http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/003107.html
that implements network access using libpcap. Works perfect for me and allows access to the local Ethernet right out of the box, very much unlike tap and bridging. The attached version applies to trunk.
CU
Uli
Makefile.target +3 -0
@@ -619,6 +619,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
vl.c +19 -0
@@ -102,6 +102,10 @@int inet_aton (const char *cp,struct in_addr *ia);#endif +#if defined(CONFIG_PCAP ) +#include <pcap.h> +#endif +#if defined(CONFIG_SLIRP )#include "libslirp.h" #endif
@@ -4094,6 +4098,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 {
@@ -4978,6 +5080,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];@@ -7381,6 +7492,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"
configure +7 -0
@@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +pcap="yes" fmod_lib="" fmod_inc="" vnc_tls="yes"
@@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --disable-pcap) pcap="no" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no"
@@ -1032,6 +1035,10 @@ echo "CONFIG_SLIRP=yes" >> $config_mak echo "#define CONFIG_SLIRP 1" >> $config_h 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
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
Makefile.target +3 -0
@@ -619,6 +619,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
vl.c +115 -0
139 lines not on this page · raw message
configure +7 -0
@@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +pcap="yes" fmod_lib="" fmod_inc="" vnc_tls="yes"
@@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --disable-pcap) pcap="no" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no"
@@ -1032,6 +1035,10 @@ echo "CONFIG_SLIRP=yes" >> $config_mak echo "#define CONFIG_SLIRP 1" >> $config_h 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
Quoted 8 lines · Ulrich Hecht
Hi!
I just discovered this patch
http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/003107.html
that implements network access using libpcap. Works perfect for me and allows access to the local Ethernet right out of the box, very much unlike tap and bridging. The attached version applies to trunk.
You could also just use slirp? The difference being that pcap requires root (as would raw sockets, which could also work).
Regards,
Anthony Liguori
Quoted 205 lines
CU
UliIndex: Makefile.target
===================================================================Makefile.target +3
-0@@ -619,6 +619,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 emulatorIndex:
vl.c
===================================================================vl.c +102
-0@@ -102,6 +102,10 @@int inet_aton (const char *cp,struct in_addr *ia);#endif +#if defined(CONFIG_PCAP ) +#include <pcap.h> +#endif +#if defined(CONFIG_SLIRP )#include "libslirp.h" #endif @@ -4094,6 +4098,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 {
vl.c +9
-0@@ -4978,6 +5080,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 _WIN32if (!strcmp (device,"tap" )) {char ifname[64 ];@@ -7381,6 +7492,10 @@ " connect the user mode network stack toVLAN 'n' and send\n"
" hostname 'host' to DHCP clients\n"
#endifvl.c +3
-0+#ifdef CONFIG_PCAP +"-net pcap[,vlan=n][,ifname=name]\n" + " connect the host network interface usingPCAP to VLAN 'n'\n"
+#endif
#ifdef_WIN32
"-net tap[,vlan=n],ifname=name\n"
" connect the host TAP network interface to
VLAN 'n'\n"
Index: configure
===================================================================configure +7
-0@@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +pcap="yes" fmod_lib="" fmod_inc="" vnc_tls="yes"@@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --disable-pcap) pcap="no" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no"@@ -1032,6 +1035,10 @@ echo "CONFIG_SLIRP=yes" >> $config_mak echo "#define CONFIG_SLIRP 1" >> $config_h 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
Quoted 2 lines · Anthony Liguori
You could also just use slirp? The difference being that pcap requires root (as would raw sockets, which could also work).
Ever tried doing IPv6 with that?
CU
Uli
Signature · 1 line
SUSE LINUX Products GmbH, GF: Markus Rex, HRB 16746 (AG Nürnberg)
I think the patch is broken by your mailer agent.
Laurent
Quoted 52 lines · Ulrich Hecht
Hi!
I just discovered this patch
http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/003107.html
that implements network access using libpcap. Works perfect for me and allows access to the local Ethernet right out of the box, very much unlike tap and bridging. The attached version applies to trunk.
CU
UliIndex: Makefile.target
===================================================================Makefile.target +3
-0@@ -619,6 +619,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 emulatorIndex:
vl.c
===================================================================vl.c +10
-0@@ -102,6 +102,10 @@int inet_aton (const char *cp,struct in_addr *ia);#endif +#if defined(CONFIG_PCAP ) +#include <pcap.h> +#endif +#if defined(CONFIG_SLIRP )#include "libslirp.h" #endif @@ -4094,6 +4098,104 @@#endif /* CONFIG_SLIRP */ +#if defined(CONFIG_PCAP ) + +typedef struct PCAPState { +VLANClientState *vc; +pcap_t *handle; +}PCAPState ;
vl.c line 4116
Quoted 10 lines
vl.c +9
-0+ +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)
^ Here
vl.c
Quoted 12 lines
vl.c +11
-0+{ +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);
^Here
Quoted 140 lines
vl.c +72
-0+} + +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 {
vl.c +9
-0@@ -4978,6 +5080,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 _WIN32if (!strcmp (device,"tap" )) {char ifname[64 ];@@ -7381,6 +7492,10 @@ " connect the user mode network stack toVLAN 'n' and send\n"
" hostname 'host' to DHCP clients\n"
#endifvl.c +3
-0+#ifdef CONFIG_PCAP +"-net pcap[,vlan=n][,ifname=name]\n" + " connect the host network interface usingPCAP to VLAN 'n'\n"
+#endif
#ifdef_WIN32
"-net tap[,vlan=n],ifname=name\n"
" connect the host TAP network interface to
VLAN 'n'\n"
Index: configure
===================================================================configure +7
-0@@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +pcap="yes" fmod_lib="" fmod_inc="" vnc_tls="yes"@@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --disable-pcap) pcap="no" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no"@@ -1032,6 +1035,10 @@ echo "CONFIG_SLIRP=yes" >> $config_mak echo "#define CONFIG_SLIRP 1" >> $config_h 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
Signature · 3 lines
------------- [email protected] --------------- "The best way to predict the future is to invent it." - Alan Kay
Quoted 1 line · Laurent Vivier
I think the patch is broken by your mailer agent.
In fact, the inlined one is broken but the attached one is good...
Quoted 223 lines
Laurent
Quoted 52 lines · Ulrich Hecht
Hi!
I just discovered this patch
http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/003107.html
that implements network access using libpcap. Works perfect for me and allows access to the local Ethernet right out of the box, very much unlike tap and bridging. The attached version applies to trunk.
CU
UliIndex: Makefile.target
===================================================================Makefile.target +3
-0@@ -619,6 +619,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 emulatorIndex:
vl.c
===================================================================vl.c +10
-0@@ -102,6 +102,10 @@int inet_aton (const char *cp,struct in_addr *ia);#endif +#if defined(CONFIG_PCAP ) +#include <pcap.h> +#endif +#if defined(CONFIG_SLIRP )#include "libslirp.h" #endif @@ -4094,6 +4098,104 @@#endif /* CONFIG_SLIRP */ +#if defined(CONFIG_PCAP ) + +typedef struct PCAPState { +VLANClientState *vc; +pcap_t *handle; +}PCAPState ;vl.c line 4116
Quoted 10 lines
vl.c +9
-0+ +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)^ Here
vl.c
Quoted 12 lines
vl.c +11
-0+{ +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);^Here
Quoted 140 lines
vl.c +72
-0+} + +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 {
vl.c +9
-0@@ -4978,6 +5080,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 _WIN32if (!strcmp (device,"tap" )) {char ifname[64 ];@@ -7381,6 +7492,10 @@ " connect the user mode network stack toVLAN 'n' and send\n"
" hostname 'host' to DHCP clients\n"
#endifvl.c +3
-0+#ifdef CONFIG_PCAP +"-net pcap[,vlan=n][,ifname=name]\n" + " connect the host network interface usingPCAP to VLAN 'n'\n"
+#endif
#ifdef_WIN32
"-net tap[,vlan=n],ifname=name\n"
" connect the host TAP network interface to
VLAN 'n'\n"
Index: configure
===================================================================configure +7
-0@@ -89,6 +89,7 @@ EXESUF="" gdbstub="yes" slirp="yes" +pcap="yes" fmod_lib="" fmod_inc="" vnc_tls="yes"@@ -280,6 +281,8 @@ ;; --disable-slirp) slirp="no" ;; + --disable-pcap) pcap="no" + ;; --disable-kqemu) kqemu="no" ;; --disable-brlapi) brlapi="no"@@ -1032,6 +1035,10 @@ echo "CONFIG_SLIRP=yes" >> $config_mak echo "#define CONFIG_SLIRP 1" >> $config_h 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
Signature · 3 lines
------------- [email protected] --------------- "The best way to predict the future is to invent it." - Alan Kay
Quoted 5 lines
I just discovered this patch
http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/003107.html
that implements network access using libpcap. Works perfect for me and allows access to the local Ethernet right out of the box, very much unlike tap and bridging. The attached version applies to trunk.
I have modified (e.g. got rid of threads) the original patch from the forum and am using it here on Windows. It works fine but performance is pretty low.
Makefile.target line 624
Quoted 3 lines
Makefile.target +3
-0+ifdef CONFIG_PCAP +LIBS+=-lpcap +endif
On Windows it should be -lwpcap.
+ 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);
pcap_get_selectable_fd() is not available on Windows. I just put pcap_send() in main_loop_wait().
- Sebastian