From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1KE4Ln-0004C6-7V for qemu-devel@nongnu.org; Wed, 02 Jul 2008 11:34:31 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1KE4Lj-00049F-W0 for qemu-devel@nongnu.org; Wed, 02 Jul 2008 11:34:29 -0400 Received: from [199.232.76.173] (port=45518 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1KE4Lj-000492-Qz for qemu-devel@nongnu.org; Wed, 02 Jul 2008 11:34:27 -0400 Received: from ecfrec.frec.bull.fr ([129.183.4.8]:51667) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1KE4Lj-0004AY-6M for qemu-devel@nongnu.org; Wed, 02 Jul 2008 11:34:27 -0400 Subject: Re: [Qemu-devel] [PATCH] networking using libpcap From: Laurent Vivier In-Reply-To: <1215012330.3773.6.camel@frecb07144> References: <200807021702.50752.uli@suse.de> <1215012330.3773.6.camel@frecb07144> Content-Type: text/plain; charset=UTF-8 Date: Wed, 02 Jul 2008 17:34:27 +0200 Message-Id: <1215012867.3773.7.camel@frecb07144> Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Le mercredi 02 juillet 2008 =C3=A0 17:25 +0200, Laurent Vivier a =C3=A9cr= it : > I think the patch is broken by your mailer agent. In fact, the inlined one is broken but the attached one is good... > Laurent >=20 > Le mercredi 02 juillet 2008 =C3=A0 17:02 +0200, Ulrich Hecht a =C3=A9cr= it : > > Hi! > >=20 > > I just discovered this patch > >=20 > > http://lists.freebsd.org/pipermail/freebsd-emulation/2007-February/00= 3107.html > >=20 > > that implements network access using libpcap. Works perfect for me an= d=20 > > allows access to the local Ethernet right out of the box, very much=20 > > unlike tap and bridging. The attached version applies to trunk. > >=20 > > CU > > Uli > >=20 > > Index: Makefile.target > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > --- Makefile.target (revision 4820) > > +++ Makefile.target (working copy) > > @@ -619,6 +619,9 @@ > > ifdef CONFIG_SLIRP > > CPPFLAGS+=3D-I$(SRC_PATH)/slirp > > endif > > +ifdef CONFIG_PCAP > > +LIBS+=3D-lpcap > > +endif > > =20 > > LIBS+=3D$(AIOLIBS) > > # specific flags are needed for non soft mmu emulator > > Index: vl.c > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > --- vl.c (revision 4820) > > +++ vl.c (working copy) > > @@ -102,6 +102,10 @@ > > int inet_aton(const char *cp, struct in_addr *ia); > > #endif > > =20 > > +#if defined(CONFIG_PCAP) > > +#include > > +#endif > > + > > #if defined(CONFIG_SLIRP) > > #include "libslirp.h" > > #endif > > @@ -4094,6 +4098,104 @@ > > =20 > > #endif /* CONFIG_SLIRP */ > > =20 > > +#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 =3D (PCAPState *)opaque; > > + > > + pcap_sendpacket(s->handle, (u_char*)buf, size); > > +} > > + > > +static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_= char=20 > > *pdata) >=20 > ^ Here > =20 > > +{ > > + VLANClientState *vc =3D (VLANClientState *)user; > > + > > + qemu_send_packet(vc, pdata, phdr->len); > > +} > > + > > +static void pcap_send(void *opaque) > > +{ > > + PCAPState *s =3D (PCAPState *)opaque; > > + > > + pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_cha= r=20 > > *)s->vc); >=20 > ^Here >=20 > > +} > > + > > +static int net_pcap_init(VLANState *vlan, char *ifname) > > +{ > > + PCAPState *s; > > + char errbuf[PCAP_ERRBUF_SIZE]; > > + int fd; > > + > > + s =3D qemu_mallocz(sizeof(PCAPState)); > > + if (!s) > > + return -1; > > + > > + if (ifname =3D=3D NULL && (ifname =3D pcap_lookupdev(errbuf)) =3D= =3D NULL) { > > + fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf); > > + goto fail; > > + } > > + > > + /* Attempt to connect device. */ > > + s->handle =3D (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 =3D 1; > > + ioctl(pcap_fileno(s->handle), BIOCSHDRCMPLT, &one); > > + } > > +#endif /* BIOCSHDRCMPLT */ > > + > > +#if defined(BIOCIMMEDIATE) > > + /* > > + * Tell the kernel that the packet has to be processed immediate= ly. > > + */ > > + { > > + unsigned int one =3D 1; > > + ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one); > > + } > > +#endif /* BIOCIMMEDIATE */ > > + > > + s->vc =3D qemu_new_vlan_client(vlan, pcap_receive, NULL, s); > > + snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap=20 > > redirector"); > > + if ((fd =3D 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) > > =20 > > typedef struct TAPState { > > @@ -4978,6 +5080,15 @@ > > ret =3D 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) <=3D 0) > > + ret =3D net_pcap_init(vlan, NULL); > > + else > > + ret =3D 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=20 > > VLAN 'n' and send\n" > > " hostname 'host' to DHCP clients\n" > > #endif > > +#ifdef CONFIG_PCAP > > + "-net pcap[,vlan=3Dn][,ifname=3Dname]\n" > > + " connect the host network interface using= =20 > > PCAP to VLAN 'n'\n" > > +#endif > > #ifdef _WIN32 > > "-net tap[,vlan=3Dn],ifname=3Dname\n" > > " connect the host TAP network interface t= o=20 > > VLAN 'n'\n" > > Index: configure > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > --- configure (revision 4820) > > +++ configure (working copy) > > @@ -89,6 +89,7 @@ > > EXESUF=3D"" > > gdbstub=3D"yes" > > slirp=3D"yes" > > +pcap=3D"yes" > > fmod_lib=3D"" > > fmod_inc=3D"" > > vnc_tls=3D"yes" > > @@ -280,6 +281,8 @@ > > ;; > > --disable-slirp) slirp=3D"no" > > ;; > > + --disable-pcap) pcap=3D"no" > > + ;; > > --disable-kqemu) kqemu=3D"no" > > ;; > > --disable-brlapi) brlapi=3D"no" > > @@ -1032,6 +1035,10 @@ > > echo "CONFIG_SLIRP=3Dyes" >> $config_mak > > echo "#define CONFIG_SLIRP 1" >> $config_h > > fi > > +if test "$pcap" =3D "yes" ; then > > + echo "CONFIG_PCAP=3Dyes" >> $config_mak > > + echo "#define CONFIG_PCAP 1" >> $config_h > > +fi > > for card in $audio_card_list; do > > def=3DCONFIG_`echo $card | tr '[:lower:]' '[:upper:]'` > > echo "$def=3Dyes" >> $config_mak > >=20 > >=20 --=20 ------------- Laurent.Vivier@bull.net --------------- "The best way to predict the future is to invent it." - Alan Kay