qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <anthony@codemonkey.ws>
To: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH] networking using libpcap
Date: Wed, 02 Jul 2008 10:20:59 -0500	[thread overview]
Message-ID: <486B9CDB.30302@codemonkey.ws> (raw)
In-Reply-To: <200807021702.50752.uli@suse.de>

Ulrich Hecht wrote:
> 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

> 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)
> +{
> +    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"
> 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
>
>
>   

  reply	other threads:[~2008-07-02 15:21 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-07-02 15:02 [Qemu-devel] [PATCH] networking using libpcap Ulrich Hecht
2008-07-02 15:20 ` Anthony Liguori [this message]
2008-07-02 16:03   ` Ulrich Hecht
2008-07-02 15:25 ` Laurent Vivier
2008-07-02 15:34   ` Laurent Vivier
2008-07-02 23:39 ` [Qemu-devel] " Sebastian Herbszt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=486B9CDB.30302@codemonkey.ws \
    --to=anthony@codemonkey.ws \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).