diff options
Diffstat (limited to 'emulators/qemu-devel/files/pcap-patch')
-rw-r--r-- | emulators/qemu-devel/files/pcap-patch | 398 |
1 files changed, 0 insertions, 398 deletions
diff --git a/emulators/qemu-devel/files/pcap-patch b/emulators/qemu-devel/files/pcap-patch index 0c798e5b1ca5..c8b3c9d00689 100644 --- a/emulators/qemu-devel/files/pcap-patch +++ b/emulators/qemu-devel/files/pcap-patch @@ -1,150 +1,3 @@ -configure ---- configure 2015-12-17 04:04:48.000000000 +0600 -+++ configure 2015-12-25 01:32:09.000000000 +0600 -@@ -342,6 +342,10 @@ - tpm="yes" - libssh2="" - vhdx="" -+quorum="no" -+pcap="no" -+pcap_create="no" -+bpf="no" - numa="" - tcmalloc="no" - jemalloc="no" -@@ -602,7 +606,7 @@ - audio_drv_list="oss" - audio_possible_drivers="oss sdl pa" - # needed for kinfo_getvmmap(3) in libutil.h -- LIBS="-lutil $LIBS" -+ LIBS="-lprocstat -lkvm -lelf -lutil $LIBS" - netmap="" # enable netmap autodetect - HOST_VARIANT_DIR="freebsd" - ;; -@@ -905,6 +909,10 @@ - ;; - --enable-vnc-png) vnc_png="yes" - ;; -+ --enable-pcap) pcap="yes" -+ ;; -+ --disable-pcap) pcap="no" -+ ;; - --disable-slirp) slirp="no" - ;; - --disable-uuid) uuid="no" -@@ -2427,6 +2435,14 @@ - - - ########################################## -+# getifaddrs (for tests/test-io-channel-socket ) -+ -+have_ifaddrs_h=yes -+if ! check_include "ifaddrs.h" ; then -+ have_ifaddrs_h=no -+fi -+ -+########################################## - # VTE probe - - if test "$vte" != "no"; then -@@ -2569,6 +2585,50 @@ - fi - fi - -+########################################## -+# pcap probe -+ -+if test "$pcap" = "yes" -a "$pcap" != "no"; then -+ cat > $TMPC << EOF -+#include <pcap.h> -+int main(void) { return (pcap_lib_version() == (char *)0 ? 1 : 0); } -+EOF -+ if test "$mingw32" = "no" ; then -+ libpcap=-lpcap -+ else -+ libpcap=-lwpcap -+ fi -+ if compile_prog "" "$libpcap" ; then -+ : -+ else -+ 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 compile_prog "" "$libpcap" ; 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 compile_prog ; then -+ bpf="yes" -+ fi -+ libs_softmmu="$libpcap $libs_softmmu" -+fi # test "$pcap" - - ########################################## - # VNC SASL detection -@@ -4758,7 +4833,11 @@ - echo "GNUTLS support $gnutls" - echo "GNUTLS hash $gnutls_hash" - echo "libgcrypt $gcrypt" --echo "nettle $nettle ${nettle+($nettle_version)}" -+if test "$nettle" = "yes"; then -+ echo "nettle $nettle ($nettle_version)" -+else -+ echo "nettle $nettle" -+fi - echo "libtasn1 $tasn1" - echo "VTE support $vte" - echo "curses support $curses" -@@ -4769,6 +4848,7 @@ - echo "Block whitelist (rw) $block_drv_rw_whitelist" - echo "Block whitelist (ro) $block_drv_ro_whitelist" - echo "VirtFS support $virtfs" -+echo "pcap support $pcap" - echo "VNC support $vnc" - if test "$vnc" = "yes" ; then - echo "VNC SASL support $vnc_sasl" -@@ -4947,6 +5027,15 @@ - if test "$profiler" = "yes" ; then - echo "CONFIG_PROFILER=y" >> $config_host_mak - fi -+if test "$pcap" = "yes" ; then -+ 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=y" >> $config_host_mak - echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak -@@ -5137,6 +5226,9 @@ - if test "$tasn1" = "yes" ; then - echo "CONFIG_TASN1=y" >> $config_host_mak - fi -+if test "$have_ifaddrs_h" = "yes" ; then -+ echo "HAVE_IFADDRS_H=y" >> $config_host_mak -+fi - if test "$vte" = "yes" ; then - echo "CONFIG_VTE=y" >> $config_host_mak - echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak diff -ruN net/clients.h net/clients.h --- net/clients.h 2015-12-17 04:04:50.000000000 +0600 +++ net/clients.h 2015-12-25 01:32:09.000000000 +0600 @@ -171,257 +24,6 @@ diff -ruN net/hub.c net/hub.c has_host_dev = 1; break; default: -diff -ruN net/net.c net/net.c ---- net/net.c 2015-12-17 04:04:50.000000000 +0600 -+++ net/net.c 2015-12-25 01:32:09.000000000 +0600 -@@ -46,6 +46,11 @@ - #include "sysemu/sysemu.h" - #include "net/filter.h" - -+#include <sys/ioctl.h> -+#ifdef __FreeBSD__ -+#include <net/if.h> -+#endif -+ - /* Net bridge is currently not supported for W32. */ - #if !defined(_WIN32) - # define CONFIG_NET_BRIDGE -@@ -942,8 +947,224 @@ - 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> -+ -+struct PCAPState { -+ NetClientState nc; -+ pcap_t *handle; -+ int max_eth_frame_size; -+}; -+ -+static ssize_t pcap_receive(NetClientState *nc, const uint8_t *buf, size_t size) -+{ -+ struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc); -+ -+ return pcap_inject(s->handle, (u_char*)buf, size); -+} -+ -+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata -+ ) -+{ -+ NetClientState *nc = (NetClientState *)user; -+ -+ int len = phdr->len; -+#ifdef __FreeBSD__ -+ struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc); -+ int max_eth_frame_size = s->max_eth_frame_size; -+ -+ 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; -+ } -+#endif -+ qemu_send_packet(nc, pdata, len); -+} -+ -+static void pcap_send(void *opaque) -+{ -+ struct PCAPState *s = (struct PCAPState *)opaque; -+ -+ for (;;) { -+ if (pcap_dispatch(s->handle, 0, (pcap_handler)&pcap_callback, (u_char *)&s->nc) >= 0) -+ break; -+ } -+} -+ -+static void pcap_cleanup(NetClientState *nc) -+{ -+ struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc); -+ -+ qemu_purge_queued_packets(nc); -+ pcap_close(s->handle); -+} -+ -+static NetClientInfo net_pcap_info = { -+ .type = NET_CLIENT_OPTIONS_KIND_PCAP, -+ .size = sizeof(struct PCAPState), -+ .receive = pcap_receive, -+// .receive_raw = pcap_receive_raw, -+// .receive_iov = pcap_receive_iov, -+// .poll = pcap_poll, -+ .cleanup = pcap_cleanup, -+}; -+/* -+ * ... -net pcap,ifname="..." -+ */ -+ -+int net_init_pcap(const NetClientOptions *opts, -+ const char *name, NetClientState *peer, Error **errp) -+{ -+ const NetdevPcapOptions *pcap_opts = opts->u.pcap; -+ NetClientState *nc; -+ struct PCAPState *s; -+ const char *ifname; -+ char errbuf[PCAP_ERRBUF_SIZE]; -+#if defined(_WIN32) -+ HANDLE h; -+#endif -+ int i; -+ -+ if (!pcap_opts->has_ifname) -+ return -1; -+ -+ ifname = pcap_opts->ifname; -+ -+ /* create the object */ -+ nc = qemu_new_net_client(&net_pcap_info, peer, "pcap", ifname); -+ s = DO_UPCAST(struct PCAPState, nc, nc); -+ -+ if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) { -+ fprintf(stderr, "qemu: pcap_create: %s\n", errbuf); -+ goto fail; -+ } -+ -+#ifdef __FreeBSD__ -+ /* -+ * We want to avoid passing oversize packets to the guest, which -+ * at least on FreeBSD can happen if the host interface uses tso -+ * (seen with an em(4) in this case) - so find out the host -+ * interface's mtu and assume the guest is configured the same. -+ */ -+ s->max_eth_frame_size = 1514; -+ i = socket(AF_INET, SOCK_DGRAM, 0); -+ if (i >= 0) { -+ struct ifreq ifr; -+ -+ (void) memset(&ifr, 0, sizeof(ifr)); -+ strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); -+ if (ioctl(i, SIOCGIFMTU, &ifr) != -1) -+ s->max_eth_frame_size = ifr.ifr_mtu + 14; -+ close(i); -+ } -+#endif -+ -+#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_create: %s\n", errbuf); -+ goto fail; -+ } -+ if (pcap_set_promisc(s->handle, 1) != 0) { -+ pcap_perror(s->handle, (char *)"qemu: pcap_set_promisc:"); -+ goto fail; -+ } -+ if (pcap_activate(s->handle) != 0) { -+ pcap_perror(s->handle, (char *)"qemu: pcap_activate:"); -+ goto fail; -+ } -+#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) { -+ 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; -+ } -+#else /* !_WIN32 */ -+#if defined(CONFIG_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 /* CONFIG_BPF */ -+#endif /* _WIN32 */ -+ -+ snprintf(s->nc.info_str, sizeof(s->nc.info_str), "pcap redirector"); -+ -+#if defined(_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 /* !_WIN32 */ -+ 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 /* _WIN32 */ -+ -+ return 0; -+ -+fail: -+ if (s) { -+ if (s->handle) -+ pcap_close(s->handle); -+ } -+ -+ return -1; -+} -+ -+#endif - --static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( -+static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])( - const NetClientOptions *opts, - const char *name, - NetClientState *peer, Error **errp) = { -@@ -963,6 +1184,9 @@ - #ifdef CONFIG_NET_BRIDGE - [NET_CLIENT_OPTIONS_KIND_BRIDGE] = net_init_bridge, - #endif -+#ifdef CONFIG_PCAP -+ [NET_CLIENT_OPTIONS_KIND_PCAP] = net_init_pcap, -+#endif - [NET_CLIENT_OPTIONS_KIND_HUBPORT] = net_init_hubport, - #ifdef CONFIG_VHOST_NET_USED - [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user, diff -ruN qapi-schema.json qapi-schema.json --- qapi-schema.json 2015-12-17 04:04:50.000000000 +0600 +++ qapi-schema.json 2015-12-25 01:32:09.000000000 +0600 |