--- Makefile.orig 2008-07-17 18:59:42.000000000 -0400 +++ Makefile 2008-07-17 18:57:42.000000000 -0400 @@ -7,6 +7,7 @@ PORTNAME= qemu PORTVERSION= 0.9.1s.20080620 +PORTREVISION= 1 CATEGORIES= emulators MASTER_SITES= http://bellard.org/qemu/:release \ http://qemu-forum.ipi.fi/qemu-snapshots/:snapshot \ @@ -36,6 +37,7 @@ SAMBA "samba dependency (for -smb)" Off \ SDL "SDL/X dependency (graphical output)" On \ GNUTLS "gnutls dependency (vnc encryption)" On \ + PCAP "pcap dependency (networking with bpf)" On \ CDROM_DMA "IDE CDROM DMA" On \ ALL_TARGETS "Also build dyngen targets (requires gcc34)" On @@ -71,6 +73,10 @@ LIB_DEPENDS+= gnutls:${PORTSDIR}/security/gnutls .endif +.if defined(WITH_PCAP) +CONFIGURE_ARGS+= --enable-pcap +.endif + .if defined(WITH_SAMBA) RUN_DEPENDS+= ${LOCALBASE}/sbin/smbd:${PORTSDIR}/net/samba3 .endif --- files/patch-Makefile.target.orig 2008-07-17 18:45:01.000000000 -0400 +++ files/patch-Makefile.target 2008-07-17 18:45:01.000000000 -0400 @@ -0,0 +1,16 @@ +--- qemu/Makefile.target.orig 2008-07-17 14:55:18.000000000 -0400 ++++ qemu/Makefile.target 2008-07-17 13:20:09.000000000 -0400 +@@ -619,6 +619,13 @@ + ifdef CONFIG_SLIRP + CPPFLAGS+=-I$(SRC_PATH)/slirp + endif ++ifdef CONFIG_PCAP ++ifdef CONFIG_WIN32 ++LIBS+=-lwpcap ++else ++LIBS+=-lpcap ++endif ++endif + + LIBS+=$(AIOLIBS) + # specific flags are needed for non soft mmu emulator --- files/patch-configure.orig 2008-06-03 14:39:51.000000000 -0400 +++ files/patch-configure 2008-07-17 18:52:26.000000000 -0400 @@ -1,5 +1,48 @@ -Index: qemu/configure -@@ -689,7 +689,7 @@ +--- qemu/configure.orig 2008-07-17 18:50:44.000000000 -0400 ++++ qemu/configure 2008-07-17 18:51:32.000000000 -0400 +@@ -87,6 +87,7 @@ + EXESUF="" + gdbstub="yes" + slirp="yes" ++pcap="no" + adlib="no" + ac97="no" + gus="no" +@@ -285,6 +286,8 @@ + ;; + --disable-slirp) slirp="no" + ;; ++ --enable-pcap) pcap="yes" ++ ;; + --enable-adlib) adlib="yes" + ;; + --enable-ac97) ac97="yes" +@@ -724,6 +727,24 @@ + fi # -z $sdl + + ########################################## ++# pcap probe ++ ++if test "$pcap" = "yes" ; then ++ cat > $TMPC << EOF ++#include ++int main(void) { return (pcap_lib_version() == (char *)0 ? 1 : 0); } ++EOF ++ if test "$mingw32" = "no" ; then ++ libpcap=-lpcap ++ else ++ libpcap=-lwpcap ++ fi ++ if ! $cc $ARCH_CFLAGS -o $TMPE $TMPC $libpcap 2> /dev/null ; then ++ pcap=no ++ fi ++fi # test "$pcap" ++ ++########################################## + # VNC TLS detection + if test "$vnc_tls" = "yes" ; then + `pkg-config gnutls` || vnc_tls="no" +@@ -781,7 +802,7 @@ fi # test "$curses" # Check if tools are available to build documentation. @@ -8,3 +51,27 @@ [ -x "`which pod2man 2>/dev/null`" ]; then build_docs="yes" fi +@@ -860,6 +881,7 @@ + echo " TLS CFLAGS $vnc_tls_cflags" + echo " TLS LIBS $vnc_tls_libs" + fi ++echo "pcap support $pcap" + if test -n "$sparc_cpu"; then + echo "Target Sparc Arch $sparc_cpu" + fi +@@ -1033,6 +1055,15 @@ + 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 ++ if test "$mingw32" = "no" ; then ++ if test -c /dev/bpf0 ; then ++ echo "#define HAVE_BPF 1" >> $config_h ++ fi ++ fi ++fi + if test "$adlib" = "yes" ; then + echo "CONFIG_ADLIB=yes" >> $config_mak + echo "#define CONFIG_ADLIB 1" >> $config_h --- files/patch-vl.c-pcap.orig 2008-07-17 18:45:01.000000000 -0400 +++ files/patch-vl.c-pcap 2008-07-17 18:53:31.000000000 -0400 @@ -0,0 +1,212 @@ +--- vl.c.orig 2008-07-17 18:53:01.000000000 -0400 ++++ vl.c 2008-07-17 18:43:34.000000000 -0400 +@@ -109,6 +109,10 @@ + #include + #endif + ++#if defined(CONFIG_PCAP) ++#include ++#endif ++ + #if defined(CONFIG_SLIRP) + #include "libslirp.h" + #endif +@@ -4083,6 +4087,170 @@ + } + #endif + ++#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 = NULL; ++#ifdef PCAP_SET_FILTER ++ struct bpf_program fcode = { 0, NULL }; ++ char pcap_program[128]; ++#endif ++ char macstr[] = "xx:xx:xx:xx:xx:xx"; ++ char errbuf[PCAP_ERRBUF_SIZE]; ++#ifdef _WIN32 ++ HANDLE h; ++#endif ++ int i; ++ ++ /* Find guest's MAC address. */ ++ for (i = 0; i < nb_nics; i++) ++ if (nd_table[i].vlan == vlan) { ++ u_char *mac = nd_table[i].macaddr; ++ snprintf(macstr, sizeof(macstr), "%02x:%02x:%02x:%02x:%02x:%02x", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++ break; ++ } ++ if (macstr[0] == 'x') { ++ fprintf(stderr, "qemu: net_pcap_init: no matching NIC found\n"); ++ return -1; ++ } ++ ++ 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; ++ } ++ ++#ifdef PCAP_SET_FILTER ++ /* Set filter program. */ ++ snprintf(pcap_program, 128, "ether dst %s or " ++ "((broadcast or multicast) and not ether src %s)", ++ macstr, macstr); ++ if (pcap_compile(s->handle, &fcode, pcap_program, 1, 0) < 0) { ++ fprintf(stderr, "qemu: pcap_compile failed\n"); ++ goto fail; ++ } ++ if (pcap_setfilter(s->handle, &fcode) < 0) { ++ fprintf(stderr, "qemu: pcap_setfilter failed\n"); ++ goto fail; ++ } ++#endif ++ ++ /* Set non-blocking mode. */ ++ if (pcap_setnonblock(s->handle, 1, errbuf) < 0) { ++ fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf); ++ goto fail; ++ } ++ ++#if defined(_WIN32) ++ /* ++ * Tell the kernel that the packet has to be seen immediately. ++ */ ++ if (pcap_setmintocopy(s->handle, 0) < 0) { ++ fprintf(stderr, "qemu: pcap failed to set immediate mode\n"); ++ goto fail; ++ } ++#elif defined(HAVE_BPF) ++#if defined(BIOCIMMEDIATE) ++ /* ++ * Tell the kernel that the packet has to be seen immediately. ++ */ ++ { ++ unsigned int one = 1; ++ if (ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one) < 0) { ++ fprintf(stderr, "qemu: pcap failed to set immediate mode\n"); ++ goto fail; ++ } ++ } ++#endif /* BIOCIMMEDIATE */ ++ ++#if defined(BIOCFEEDBACK) ++ /* ++ * Tell the kernel that the sent packet has to be fed back. ++ * This is necessary to connect host and guest. ++ */ ++ { ++ unsigned int one = 1; ++ if (ioctl(pcap_fileno(s->handle), BIOCFEEDBACK, &one) < 0) { ++ fprintf(stderr, "qemu: pcap failed to set feedback mode\n"); ++ goto fail; ++ } ++ } ++#endif /* BIOCFEEDBACK */ ++#endif ++ ++ s->vc = qemu_new_vlan_client(vlan, pcap_receive, NULL, s); ++ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector"); ++ ++#ifdef _WIN32 ++ if ((h = pcap_getevent(s->handle)) == NULL) { ++ fprintf(stderr, "qemu: pcap_getevent failed\n"); ++ goto fail; ++ } ++ qemu_add_wait_object(h, pcap_send, s); ++#else ++ if ((i = pcap_get_selectable_fd(s->handle)) < 0) { ++ fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n"); ++ goto fail; ++ } ++ qemu_set_fd_handler(i, pcap_send, NULL, s); ++#endif ++ ++ return 0; ++ ++fail: ++ if (s) { ++ if (s->handle) { ++#ifdef PCAP_SET_FILTER ++ if (fcode.bf_len) ++ pcap_freecode(&fcode); ++#endif ++ pcap_close(s->handle); ++ } ++ qemu_free(s); ++ } ++ ++ return -1; ++} ++#endif /* CONFIG_PCAP */ ++ + #if !defined(_WIN32) + + typedef struct TAPState { +@@ -5024,6 +5192,16 @@ + ret = net_slirp_init(vlan); + } 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) ++ ret = net_pcap_init(vlan, NULL); ++ else ++ ret = net_pcap_init(vlan, ifname); ++ } else ++#endif + #ifdef _WIN32 + if (!strcmp(device, "tap")) { + char ifname[64]; +@@ -7361,6 +7539,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"