View | Details | Raw Unified | Return to bug 205826 | Differences between
and this patch

Collapse All | Expand All

(-)/usr/ports/emulators/qemu-devel/Makefile (-2 / +10 lines)
Lines 44-50 Link Here
44
GTK2_USES=	gettext
44
GTK2_USES=	gettext
45
GTK2_CONFIGURE_OFF=	--disable-gtk --disable-vte
45
GTK2_CONFIGURE_OFF=	--disable-gtk --disable-vte
46
GNUTLS_LIB_DEPENDS=	libgnutls.so:${PORTSDIR}/security/gnutls
46
GNUTLS_LIB_DEPENDS=	libgnutls.so:${PORTSDIR}/security/gnutls
47
GNUTLS_CONFIGURE_OFF=	--disable-vnc-tls
47
GNUTLS_CONFIGURE_OFF=	--disable-gnutls
48
SASL_LIB_DEPENDS=	libsasl2.so:${PORTSDIR}/security/cyrus-sasl2
48
SASL_LIB_DEPENDS=	libsasl2.so:${PORTSDIR}/security/cyrus-sasl2
49
SASL_CONFIGURE_OFF=	--disable-vnc-sasl
49
SASL_CONFIGURE_OFF=	--disable-vnc-sasl
50
JPEG_USES=		jpeg
50
JPEG_USES=		jpeg
Lines 75-81 Link Here
75
CFLAGS:=	${CFLAGS:C/-fno-tree-vrp//}
75
CFLAGS:=	${CFLAGS:C/-fno-tree-vrp//}
76
CONFIGURE_ARGS+=--localstatedir=/var --extra-ldflags=-L\"${LOCALBASE}/lib\" \
76
CONFIGURE_ARGS+=--localstatedir=/var --extra-ldflags=-L\"${LOCALBASE}/lib\" \
77
		--disable-libssh2 --enable-debug \
77
		--disable-libssh2 --enable-debug \
78
		--prefix=${PREFIX} --cc=${CC} --enable-docs --disable-kvm \
78
		--prefix=${PREFIX} --cc=${CC} --disable-kvm \
79
		--disable-linux-user --disable-linux-aio --disable-xen \
79
		--disable-linux-user --disable-linux-aio --disable-xen \
80
		--smbd=${LOCALBASE}/sbin/smbd --enable-debug-info --python=${PYTHON_CMD} \
80
		--smbd=${LOCALBASE}/sbin/smbd --enable-debug-info --python=${PYTHON_CMD} \
81
		--extra-cflags=-I${WRKSRC}\ -I${LOCALBASE}/include\ -DPREFIX=\\\"\"${PREFIX}\\\"\"
81
		--extra-cflags=-I${WRKSRC}\ -I${LOCALBASE}/include\ -DPREFIX=\\\"\"${PREFIX}\\\"\"
Lines 82-87 Link Here
82
82
83
.include <bsd.port.options.mk>
83
.include <bsd.port.options.mk>
84
84
85
.if defined(DOCS)
86
PLIST_SUB+= MANPAGE=""
87
CONFIGURE_ARGS+= --enable-docs
88
.else
89
PLIST_SUB+= MANPAGE="@comment "
90
CONFIGURE_ARGS+= --disable-docs
91
.endif
92
85
.if !defined(STRIP) || ${STRIP} == ""
93
.if !defined(STRIP) || ${STRIP} == ""
86
CONFIGURE_ARGS+=--disable-strip
94
CONFIGURE_ARGS+=--disable-strip
87
.endif
95
.endif
(-)/usr/ports/emulators/qemu-devel/files/patch-pcap (+446 lines)
Line 0 Link Here
1
configure
2
--- configure	2015-12-17 04:04:48.000000000 +0600
3
+++ configure	2015-12-25 01:32:09.000000000 +0600
4
@@ -342,6 +342,10 @@
5
 tpm="yes"
6
 libssh2=""
7
 vhdx=""
8
+quorum="no"
9
+pcap="no"
10
+pcap_create="no"
11
+bpf="no"
12
 numa=""
13
 tcmalloc="no"
14
 jemalloc="no"
15
@@ -602,7 +606,7 @@
16
   audio_drv_list="oss"
17
   audio_possible_drivers="oss sdl pa"
18
   # needed for kinfo_getvmmap(3) in libutil.h
19
-  LIBS="-lutil $LIBS"
20
+  LIBS="-lprocstat -lkvm -lelf -lutil $LIBS"
21
   netmap=""  # enable netmap autodetect
22
   HOST_VARIANT_DIR="freebsd"
23
 ;;
24
@@ -905,6 +909,10 @@
25
   ;;
26
   --enable-vnc-png) vnc_png="yes"
27
   ;;
28
+  --enable-pcap) pcap="yes"
29
+  ;;
30
+  --disable-pcap) pcap="no"
31
+  ;;
32
   --disable-slirp) slirp="no"
33
   ;;
34
   --disable-uuid) uuid="no"
35
@@ -2427,6 +2435,14 @@
36
 
37
 
38
 ##########################################
39
+# getifaddrs (for tests/test-io-channel-socket )
40
+
41
+have_ifaddrs_h=yes
42
+if ! check_include "ifaddrs.h" ; then
43
+  have_ifaddrs_h=no
44
+fi
45
+
46
+##########################################
47
 # VTE probe
48
 
49
 if test "$vte" != "no"; then
50
@@ -2569,6 +2585,50 @@
51
   fi
52
 fi
53
 
54
+##########################################
55
+# pcap probe
56
+
57
+if test "$pcap" = "yes" -a "$pcap" != "no"; then
58
+  cat > $TMPC << EOF
59
+#include <pcap.h>
60
+int main(void) { return (pcap_lib_version() == (char *)0 ? 1 : 0); }
61
+EOF
62
+  if test "$mingw32" = "no" ; then
63
+    libpcap=-lpcap
64
+  else
65
+    libpcap=-lwpcap
66
+  fi
67
+  if compile_prog "" "$libpcap" ; then
68
+    :
69
+  else
70
+    echo
71
+    echo "Error: Could not find pcap"
72
+    echo "Make sure to have the pcap libs and headers installed."
73
+    echo
74
+    exit 1
75
+  fi
76
+  cat > $TMPC << EOF
77
+#include <pcap.h>
78
+int main(void)
79
+{
80
+  char errbuf[PCAP_ERRBUF_SIZE];
81
+  return (pcap_create("foo", errbuf) == (pcap_t *)0 ? 1 : 0);
82
+}
83
+EOF
84
+  if compile_prog "" "$libpcap" ; then
85
+    pcap_create="yes"
86
+  fi
87
+  cat > $TMPC << EOF
88
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
89
+#include <pcap.h>
90
+#include <net/bpf.h>
91
+int main(void) { return (BPF_MAJOR_VERSION); }
92
+EOF
93
+  if compile_prog ; then
94
+    bpf="yes"
95
+  fi
96
+  libs_softmmu="$libpcap $libs_softmmu"
97
+fi # test "$pcap"
98
 
99
 ##########################################
100
 # VNC SASL detection
101
@@ -4758,7 +4833,11 @@
102
 echo "GNUTLS support    $gnutls"
103
 echo "GNUTLS hash       $gnutls_hash"
104
 echo "libgcrypt         $gcrypt"
105
-echo "nettle            $nettle ${nettle+($nettle_version)}"
106
+if test "$nettle" = "yes"; then
107
+    echo "nettle            $nettle ($nettle_version)"
108
+else
109
+    echo "nettle            $nettle"
110
+fi
111
 echo "libtasn1          $tasn1"
112
 echo "VTE support       $vte"
113
 echo "curses support    $curses"
114
@@ -4769,6 +4848,7 @@
115
 echo "Block whitelist (rw) $block_drv_rw_whitelist"
116
 echo "Block whitelist (ro) $block_drv_ro_whitelist"
117
 echo "VirtFS support    $virtfs"
118
+echo "pcap support      $pcap"
119
 echo "VNC support       $vnc"
120
 if test "$vnc" = "yes" ; then
121
     echo "VNC SASL support  $vnc_sasl"
122
@@ -4947,6 +5027,15 @@
123
 if test "$profiler" = "yes" ; then
124
   echo "CONFIG_PROFILER=y" >> $config_host_mak
125
 fi
126
+if test "$pcap" = "yes" ; then
127
+  echo "CONFIG_PCAP=y" >> $config_host_mak
128
+  if test "$pcap_create" = "yes" ; then
129
+    echo "CONFIG_PCAP_CREATE=y" >> $config_host_mak
130
+  fi
131
+  if test "$bpf" = "yes" ; then
132
+    echo "CONFIG_BPF=y" >> $config_host_mak
133
+  fi
134
+fi
135
 if test "$slirp" = "yes" ; then
136
   echo "CONFIG_SLIRP=y" >> $config_host_mak
137
   echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
138
@@ -5137,6 +5226,9 @@
139
 if test "$tasn1" = "yes" ; then
140
   echo "CONFIG_TASN1=y" >> $config_host_mak
141
 fi
142
+if test "$have_ifaddrs_h" = "yes" ; then
143
+    echo "HAVE_IFADDRS_H=y" >> $config_host_mak
144
+fi
145
 if test "$vte" = "yes" ; then
146
   echo "CONFIG_VTE=y" >> $config_host_mak
147
   echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
148
diff -ruN net/clients.h net/clients.h
149
--- net/clients.h	2015-12-17 04:04:50.000000000 +0600
150
+++ net/clients.h	2015-12-25 01:32:09.000000000 +0600
151
@@ -47,6 +47,11 @@
152
 int net_init_bridge(const NetClientOptions *opts, const char *name,
153
                     NetClientState *peer, Error **errp);
154
 
155
+#ifdef CONFIG_PCAP
156
+int net_init_pcap(const NetClientOptions *opts, const char *name,
157
+                  NetClientState *peer, Error **errp);
158
+#endif
159
+
160
 int net_init_l2tpv3(const NetClientOptions *opts, const char *name,
161
                     NetClientState *peer, Error **errp);
162
 #ifdef CONFIG_VDE
163
diff -ruN net/hub.c net/hub.c
164
--- net/hub.c	2015-12-17 04:04:50.000000000 +0600
165
+++ net/hub.c	2015-12-25 01:32:09.000000000 +0600
166
@@ -322,6 +322,7 @@
167
             case NET_CLIENT_OPTIONS_KIND_SOCKET:
168
             case NET_CLIENT_OPTIONS_KIND_VDE:
169
             case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
170
+            case NET_CLIENT_OPTIONS_KIND_PCAP:
171
                 has_host_dev = 1;
172
                 break;
173
             default:
174
diff -ruN net/net.c net/net.c
175
--- net/net.c	2015-12-17 04:04:50.000000000 +0600
176
+++ net/net.c	2015-12-25 01:32:09.000000000 +0600
177
@@ -46,6 +46,11 @@
178
 #include "sysemu/sysemu.h"
179
 #include "net/filter.h"
180
 
181
+#include <sys/ioctl.h>
182
+#ifdef __FreeBSD__
183
+#include <net/if.h>
184
+#endif
185
+
186
 /* Net bridge is currently not supported for W32. */
187
 #if !defined(_WIN32)
188
 # define CONFIG_NET_BRIDGE
189
@@ -942,8 +947,224 @@
190
     return idx;
191
 }
192
 
193
+#if defined(CONFIG_PCAP)
194
+#if defined(CONFIG_BPF)
195
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
196
+#include <net/bpf.h>
197
+#endif
198
+#include <pcap.h>
199
+
200
+struct PCAPState {
201
+    NetClientState     nc;
202
+    pcap_t            *handle;
203
+    int                max_eth_frame_size;
204
+};
205
+
206
+static ssize_t pcap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
207
+{
208
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
209
+
210
+    return pcap_inject(s->handle, (u_char*)buf, size);
211
+}
212
+
213
+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata
214
+		)
215
+{
216
+    NetClientState *nc = (NetClientState *)user;
217
+
218
+    int len = phdr->len;
219
+#ifdef __FreeBSD__
220
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
221
+    int max_eth_frame_size = s->max_eth_frame_size;
222
+
223
+    if (len > max_eth_frame_size) {
224
+        fprintf(stderr,
225
+            "pcap_send: packet size > %d (%d), truncating\n",
226
+            max_eth_frame_size, len);
227
+        len = max_eth_frame_size;
228
+    }
229
+#endif
230
+    qemu_send_packet(nc, pdata, len);
231
+}
232
+
233
+static void pcap_send(void *opaque)
234
+{
235
+    struct PCAPState *s = (struct PCAPState *)opaque;
236
+
237
+    for (;;) {
238
+        if (pcap_dispatch(s->handle, 0, (pcap_handler)&pcap_callback, (u_char *)&s->nc) >= 0)
239
+            break;
240
+    }
241
+}
242
+
243
+static void pcap_cleanup(NetClientState *nc)
244
+{
245
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
246
+
247
+    qemu_purge_queued_packets(nc);
248
+    pcap_close(s->handle);
249
+}
250
+
251
+static NetClientInfo net_pcap_info = {
252
+    .type = NET_CLIENT_OPTIONS_KIND_PCAP,
253
+    .size = sizeof(struct PCAPState),
254
+    .receive = pcap_receive,
255
+//    .receive_raw = pcap_receive_raw,
256
+//    .receive_iov = pcap_receive_iov,
257
+//    .poll = pcap_poll,
258
+    .cleanup = pcap_cleanup,
259
+};
260
+/*
261
+ * ... -net pcap,ifname="..."
262
+ */
263
+
264
+int net_init_pcap(const NetClientOptions *opts,
265
+    const char *name, NetClientState *peer, Error **errp)
266
+{
267
+    const NetdevPcapOptions *pcap_opts = opts->u.pcap;
268
+    NetClientState *nc;
269
+    struct PCAPState *s;
270
+    const char *ifname;
271
+    char errbuf[PCAP_ERRBUF_SIZE];
272
+#if defined(_WIN32)
273
+    HANDLE h;
274
+#endif
275
+    int i;
276
+
277
+    if (!pcap_opts->has_ifname)
278
+        return -1;
279
+
280
+    ifname = pcap_opts->ifname;
281
+
282
+    /* create the object */
283
+    nc = qemu_new_net_client(&net_pcap_info, peer, "pcap", ifname);
284
+    s = DO_UPCAST(struct PCAPState, nc, nc);
285
+
286
+    if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) {
287
+        fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
288
+        goto fail;
289
+    }
290
+
291
+#ifdef __FreeBSD__
292
+    /*
293
+     * We want to avoid passing oversize packets to the guest, which
294
+     * at least on FreeBSD can happen if the host interface uses tso
295
+     * (seen with an em(4) in this case) - so find out the host
296
+     * interface's mtu and assume the guest is configured the same.
297
+     */
298
+    s->max_eth_frame_size = 1514;
299
+    i = socket(AF_INET, SOCK_DGRAM, 0);
300
+    if (i >= 0) {
301
+        struct ifreq ifr;
302
+
303
+        (void) memset(&ifr, 0, sizeof(ifr));
304
+        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
305
+        if (ioctl(i, SIOCGIFMTU, &ifr) != -1)
306
+            s->max_eth_frame_size = ifr.ifr_mtu + 14;
307
+        close(i);
308
+    }
309
+#endif
310
+
311
+#if defined(CONFIG_PCAP_CREATE) || defined(_WIN32)
312
+    /*
313
+     * Create pcap handle for the device, set promiscuous mode and activate.
314
+     */
315
+    s->handle = (void *)pcap_create(ifname, errbuf);
316
+    if (!s->handle) {
317
+        fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
318
+        goto fail;
319
+    }
320
+    if (pcap_set_promisc(s->handle, 1) != 0) {
321
+        pcap_perror(s->handle, (char *)"qemu: pcap_set_promisc:");
322
+        goto fail;
323
+    }
324
+    if (pcap_activate(s->handle) != 0) {
325
+        pcap_perror(s->handle, (char *)"qemu: pcap_activate:");
326
+        goto fail;
327
+    }
328
+#else
329
+    /* Attempt to connect device. */
330
+    s->handle = (void *)pcap_open_live(ifname, 65535, 1, 0, errbuf);
331
+    if (!s->handle) {
332
+        fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
333
+        goto fail;
334
+    }
335
+#endif
336
+
337
+    /* Set non-blocking mode. */
338
+    if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
339
+        fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf);
340
+        goto fail;
341
+    }
342
+
343
+#if defined(_WIN32)
344
+    /*
345
+     * Tell the kernel that the packet has to be seen immediately.
346
+     */
347
+    if (pcap_setmintocopy(s->handle, 0) < 0) {
348
+        fprintf(stderr, "qemu: pcap failed to set immediate mode\n");
349
+        goto fail;
350
+    }
351
+#else /* !_WIN32 */
352
+#if defined(CONFIG_BPF)
353
+#if defined(BIOCIMMEDIATE)
354
+    /*
355
+     * Tell the kernel that the packet has to be seen immediately.
356
+     */
357
+    {
358
+        unsigned int one = 1;
359
+        if (ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one) < 0) {
360
+            fprintf(stderr, "qemu: pcap failed to set immediate mode\n");
361
+            goto fail;
362
+        }
363
+    }
364
+#endif /* BIOCIMMEDIATE */
365
+#if defined(BIOCFEEDBACK)
366
+    /*
367
+     * Tell the kernel that the sent packet has to be fed back.
368
+     * This is necessary to connect host and guest.
369
+     */
370
+    {
371
+        unsigned int one = 1;
372
+        if (ioctl(pcap_fileno(s->handle), BIOCFEEDBACK, &one) < 0) {
373
+            fprintf(stderr, "qemu: pcap failed to set feedback mode\n");
374
+            goto fail;
375
+        }
376
+    }
377
+#endif /* BIOCFEEDBACK */
378
+#endif /* CONFIG_BPF */
379
+#endif /* _WIN32 */
380
+
381
+    snprintf(s->nc.info_str, sizeof(s->nc.info_str), "pcap redirector");
382
+
383
+#if defined(_WIN32)
384
+    if ((h = pcap_getevent(s->handle)) == NULL) {
385
+        fprintf(stderr, "qemu: pcap_getevent failed\n");
386
+        goto fail;
387
+    }
388
+    qemu_add_wait_object(h, pcap_send, s);
389
+#else /* !_WIN32 */
390
+    if ((i = pcap_get_selectable_fd(s->handle)) < 0) {
391
+        fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n");
392
+        goto fail;
393
+    }
394
+    qemu_set_fd_handler(i, pcap_send, NULL, s);
395
+#endif /* _WIN32 */
396
+
397
+    return 0;
398
+
399
+fail:
400
+    if (s) {
401
+        if (s->handle)
402
+            pcap_close(s->handle);
403
+    }
404
+
405
+    return -1;
406
+}
407
+
408
+#endif
409
 
410
-static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
411
+static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
412
     const NetClientOptions *opts,
413
     const char *name,
414
     NetClientState *peer, Error **errp) = {
415
@@ -963,6 +1184,9 @@
416
 #ifdef CONFIG_NET_BRIDGE
417
         [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
418
 #endif
419
+#ifdef CONFIG_PCAP
420
+	[NET_CLIENT_OPTIONS_KIND_PCAP]      = net_init_pcap,
421
+#endif
422
         [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
423
 #ifdef CONFIG_VHOST_NET_USED
424
         [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
425
diff -ruN qapi-schema.json qapi-schema.json
426
--- qapi-schema.json	2015-12-17 04:04:50.000000000 +0600
427
+++ qapi-schema.json	2015-12-25 01:32:09.000000000 +0600
428
@@ -2538,6 +2538,10 @@
429
     '*br':     'str',
430
     '*helper': 'str' } }
431
 
432
+{ 'struct': 'NetdevPcapOptions',
433
+  'data': {
434
+    '*ifname':     'str' } }
435
+
436
 ##
437
 # @NetdevHubPortOptions
438
 #
439
@@ -2608,6 +2612,7 @@
440
     'nic':      'NetLegacyNicOptions',
441
     'user':     'NetdevUserOptions',
442
     'tap':      'NetdevTapOptions',
443
+    'pcap':     'NetdevPcapOptions',
444
     'l2tpv3':   'NetdevL2TPv3Options',
445
     'socket':   'NetdevSocketOptions',
446
     'vde':      'NetdevVdeOptions',
(-)/usr/ports/emulators/qemu-devel/files/pcap-patch (-446 lines)
Lines 1-446 Link Here
1
configure
2
--- configure	2015-12-17 04:04:48.000000000 +0600
3
+++ configure	2015-12-25 01:32:09.000000000 +0600
4
@@ -342,6 +342,10 @@
5
 tpm="yes"
6
 libssh2=""
7
 vhdx=""
8
+quorum="no"
9
+pcap="no"
10
+pcap_create="no"
11
+bpf="no"
12
 numa=""
13
 tcmalloc="no"
14
 jemalloc="no"
15
@@ -602,7 +606,7 @@
16
   audio_drv_list="oss"
17
   audio_possible_drivers="oss sdl pa"
18
   # needed for kinfo_getvmmap(3) in libutil.h
19
-  LIBS="-lutil $LIBS"
20
+  LIBS="-lprocstat -lkvm -lelf -lutil $LIBS"
21
   netmap=""  # enable netmap autodetect
22
   HOST_VARIANT_DIR="freebsd"
23
 ;;
24
@@ -905,6 +909,10 @@
25
   ;;
26
   --enable-vnc-png) vnc_png="yes"
27
   ;;
28
+  --enable-pcap) pcap="yes"
29
+  ;;
30
+  --disable-pcap) pcap="no"
31
+  ;;
32
   --disable-slirp) slirp="no"
33
   ;;
34
   --disable-uuid) uuid="no"
35
@@ -2427,6 +2435,14 @@
36
 
37
 
38
 ##########################################
39
+# getifaddrs (for tests/test-io-channel-socket )
40
+
41
+have_ifaddrs_h=yes
42
+if ! check_include "ifaddrs.h" ; then
43
+  have_ifaddrs_h=no
44
+fi
45
+
46
+##########################################
47
 # VTE probe
48
 
49
 if test "$vte" != "no"; then
50
@@ -2569,6 +2585,50 @@
51
   fi
52
 fi
53
 
54
+##########################################
55
+# pcap probe
56
+
57
+if test "$pcap" = "yes" -a "$pcap" != "no"; then
58
+  cat > $TMPC << EOF
59
+#include <pcap.h>
60
+int main(void) { return (pcap_lib_version() == (char *)0 ? 1 : 0); }
61
+EOF
62
+  if test "$mingw32" = "no" ; then
63
+    libpcap=-lpcap
64
+  else
65
+    libpcap=-lwpcap
66
+  fi
67
+  if compile_prog "" "$libpcap" ; then
68
+    :
69
+  else
70
+    echo
71
+    echo "Error: Could not find pcap"
72
+    echo "Make sure to have the pcap libs and headers installed."
73
+    echo
74
+    exit 1
75
+  fi
76
+  cat > $TMPC << EOF
77
+#include <pcap.h>
78
+int main(void)
79
+{
80
+  char errbuf[PCAP_ERRBUF_SIZE];
81
+  return (pcap_create("foo", errbuf) == (pcap_t *)0 ? 1 : 0);
82
+}
83
+EOF
84
+  if compile_prog "" "$libpcap" ; then
85
+    pcap_create="yes"
86
+  fi
87
+  cat > $TMPC << EOF
88
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
89
+#include <pcap.h>
90
+#include <net/bpf.h>
91
+int main(void) { return (BPF_MAJOR_VERSION); }
92
+EOF
93
+  if compile_prog ; then
94
+    bpf="yes"
95
+  fi
96
+  libs_softmmu="$libpcap $libs_softmmu"
97
+fi # test "$pcap"
98
 
99
 ##########################################
100
 # VNC SASL detection
101
@@ -4758,7 +4833,11 @@
102
 echo "GNUTLS support    $gnutls"
103
 echo "GNUTLS hash       $gnutls_hash"
104
 echo "libgcrypt         $gcrypt"
105
-echo "nettle            $nettle ${nettle+($nettle_version)}"
106
+if test "$nettle" = "yes"; then
107
+    echo "nettle            $nettle ($nettle_version)"
108
+else
109
+    echo "nettle            $nettle"
110
+fi
111
 echo "libtasn1          $tasn1"
112
 echo "VTE support       $vte"
113
 echo "curses support    $curses"
114
@@ -4769,6 +4848,7 @@
115
 echo "Block whitelist (rw) $block_drv_rw_whitelist"
116
 echo "Block whitelist (ro) $block_drv_ro_whitelist"
117
 echo "VirtFS support    $virtfs"
118
+echo "pcap support      $pcap"
119
 echo "VNC support       $vnc"
120
 if test "$vnc" = "yes" ; then
121
     echo "VNC SASL support  $vnc_sasl"
122
@@ -4947,6 +5027,15 @@
123
 if test "$profiler" = "yes" ; then
124
   echo "CONFIG_PROFILER=y" >> $config_host_mak
125
 fi
126
+if test "$pcap" = "yes" ; then
127
+  echo "CONFIG_PCAP=y" >> $config_host_mak
128
+  if test "$pcap_create" = "yes" ; then
129
+    echo "CONFIG_PCAP_CREATE=y" >> $config_host_mak
130
+  fi
131
+  if test "$bpf" = "yes" ; then
132
+    echo "CONFIG_BPF=y" >> $config_host_mak
133
+  fi
134
+fi
135
 if test "$slirp" = "yes" ; then
136
   echo "CONFIG_SLIRP=y" >> $config_host_mak
137
   echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak
138
@@ -5137,6 +5226,9 @@
139
 if test "$tasn1" = "yes" ; then
140
   echo "CONFIG_TASN1=y" >> $config_host_mak
141
 fi
142
+if test "$have_ifaddrs_h" = "yes" ; then
143
+    echo "HAVE_IFADDRS_H=y" >> $config_host_mak
144
+fi
145
 if test "$vte" = "yes" ; then
146
   echo "CONFIG_VTE=y" >> $config_host_mak
147
   echo "VTE_CFLAGS=$vte_cflags" >> $config_host_mak
148
diff -ruN net/clients.h net/clients.h
149
--- net/clients.h	2015-12-17 04:04:50.000000000 +0600
150
+++ net/clients.h	2015-12-25 01:32:09.000000000 +0600
151
@@ -47,6 +47,11 @@
152
 int net_init_bridge(const NetClientOptions *opts, const char *name,
153
                     NetClientState *peer, Error **errp);
154
 
155
+#ifdef CONFIG_PCAP
156
+int net_init_pcap(const NetClientOptions *opts, const char *name,
157
+                  NetClientState *peer, Error **errp);
158
+#endif
159
+
160
 int net_init_l2tpv3(const NetClientOptions *opts, const char *name,
161
                     NetClientState *peer, Error **errp);
162
 #ifdef CONFIG_VDE
163
diff -ruN net/hub.c net/hub.c
164
--- net/hub.c	2015-12-17 04:04:50.000000000 +0600
165
+++ net/hub.c	2015-12-25 01:32:09.000000000 +0600
166
@@ -322,6 +322,7 @@
167
             case NET_CLIENT_OPTIONS_KIND_SOCKET:
168
             case NET_CLIENT_OPTIONS_KIND_VDE:
169
             case NET_CLIENT_OPTIONS_KIND_VHOST_USER:
170
+            case NET_CLIENT_OPTIONS_KIND_PCAP:
171
                 has_host_dev = 1;
172
                 break;
173
             default:
174
diff -ruN net/net.c net/net.c
175
--- net/net.c	2015-12-17 04:04:50.000000000 +0600
176
+++ net/net.c	2015-12-25 01:32:09.000000000 +0600
177
@@ -46,6 +46,11 @@
178
 #include "sysemu/sysemu.h"
179
 #include "net/filter.h"
180
 
181
+#include <sys/ioctl.h>
182
+#ifdef __FreeBSD__
183
+#include <net/if.h>
184
+#endif
185
+
186
 /* Net bridge is currently not supported for W32. */
187
 #if !defined(_WIN32)
188
 # define CONFIG_NET_BRIDGE
189
@@ -942,8 +947,224 @@
190
     return idx;
191
 }
192
 
193
+#if defined(CONFIG_PCAP)
194
+#if defined(CONFIG_BPF)
195
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
196
+#include <net/bpf.h>
197
+#endif
198
+#include <pcap.h>
199
+
200
+struct PCAPState {
201
+    NetClientState     nc;
202
+    pcap_t            *handle;
203
+    int                max_eth_frame_size;
204
+};
205
+
206
+static ssize_t pcap_receive(NetClientState *nc, const uint8_t *buf, size_t size)
207
+{
208
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
209
+
210
+    return pcap_inject(s->handle, (u_char*)buf, size);
211
+}
212
+
213
+static void pcap_callback(u_char *user, struct pcap_pkthdr *phdr, u_char *pdata
214
+		)
215
+{
216
+    NetClientState *nc = (NetClientState *)user;
217
+
218
+    int len = phdr->len;
219
+#ifdef __FreeBSD__
220
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
221
+    int max_eth_frame_size = s->max_eth_frame_size;
222
+
223
+    if (len > max_eth_frame_size) {
224
+        fprintf(stderr,
225
+            "pcap_send: packet size > %d (%d), truncating\n",
226
+            max_eth_frame_size, len);
227
+        len = max_eth_frame_size;
228
+    }
229
+#endif
230
+    qemu_send_packet(nc, pdata, len);
231
+}
232
+
233
+static void pcap_send(void *opaque)
234
+{
235
+    struct PCAPState *s = (struct PCAPState *)opaque;
236
+
237
+    for (;;) {
238
+        if (pcap_dispatch(s->handle, 0, (pcap_handler)&pcap_callback, (u_char *)&s->nc) >= 0)
239
+            break;
240
+    }
241
+}
242
+
243
+static void pcap_cleanup(NetClientState *nc)
244
+{
245
+    struct PCAPState *s = DO_UPCAST(struct PCAPState, nc, nc);
246
+
247
+    qemu_purge_queued_packets(nc);
248
+    pcap_close(s->handle);
249
+}
250
+
251
+static NetClientInfo net_pcap_info = {
252
+    .type = NET_CLIENT_OPTIONS_KIND_PCAP,
253
+    .size = sizeof(struct PCAPState),
254
+    .receive = pcap_receive,
255
+//    .receive_raw = pcap_receive_raw,
256
+//    .receive_iov = pcap_receive_iov,
257
+//    .poll = pcap_poll,
258
+    .cleanup = pcap_cleanup,
259
+};
260
+/*
261
+ * ... -net pcap,ifname="..."
262
+ */
263
+
264
+int net_init_pcap(const NetClientOptions *opts,
265
+    const char *name, NetClientState *peer, Error **errp)
266
+{
267
+    const NetdevPcapOptions *pcap_opts = opts->u.pcap;
268
+    NetClientState *nc;
269
+    struct PCAPState *s;
270
+    const char *ifname;
271
+    char errbuf[PCAP_ERRBUF_SIZE];
272
+#if defined(_WIN32)
273
+    HANDLE h;
274
+#endif
275
+    int i;
276
+
277
+    if (!pcap_opts->has_ifname)
278
+        return -1;
279
+
280
+    ifname = pcap_opts->ifname;
281
+
282
+    /* create the object */
283
+    nc = qemu_new_net_client(&net_pcap_info, peer, "pcap", ifname);
284
+    s = DO_UPCAST(struct PCAPState, nc, nc);
285
+
286
+    if (ifname == NULL && (ifname = pcap_lookupdev(errbuf)) == NULL) {
287
+        fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
288
+        goto fail;
289
+    }
290
+
291
+#ifdef __FreeBSD__
292
+    /*
293
+     * We want to avoid passing oversize packets to the guest, which
294
+     * at least on FreeBSD can happen if the host interface uses tso
295
+     * (seen with an em(4) in this case) - so find out the host
296
+     * interface's mtu and assume the guest is configured the same.
297
+     */
298
+    s->max_eth_frame_size = 1514;
299
+    i = socket(AF_INET, SOCK_DGRAM, 0);
300
+    if (i >= 0) {
301
+        struct ifreq ifr;
302
+
303
+        (void) memset(&ifr, 0, sizeof(ifr));
304
+        strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
305
+        if (ioctl(i, SIOCGIFMTU, &ifr) != -1)
306
+            s->max_eth_frame_size = ifr.ifr_mtu + 14;
307
+        close(i);
308
+    }
309
+#endif
310
+
311
+#if defined(CONFIG_PCAP_CREATE) || defined(_WIN32)
312
+    /*
313
+     * Create pcap handle for the device, set promiscuous mode and activate.
314
+     */
315
+    s->handle = (void *)pcap_create(ifname, errbuf);
316
+    if (!s->handle) {
317
+        fprintf(stderr, "qemu: pcap_create: %s\n", errbuf);
318
+        goto fail;
319
+    }
320
+    if (pcap_set_promisc(s->handle, 1) != 0) {
321
+        pcap_perror(s->handle, (char *)"qemu: pcap_set_promisc:");
322
+        goto fail;
323
+    }
324
+    if (pcap_activate(s->handle) != 0) {
325
+        pcap_perror(s->handle, (char *)"qemu: pcap_activate:");
326
+        goto fail;
327
+    }
328
+#else
329
+    /* Attempt to connect device. */
330
+    s->handle = (void *)pcap_open_live(ifname, 65535, 1, 0, errbuf);
331
+    if (!s->handle) {
332
+        fprintf(stderr, "qemu: pcap_open_live: %s\n", errbuf);
333
+        goto fail;
334
+    }
335
+#endif
336
+
337
+    /* Set non-blocking mode. */
338
+    if (pcap_setnonblock(s->handle, 1, errbuf) < 0) {
339
+        fprintf(stderr, "qemu: pcap_setnonblock: %s\n", errbuf);
340
+        goto fail;
341
+    }
342
+
343
+#if defined(_WIN32)
344
+    /*
345
+     * Tell the kernel that the packet has to be seen immediately.
346
+     */
347
+    if (pcap_setmintocopy(s->handle, 0) < 0) {
348
+        fprintf(stderr, "qemu: pcap failed to set immediate mode\n");
349
+        goto fail;
350
+    }
351
+#else /* !_WIN32 */
352
+#if defined(CONFIG_BPF)
353
+#if defined(BIOCIMMEDIATE)
354
+    /*
355
+     * Tell the kernel that the packet has to be seen immediately.
356
+     */
357
+    {
358
+        unsigned int one = 1;
359
+        if (ioctl(pcap_fileno(s->handle), BIOCIMMEDIATE, &one) < 0) {
360
+            fprintf(stderr, "qemu: pcap failed to set immediate mode\n");
361
+            goto fail;
362
+        }
363
+    }
364
+#endif /* BIOCIMMEDIATE */
365
+#if defined(BIOCFEEDBACK)
366
+    /*
367
+     * Tell the kernel that the sent packet has to be fed back.
368
+     * This is necessary to connect host and guest.
369
+     */
370
+    {
371
+        unsigned int one = 1;
372
+        if (ioctl(pcap_fileno(s->handle), BIOCFEEDBACK, &one) < 0) {
373
+            fprintf(stderr, "qemu: pcap failed to set feedback mode\n");
374
+            goto fail;
375
+        }
376
+    }
377
+#endif /* BIOCFEEDBACK */
378
+#endif /* CONFIG_BPF */
379
+#endif /* _WIN32 */
380
+
381
+    snprintf(s->nc.info_str, sizeof(s->nc.info_str), "pcap redirector");
382
+
383
+#if defined(_WIN32)
384
+    if ((h = pcap_getevent(s->handle)) == NULL) {
385
+        fprintf(stderr, "qemu: pcap_getevent failed\n");
386
+        goto fail;
387
+    }
388
+    qemu_add_wait_object(h, pcap_send, s);
389
+#else /* !_WIN32 */
390
+    if ((i = pcap_get_selectable_fd(s->handle)) < 0) {
391
+        fprintf(stderr, "qemu: pcap_get_selectable_fd failed\n");
392
+        goto fail;
393
+    }
394
+    qemu_set_fd_handler(i, pcap_send, NULL, s);
395
+#endif /* _WIN32 */
396
+
397
+    return 0;
398
+
399
+fail:
400
+    if (s) {
401
+        if (s->handle)
402
+            pcap_close(s->handle);
403
+    }
404
+
405
+    return -1;
406
+}
407
+
408
+#endif
409
 
410
-static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
411
+static int (* const net_client_init_fun[NET_CLIENT_OPTIONS_KIND_MAX])(
412
     const NetClientOptions *opts,
413
     const char *name,
414
     NetClientState *peer, Error **errp) = {
415
@@ -963,6 +1184,9 @@
416
 #ifdef CONFIG_NET_BRIDGE
417
         [NET_CLIENT_OPTIONS_KIND_BRIDGE]    = net_init_bridge,
418
 #endif
419
+#ifdef CONFIG_PCAP
420
+	[NET_CLIENT_OPTIONS_KIND_PCAP]      = net_init_pcap,
421
+#endif
422
         [NET_CLIENT_OPTIONS_KIND_HUBPORT]   = net_init_hubport,
423
 #ifdef CONFIG_VHOST_NET_USED
424
         [NET_CLIENT_OPTIONS_KIND_VHOST_USER] = net_init_vhost_user,
425
diff -ruN qapi-schema.json qapi-schema.json
426
--- qapi-schema.json	2015-12-17 04:04:50.000000000 +0600
427
+++ qapi-schema.json	2015-12-25 01:32:09.000000000 +0600
428
@@ -2538,6 +2538,10 @@
429
     '*br':     'str',
430
     '*helper': 'str' } }
431
 
432
+{ 'struct': 'NetdevPcapOptions',
433
+  'data': {
434
+    '*ifname':     'str' } }
435
+
436
 ##
437
 # @NetdevHubPortOptions
438
 #
439
@@ -2608,6 +2612,7 @@
440
     'nic':      'NetLegacyNicOptions',
441
     'user':     'NetdevUserOptions',
442
     'tap':      'NetdevTapOptions',
443
+    'pcap':     'NetdevPcapOptions',
444
     'l2tpv3':   'NetdevL2TPv3Options',
445
     'socket':   'NetdevSocketOptions',
446
     'vde':      'NetdevVdeOptions',
(-)/usr/ports/emulators/qemu-devel/pkg-plist (-4 / +8 lines)
Lines 3-9 Link Here
3
bin/qemu-ga
3
bin/qemu-ga
4
bin/qemu-img
4
bin/qemu-img
5
bin/qemu-io
5
bin/qemu-io
6
bin/qemu-i386
6
bin/qemu-nbd
7
bin/qemu-nbd
8
%%X86_TARGETS%%bin/qemu-sparc
9
%%X86_TARGETS%%bin/qemu-sparc64
7
%%X86_TARGETS%%bin/qemu-system-aarch64
10
%%X86_TARGETS%%bin/qemu-system-aarch64
8
%%X86_TARGETS%%bin/qemu-system-alpha
11
%%X86_TARGETS%%bin/qemu-system-alpha
9
%%X86_TARGETS%%bin/qemu-system-arm
12
%%X86_TARGETS%%bin/qemu-system-arm
Lines 32-41 Link Here
32
bin/qemu-system-x86_64
35
bin/qemu-system-x86_64
33
%%X86_TARGETS%%bin/qemu-system-xtensa
36
%%X86_TARGETS%%bin/qemu-system-xtensa
34
%%X86_TARGETS%%bin/qemu-system-xtensaeb
37
%%X86_TARGETS%%bin/qemu-system-xtensaeb
35
man/man1/qemu.1.gz
38
bin/qemu-x86_64
36
man/man1/qemu-img.1.gz
39
%%MANPAGE%%man/man1/qemu.1.gz
37
man/man8/qemu-ga.8.gz
40
%%MANPAGE%%man/man1/qemu-img.1.gz
38
man/man8/qemu-nbd.8.gz
41
%%MANPAGE%%man/man8/qemu-ga.8.gz
42
%%MANPAGE%%man/man8/qemu-nbd.8.gz
39
@sample etc/qemu-ifup.sample
43
@sample etc/qemu-ifup.sample
40
@sample etc/qemu-ifdown.sample
44
@sample etc/qemu-ifdown.sample
41
%%DATADIR%%/QEMU,tcx.bin
45
%%DATADIR%%/QEMU,tcx.bin

Return to bug 205826