summaryrefslogtreecommitdiff
path: root/emulators/qemu-devel/files/pcap-patch
diff options
context:
space:
mode:
Diffstat (limited to 'emulators/qemu-devel/files/pcap-patch')
-rw-r--r--emulators/qemu-devel/files/pcap-patch327
1 files changed, 192 insertions, 135 deletions
diff --git a/emulators/qemu-devel/files/pcap-patch b/emulators/qemu-devel/files/pcap-patch
index 7e740976e378..d5d8b0cb466f 100644
--- a/emulators/qemu-devel/files/pcap-patch
+++ b/emulators/qemu-devel/files/pcap-patch
@@ -1,40 +1,25 @@
---- Makefile.target.orig 2008-07-18 15:18:11.000000000 -0400
-+++ Makefile.target 2008-07-18 15:23:11.000000000 -0400
-@@ -619,6 +619,13 @@
- COCOA_LIBS+=-framework CoreAudio
- endif
- endif
-+ifdef CONFIG_PCAP
-+ifdef CONFIG_WIN32
-+LIBS+=-lwpcap
-+else
-+LIBS+=-lpcap
-+endif
-+endif
- ifdef CONFIG_SLIRP
- CPPFLAGS+=-I$(SRC_PATH)/slirp
- endif
---- configure.orig 2008-07-18 15:18:42.000000000 -0400
-+++ configure 2008-07-18 15:22:24.000000000 -0400
-@@ -88,6 +88,7 @@
- mingw32="no"
- EXESUF=""
- gdbstub="yes"
+Index: configure
+@@ -257,6 +257,9 @@ pkgversion=""
+ check_utests="no"
+ user_pie="no"
+ zero_malloc=""
+pcap="no"
- slirp="yes"
- fmod_lib=""
- fmod_inc=""
-@@ -278,6 +279,8 @@
++pcap_create="no"
++bpf="no"
+
+ # OS specific
+ if check_define __linux__ ; then
+@@ -492,6 +495,8 @@ for opt do
;;
- --enable-mingw32) mingw32="yes" ; cross_prefix="i386-mingw32-" ; linux_user="no"
+ --enable-vnc-sasl) vnc_sasl="yes"
;;
+ --enable-pcap) pcap="yes"
+ ;;
--disable-slirp) slirp="no"
;;
- --disable-kqemu) kqemu="no"
-@@ -712,6 +715,28 @@
- fi # -z $sdl
+ --disable-uuid) uuid="no"
+@@ -1041,6 +1046,49 @@ EOF
+ fi
##########################################
+# pcap probe
@@ -49,142 +34,194 @@
+ else
+ libpcap=-lwpcap
+ fi
-+ if ! $cc $ARCH_CFLAGS -o $TMPE $TMPC $libpcap 2> /dev/null ; then
++ if ! $cc $ARCH_CFLAGS -o $TMPE $libpcap $TMPC 2> /dev/null ; then
+ echo
+ echo "Error: Could not find pcap"
+ echo "Make sure to have the pcap libs and headers installed."
+ echo
+ exit 1
+ fi
++ cat > $TMPC << EOF
++#include <pcap.h>
++int main(void)
++{
++ char errbuf[PCAP_ERRBUF_SIZE];
++ return (pcap_create("foo", errbuf) == (pcap_t *)0 ? 1 : 0);
++}
++EOF
++ if $cc $ARCH_CFLAGS -o $TMPE $libpcap $TMPC 2> /dev/null ; then
++ pcap_create="yes"
++ fi
++ cat > $TMPC << EOF
++#define PCAP_DONT_INCLUDE_PCAP_BPF_H
++#include <pcap.h>
++#include <net/bpf.h>
++int main(void) { return (BPF_MAJOR_VERSION); }
++EOF
++ if $cc $ARCH_CFLAGS -o $TMPE $TMPC 2> /dev/null ; then
++ bpf="yes"
++ fi
++ libs_softmmu="$libpcap $libs_softmmu"
+fi # test "$pcap"
+
+##########################################
# VNC TLS detection
- if test "$vnc_tls" = "yes" ; then
- `pkg-config gnutls` || vnc_tls="no"
-@@ -865,6 +890,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
-@@ -1034,6 +1060,15 @@
+ if test "$vnc_tls" != "no" ; then
+ cat > $TMPC <<EOF
+@@ -1976,6 +2024,15 @@ fi
if test $profiler = "yes" ; then
- echo "#define CONFIG_PROFILER 1" >> $config_h
+ echo "CONFIG_PROFILER=y" >> $config_host_mak
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
++ echo "CONFIG_PCAP=y" >> $config_host_mak
++ if test "$pcap_create" = "yes" ; then
++ echo "CONFIG_PCAP_CREATE=y" >> $config_host_mak
++ fi
++ if test "$bpf" = "yes" ; then
++ echo "CONFIG_BPF=y" >> $config_host_mak
+ fi
+fi
if test "$slirp" = "yes" ; then
- echo "CONFIG_SLIRP=yes" >> $config_mak
- echo "#define CONFIG_SLIRP 1" >> $config_h
---- vl.c.orig 2008-07-18 15:19:26.000000000 -0400
-+++ vl.c 2008-07-18 15:31:25.000000000 -0400
-@@ -102,6 +102,13 @@
- int inet_aton(const char *cp, struct in_addr *ia);
- #endif
+ echo "CONFIG_SLIRP=y" >> $config_host_mak
+ QEMU_CFLAGS="-I\$(SRC_PATH)/slirp $QEMU_CFLAGS"
+Index: net.h
+@@ -33,7 +33,8 @@ typedef enum {
+ NET_CLIENT_TYPE_TAP,
+ NET_CLIENT_TYPE_SOCKET,
+ NET_CLIENT_TYPE_VDE,
+- NET_CLIENT_TYPE_DUMP
++ NET_CLIENT_TYPE_DUMP,
++ NET_CLIENT_TYPE_PCAP
+ } net_client_type;
-+#if defined(CONFIG_PCAP)
-+#if defined(_WIN32)
-+#define WPCAP 1
-+#endif
-+#include <pcap.h>
-+#endif
+ typedef int (NetCanReceive)(VLANClientState *);
+Index: net.c
+@@ -36,6 +36,8 @@
+ #include "qemu-common.h"
+ #include "qemu_socket.h"
+
++#include <sys/ioctl.h>
+
- #if defined(CONFIG_SLIRP)
- #include "libslirp.h"
- #endif
-@@ -3914,6 +3921,164 @@
- }
+ static QTAILQ_HEAD(, VLANState) vlans;
+ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
+
+@@ -820,6 +822,212 @@ static int net_init_nic(QemuOpts *opts,
+ return idx;
}
+#if defined(CONFIG_PCAP)
++#if defined(CONFIG_BPF)
++#define PCAP_DONT_INCLUDE_PCAP_BPF_H
++#include <net/bpf.h>
++#endif
++#include <pcap.h>
+
+typedef struct PCAPState {
-+ VLANClientState *vc;
++ VLANClientState nc;
+ pcap_t *handle;
+} PCAPState;
+
-+static void pcap_receive(void *opaque, const uint8_t *buf, int size)
++static ssize_t pcap_receive(VLANClientState *nc, const uint8_t *buf, size_t size)
+{
-+ PCAPState *s = (PCAPState *)opaque;
++ PCAPState *s = DO_UPCAST(PCAPState, nc, nc);
+
-+ pcap_sendpacket(s->handle, (u_char*)buf, size);
++ return pcap_inject(s->handle, (u_char*)buf, size);
+}
+
++#define MAX_ETH_FRAME_SIZE 1514
++
+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata)
+{
+ VLANClientState *vc = (VLANClientState *)user;
++ int len = phdr->len;
+
-+ qemu_send_packet(vc, pdata, phdr->len);
++ if (len > MAX_ETH_FRAME_SIZE) {
++ fprintf(stderr,
++ "pcap_send: packet size > %d (%d), truncating\n",
++ MAX_ETH_FRAME_SIZE, len);
++ len = MAX_ETH_FRAME_SIZE;
++ }
++ qemu_send_packet(vc, pdata, len);
+}
+
+static void pcap_send(void *opaque)
+{
+ PCAPState *s = (PCAPState *)opaque;
+
-+ pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_char *)s->vc);
++ pcap_dispatch(s->handle, 1, (pcap_handler)&pcap_callback, (u_char *)&s->nc);
+}
+
-+static int net_pcap_init(VLANState *vlan, char *ifname)
++static void pcap_cleanup(VLANClientState *nc)
+{
++ PCAPState *s = DO_UPCAST(PCAPState, nc, nc);
++
++ pcap_close(s->handle);
++}
++
++static NetClientInfo net_pcap_info = {
++ .type = NET_CLIENT_TYPE_PCAP,
++ .size = sizeof(PCAPState),
++ .receive = pcap_receive,
++#if 0
++ .receive_raw = tap_receive_raw,
++ .receive_iov = tap_receive_iov,
++#endif
++ .cleanup = pcap_cleanup,
++};
++
++static int net_pcap_init(VLANState *vlan, const char *model, const char *name, const char *ifname)
++{
++ VLANClientState *nc;
+ PCAPState *s = NULL;
-+ struct bpf_program fcode = { 0, NULL };
-+ char pcap_program[64];
-+ char macstr[] = "xx:xx:xx:xx:xx:xx";
+ char errbuf[PCAP_ERRBUF_SIZE];
+#if defined(_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));
++ nc = qemu_new_net_client(&net_pcap_info, vlan, NULL, model, name);
++#if 0
++ nc = qemu_new_vlan_client(NET_CLIENT_TYPE_PCAP,
++ vlan, NULL, model, name, NULL,
++ pcap_receive, NULL, NULL,
++ pcap_cleanup, s);
++#endif
++
++ s = DO_UPCAST(PCAPState, nc, nc);
+ if (!s)
+ return -1;
+
+ if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) {
-+ fprintf(stderr, "qemu: pcap_lookupdev: %s\n", errbuf);
++ fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
+ goto fail;
+ }
+
-+ /* Attempt to connect device. */
-+ s->handle = (void *)pcap_open_live(ifname, 65535, 1, 0, errbuf);
++#if defined(CONFIG_PCAP_CREATE) || defined(_WIN32)
++ /*
++ * Create pcap handle for the device, set promiscuous mode and activate.
++ */
++ s->handle = (void *)pcap_create(ifname, errbuf);
+ if (!s->handle) {
-+ fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
++ fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
+ goto fail;
+ }
-+
-+ /* Set filter program. */
-+ snprintf(pcap_program, 64, "ether dst %s or multicast", macstr);
-+ if (pcap_compile(s->handle, &fcode, pcap_program, 1, 0) < 0) {
-+ fprintf(stderr, "qemu: pcap_compile failed\n");
++ if (pcap_set_promisc(s->handle, 1) != 0) {
++ pcap_perror(s->handle, "qemu: pcap_set_promisc:");
++ goto fail;
++ }
++ if (pcap_activate(s->handle) != 0) {
++ pcap_perror(s->handle, "qemu: pcap_activate:");
+ goto fail;
+ }
-+ if (pcap_setfilter(s->handle, &fcode) < 0) {
-+ fprintf(stderr, "qemu: pcap_setfilter failed\n");
++#else
++ /* 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;
+ }
++#endif
+
+ /* Set non-blocking mode. */
+ if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
@@ -201,7 +238,7 @@
+ goto fail;
+ }
+#else /* !_WIN32 */
-+#if defined(HAVE_BPF)
++#if defined(CONFIG_BPF)
+#if defined(BIOCIMMEDIATE)
+ /*
+ * Tell the kernel that the packet has to be seen immediately.
@@ -228,11 +265,10 @@
+ }
+ }
+#endif /* BIOCFEEDBACK */
-+#endif /* HAVE_BPF */
++#endif /* CONFIG_BPF */
+#endif /* _WIN32 */
+
-+ s->vc = qemu_new_vlan_client(vlan, pcap_receive, NULL, s);
-+ snprintf(s->vc->info_str, sizeof(s->vc->info_str), "pcap redirector");
++ snprintf(s->nc.info_str, sizeof(s->nc.info_str), "pcap redirector");
+
+#if defined(_WIN32)
+ if ((h = pcap_getevent(s->handle)) == NULL) {
@@ -252,46 +288,67 @@
+
+fail:
+ if (s) {
-+ if (s->handle) {
-+ if (fcode.bf_len)
-+ pcap_freecode(&fcode);
++ if (s->handle)
+ pcap_close(s->handle);
-+ }
+ qemu_free(s);
+ }
+
+ return -1;
+}
++
++static int net_init_pcap(QemuOpts *opts,
++ Monitor *mon,
++ const char *name,
++ VLANState *vlan)
++{
++ const char *ifname;
++
++ ifname = qemu_opt_get(opts, "ifname");
++
++ if (net_pcap_init(vlan, "pcap", name, ifname) == -1) {
++ return -1;
++ }
++
++ vlan->nb_host_devs++;
++
++ return 0;
++}
+#endif /* CONFIG_PCAP */
+
- #if defined(CONFIG_SLIRP)
-
- /* slirp network adapter */
-@@ -4983,6 +5150,16 @@
- are wanted */
- ret = 0;
- } else
+ #define NET_COMMON_PARAMS_DESC \
+ { \
+ .name = "type", \
+@@ -980,6 +1188,20 @@ static struct {
+ #endif /* _WIN32 */
+ { /* end of list */ }
+ },
+#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
++ }, {
++ .type = "pcap",
++ .init = net_init_pcap,
++ .desc = {
++ NET_COMMON_PARAMS_DESC,
++ {
++ .name = "ifname",
++ .type = QEMU_OPT_STRING,
++ .help = "interface name",
++ },
++ { /* end of list */ }
++ },
+#endif
- #ifdef CONFIG_SLIRP
- if (!strcmp(device, "user")) {
- if (get_param_value(buf, sizeof(buf), "hostname", p)) {
-@@ -7398,6 +7575,10 @@
- "Network options:\n"
- "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
- " create a new Network Interface Card and connect it to VLAN 'n'\n"
+ }, {
+ .type = "socket",
+ .init = net_init_socket,
+--- qemu-options.hx.orig 2009-08-28 16:46:21.000000000 -0400
++++ qemu-options.hx 2009-09-02 16:20:14.000000000 -0400
+@@ -783,6 +783,10 @@
+ DEF("net", HAS_ARG, QEMU_OPTION_net,
+ "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
+ " create a new Network Interface Card and connect it to VLAN 'n'\n"
+#ifdef CONFIG_PCAP
-+ "-net pcap[,vlan=n][,ifname=name]\n"
-+ " connect the host network interface using PCAP to VLAN 'n'\n"
++ "-net pcap[,vlan=n][,name=str][,ifname=name]\n"
++ " connect the host network interface using PCAP to VLAN 'n'\n"
+#endif
#ifdef CONFIG_SLIRP
- "-net user[,vlan=n][,hostname=host]\n"
- " connect the user mode network stack to VLAN 'n' and send\n"
+ "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n"
+ " [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n"