[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] networking using libpcap
From: |
Laurent Vivier |
Subject: |
Re: [Qemu-devel] [PATCH] networking using libpcap |
Date: |
Wed, 02 Jul 2008 17:34:27 +0200 |
Le mercredi 02 juillet 2008 à 17:25 +0200, Laurent Vivier a écrit :
> I think the patch is broken by your mailer agent.
In fact, the inlined one is broken but the attached one is good...
> Laurent
>
> Le mercredi 02 juillet 2008 à 17:02 +0200, Ulrich Hecht a écrit :
> > 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
> >
> > Index: Makefile.target
> > ===================================================================
> > --- Makefile.target (revision 4820)
> > +++ Makefile.target (working copy)
> > @@ -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
> > Index: vl.c
> > ===================================================================
> > --- vl.c (revision 4820)
> > +++ vl.c (working copy)
> > @@ -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)
>
> ^ Here
>
> > +{
> > + 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
>
> > +}
> > +
> > +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"
> > Index: configure
> > ===================================================================
> > --- configure (revision 4820)
> > +++ configure (working copy)
> > @@ -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
> >
> >
--
------------- address@hidden ---------------
"The best way to predict the future is to invent it."
- Alan Kay