* [Qemu-devel] [Patch] Add -net dump option
@ 2009-02-04 10:22 Tristan Gingold
2009-02-06 18:53 ` Anthony Liguori
2009-02-07 4:09 ` Luca Bigliardi
0 siblings, 2 replies; 13+ messages in thread
From: Tristan Gingold @ 2009-02-04 10:22 UTC (permalink / raw)
To: qemu-devel
Hi,
this patch add a new network pseudo nic that dump traffic to a tcpdump
compatible file. I have found this feature useful to debug network protocols
with the user stack.
Signed-off-by: Tristan Gingold <gingold@adacore.com>
Tristan.
diff --git a/qemu-doc.texi b/qemu-doc.texi
index b2fa19e..73c133a 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -739,6 +739,15 @@ vde_switch -F -sock /tmp/myswitch
qemu linux.img -net nic -net vde,sock=/tmp/myswitch
@end example
+@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu.tcpdump} by
+default). At most @var{len} bytes (64 by default) by packet are stored. The
+dump can be analyzed with tools such as tcpdump.
+
+For better results you'd better to use this option before the @samp{-net user}
+one as the user stack may send replies before the initial packet was propagated
+to all receivers.
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration (@option{-net nic -net user}) which
diff --git a/net.c b/net.c
index 8d9b3de..872a17e 100644
--- a/net.c
+++ b/net.c
@@ -1064,6 +1064,75 @@ static int net_vde_init(VLANState *vlan, const char *model,
}
#endif
+static VLANClientState *tcpdump_vc;
+static FILE *tcpdump_file;
+static int tcpdump_caplen;
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+struct pcap_file_hdr {
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t thiszone;
+ uint32_t sigfigs;
+ uint32_t snaplen;
+ uint32_t linktype;
+};
+
+struct pcap_sf_pkthdr {
+ struct {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } ts;
+ uint32_t caplen;
+ uint32_t len;
+};
+
+static void tcpdump_receive(void *opaque, const uint8_t *buf, int size)
+{
+ struct pcap_sf_pkthdr hdr;
+ int64_t ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
+ int caplen = size > tcpdump_caplen ? tcpdump_caplen : size;
+
+ hdr.ts.tv_sec = ts / 1000000000LL;
+ hdr.ts.tv_usec = ts % 1000000;
+ hdr.caplen = caplen;
+ hdr.len = size;
+ fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
+ fwrite(buf, caplen, 1, tcpdump_file);
+}
+
+static int net_tcpdump_init(VLANState *vlan, const char *device,
+ const char *name, const char *filename, int len)
+{
+ struct pcap_file_hdr hdr;
+
+ tcpdump_file = fopen(filename, "wb");
+ if (!tcpdump_file) {
+ fprintf(stderr, "-net dump: can't open %s\n", filename);
+ exit(1);
+ }
+
+ tcpdump_caplen = len;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = 2;
+ hdr.version_minor = 4;
+ hdr.thiszone = 0;
+ hdr.sigfigs = 0;
+ hdr.snaplen = tcpdump_caplen;
+ hdr.linktype = 1;
+
+ fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
+
+ tcpdump_vc = qemu_new_vlan_client(vlan, device, name,
+ tcpdump_receive, NULL, NULL);
+ snprintf(tcpdump_vc->info_str, sizeof(tcpdump_vc->info_str),
+ "tcpdump to %s (len=%d)", filename, len);
+ return 0;
+}
+
/* network connection */
typedef struct NetSocketState {
VLANClientState *vc;
@@ -1701,6 +1770,18 @@ int net_client_init(const char *device, const char *p)
ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
} else
#endif
+ if (!strcmp(device, "dump")) {
+ int len = 64;
+ if (get_param_value(buf, sizeof(buf), "len", p) > 0) {
+ len = strtol(buf, NULL, 0);
+ }
+
+ if (!get_param_value(buf, sizeof(buf), "file", p)) {
+ strcpy(buf, "qemu.tcpdump");
+ }
+ vlan->nb_host_devs++;
+ ret = net_tcpdump_init(vlan, device, name, buf, len);
+ } else
{
fprintf(stderr, "Unknown network device: %s\n", device);
if (name)
diff --git a/vl.c b/vl.c
index 3676537..69dbe63 100644
--- a/vl.c
+++ b/vl.c
@@ -3943,6 +3943,8 @@ static void help(int exitcode)
" Use group 'groupname' and mode 'octalmode' to change default\n"
" ownership and permissions for communication port.\n"
#endif
+ "-net dump[,vlan=n][,file=f][,len=n]\n"
+ " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
#ifdef CONFIG_SLIRP
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-04 10:22 [Qemu-devel] [Patch] Add -net dump option Tristan Gingold
@ 2009-02-06 18:53 ` Anthony Liguori
2009-02-10 11:00 ` Tristan Gingold
2009-02-07 4:09 ` Luca Bigliardi
1 sibling, 1 reply; 13+ messages in thread
From: Anthony Liguori @ 2009-02-06 18:53 UTC (permalink / raw)
To: qemu-devel
Tristan Gingold wrote:
> Hi,
>
> this patch add a new network pseudo nic that dump traffic to a tcpdump
> compatible file. I have found this feature useful to debug network protocols
> with the user stack.
>
> Signed-off-by: Tristan Gingold <gingold@adacore.com>
> Tristan.
>
>
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index b2fa19e..73c133a 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -739,6 +739,15 @@ vde_switch -F -sock /tmp/myswitch
> qemu linux.img -net nic -net vde,sock=/tmp/myswitch
> @end example
>
> +@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
> +Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu.tcpdump} by
> +default). At most @var{len} bytes (64 by default) by packet are stored. The
> +dump can be analyzed with tools such as tcpdump.
> +
> +For better results you'd better to use this option before the @samp{-net user}
>
For better results, you should use this option before the @samp{-net user}
> +one as the user stack may send replies before the initial packet was propagated
>
I'd rather you fix this properly.
> +to all receivers.
> +
> @item -net none
> Indicate that no network devices should be configured. It is used to
> override the default configuration (@option{-net nic -net user}) which
>
> diff --git a/net.c b/net.c
> index 8d9b3de..872a17e 100644
> --- a/net.c
> +++ b/net.c
> @@ -1064,6 +1064,75 @@ static int net_vde_init(VLANState *vlan, const char *model,
> }
> #endif
>
> +static VLANClientState *tcpdump_vc;
> +static FILE *tcpdump_file;
> +static int tcpdump_caplen;
>
Instead of it being globals, you should have a proper state. That way
you can use this functionality with multiple VLANs.
> +#define TCPDUMP_MAGIC 0xa1b2c3d4
> +
> +struct pcap_file_hdr {
> + uint32_t magic;
> + uint16_t version_major;
> + uint16_t version_minor;
> + int32_t thiszone;
> + uint32_t sigfigs;
> + uint32_t snaplen;
> + uint32_t linktype;
> +};
> +
> +struct pcap_sf_pkthdr {
> + struct {
> + int32_t tv_sec;
> + int32_t tv_usec;
> + } ts;
> + uint32_t caplen;
> + uint32_t len;
> +};
> +
> +static void tcpdump_receive(void *opaque, const uint8_t *buf, int size)
> +{
> + struct pcap_sf_pkthdr hdr;
> + int64_t ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
> + int caplen = size > tcpdump_caplen ? tcpdump_caplen : size;
> +
> + hdr.ts.tv_sec = ts / 1000000000LL;
> + hdr.ts.tv_usec = ts % 1000000;
> + hdr.caplen = caplen;
> + hdr.len = size;
> + fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
> + fwrite(buf, caplen, 1, tcpdump_file);
>
You should have some error checking here. Are tcpdump files always
native endian?
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-04 10:22 [Qemu-devel] [Patch] Add -net dump option Tristan Gingold
2009-02-06 18:53 ` Anthony Liguori
@ 2009-02-07 4:09 ` Luca Bigliardi
2009-02-10 11:01 ` Tristan Gingold
1 sibling, 1 reply; 13+ messages in thread
From: Luca Bigliardi @ 2009-02-07 4:09 UTC (permalink / raw)
To: qemu-devel
On Wed, Feb 04, 2009 at 11:22 AM, Tristan Gingold wrote:
> Hi,
Hi Tristan,
> this patch add a new network pseudo nic that dump traffic to a tcpdump
> compatible file. I have found this feature useful to debug network protocols
> with the user stack.
I don't know if it entirely fits your needs, but qemu already has vde
support, and vde has a pcap plugin to dump or monitor frames sent through
the switch:
http://wiki.virtualsquare.org/index.php/VDE_Basic_Networking#Dump_or_Monitor_switch_traffic
HTH,
luca
--
Beware of programmers who carry screwdrivers.
-- Leonard Brandwein
http://shammash.homelinux.org/ - http://www.artha.org/ - http://www.yue.it/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-06 18:53 ` Anthony Liguori
@ 2009-02-10 11:00 ` Tristan Gingold
2009-02-10 12:15 ` Jamie Lokier
` (3 more replies)
0 siblings, 4 replies; 13+ messages in thread
From: Tristan Gingold @ 2009-02-10 11:00 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 1560 bytes --]
Hi,
I have modified my patch according to your comments.
On Feb 6, 2009, at 7:53 PM, Anthony Liguori wrote:
> Tristan Gingold wrote:
>> Hi,
>>
>> this patch add a new network pseudo nic that dump traffic to a
>> tcpdump
>> compatible file. I have found this feature useful to debug network
>> protocols
>> with the user stack.
...
> For better results, you should use this option before the @samp{-net
> user}
>
>> +one as the user stack may send replies before the initial packet
>> was propagated
>>
>
> I'd rather you fix this properly.
I have fixed this by making slirp client somewhat special: it is
always the last client. I think this is
the simplest and most efficient method. The other ones are (that come
to my mind) are:
* slirp send packets after a small delay - somewhat complex and will
decrease performances.
* qemu_send_packet puts packet into a buffer in case of recursion -
not very good for performances.
>> +static VLANClientState *tcpdump_vc;
>> +static FILE *tcpdump_file;
>> +static int tcpdump_caplen;
>>
>
> Instead of it being globals, you should have a proper state. That
> way you can use this functionality with multiple VLANs.
Done.
>> + fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
>> + fwrite(buf, caplen, 1, tcpdump_file);
>>
>
> You should have some error checking here.
In case of write error, the dump is now stopped and a message is logged.
> Are tcpdump files always native endian?
Yes, the reader will swap.
Thanks,
Tristan.
Signed-off-by: Tristan Gingold <gingold@adacore.com>
[-- Attachment #2: dump.patch --]
[-- Type: application/octet-stream, Size: 7980 bytes --]
diff --git a/net.c b/net.c
index e7c097e..3cfae56 100644
--- a/net.c
+++ b/net.c
@@ -27,6 +27,7 @@
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "qemu-log.h"
#include "audio/audio.h"
#include <unistd.h>
@@ -324,14 +325,14 @@ static char *assign_name(VLANClientState *vc1, const char *model)
return strdup(buf);
}
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- const char *model,
- const char *name,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque)
+static VLANClientState *qemu_new_vlan_client_common(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
{
- VLANClientState *vc, **pvc;
+ VLANClientState *vc;
vc = qemu_mallocz(sizeof(VLANClientState));
vc->model = strdup(model);
if (name)
@@ -343,10 +344,54 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
vc->opaque = opaque;
vc->vlan = vlan;
- vc->next = NULL;
+ return vc;
+}
+
+VLANClientState *qemu_new_vlan_client(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ /* Append but before last_client. */
pvc = &vlan->first_client;
- while (*pvc != NULL)
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ vc->next = *pvc;
+ break;
+ }
pvc = &(*pvc)->next;
+ }
+ *pvc = vc;
+ return vc;
+}
+
+static VLANClientState *qemu_new_vlan_client_tail(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ vc->last_client = 1;
+ pvc = &vlan->first_client;
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ fprintf(stderr, "Multiple vlan last client (%s and %s)\n",
+ (*pvc)->name, name);
+ exit(1);
+ }
+ pvc = &(*pvc)->next;
+ }
*pvc = vc;
return vc;
}
@@ -503,8 +548,8 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
slirp_inited = 1;
slirp_init(slirp_restrict, slirp_ip);
}
- slirp_vc = qemu_new_vlan_client(vlan, model, name,
- slirp_receive, NULL, NULL);
+ slirp_vc = qemu_new_vlan_client_tail(vlan, model, name,
+ slirp_receive, NULL, NULL);
slirp_vc->info_str[0] = '\0';
return 0;
}
@@ -1058,6 +1103,91 @@ static int net_vde_init(VLANState *vlan, const char *model,
}
#endif
+typedef struct DumpState {
+ VLANClientState *tcpdump_vc;
+ FILE *tcpdump_file;
+ int tcpdump_caplen;
+} DumpState;
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+struct pcap_file_hdr {
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t thiszone;
+ uint32_t sigfigs;
+ uint32_t snaplen;
+ uint32_t linktype;
+};
+
+struct pcap_sf_pkthdr {
+ struct {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } ts;
+ uint32_t caplen;
+ uint32_t len;
+};
+
+static void tcpdump_receive(void *opaque, const uint8_t *buf, int size)
+{
+ DumpState *ds = (DumpState *)opaque;
+ struct pcap_sf_pkthdr hdr;
+ int64_t ts;
+ int caplen;
+
+ /* Early return in case of previous error. */
+ if (ds->tcpdump_file == NULL)
+ return;
+
+ ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
+ caplen = size > ds->tcpdump_caplen ? ds->tcpdump_caplen : size;
+
+ hdr.ts.tv_sec = ts / 1000000000LL;
+ hdr.ts.tv_usec = ts % 1000000;
+ hdr.caplen = caplen;
+ hdr.len = size;
+ if (fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file) != 1
+ || fwrite(buf, caplen, 1, ds->tcpdump_file) != 1) {
+ qemu_log("-net dump write error - stop dump\n");
+ fclose(ds->tcpdump_file);
+ ds->tcpdump_file = NULL;
+ }
+}
+
+static int net_tcpdump_init(VLANState *vlan, const char *device,
+ const char *name, const char *filename, int len)
+{
+ struct pcap_file_hdr hdr;
+ DumpState *ds;
+
+ ds = qemu_malloc (sizeof (DumpState));
+ ds->tcpdump_file = fopen(filename, "wb");
+ if (!ds->tcpdump_file) {
+ fprintf(stderr, "-net dump: can't open %s\n", filename);
+ exit(1);
+ }
+
+ ds->tcpdump_caplen = len;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = 2;
+ hdr.version_minor = 4;
+ hdr.thiszone = 0;
+ hdr.sigfigs = 0;
+ hdr.snaplen = ds->tcpdump_caplen;
+ hdr.linktype = 1;
+
+ fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file);
+
+ ds->tcpdump_vc = qemu_new_vlan_client(vlan, device, name,
+ tcpdump_receive, NULL, ds);
+ snprintf(ds->tcpdump_vc->info_str, sizeof(ds->tcpdump_vc->info_str),
+ "tcpdump to %s (len=%d)", filename, len);
+ return 0;
+}
+
/* network connection */
typedef struct NetSocketState {
VLANClientState *vc;
@@ -1687,6 +1817,20 @@ int net_client_init(const char *device, const char *p)
ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
} else
#endif
+ if (!strcmp(device, "dump")) {
+ int len = 64;
+ if (get_param_value(buf, sizeof(buf), "len", p) > 0) {
+ len = strtol(buf, NULL, 0);
+ }
+
+ if (!get_param_value(buf, sizeof(buf), "file", p)) {
+ if (vlan_id == 0)
+ strcpy(buf, "qemu.tcpdump");
+ else
+ snprintf(buf, sizeof(buf), "qemu-vlan%d.tcpdump", vlan_id);
+ }
+ ret = net_tcpdump_init(vlan, device, name, buf, len);
+ } else
{
fprintf(stderr, "Unknown network device: %s\n", device);
if (name)
diff --git a/net.h b/net.h
index 291807a..a109067 100644
--- a/net.h
+++ b/net.h
@@ -19,6 +19,9 @@ struct VLANClientState {
IOCanRWHandler *fd_can_read;
LinkStatusChanged *link_status_changed;
int link_down;
+ /* If set this client must be the last in the VLAN (currently set only
+ by slirp). */
+ int last_client;
void *opaque;
struct VLANClientState *next;
struct VLANState *vlan;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index efb88d2..3c78b49 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -739,6 +739,11 @@ vde_switch -F -sock /tmp/myswitch
qemu linux.img -net nic -net vde,sock=/tmp/myswitch
@end example
+@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu.tcpdump} by
+default). At most @var{len} bytes (64 by default) by packet are stored. The
+dump can be analyzed with tools such as tcpdump.
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration (@option{-net nic -net user}) which
diff --git a/vl.c b/vl.c
index aff2b2c..2704251 100644
--- a/vl.c
+++ b/vl.c
@@ -3927,6 +3927,8 @@ static void help(int exitcode)
" Use group 'groupname' and mode 'octalmode' to change default\n"
" ownership and permissions for communication port.\n"
#endif
+ "-net dump[,vlan=n][,file=f][,len=n]\n"
+ " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
#ifdef CONFIG_SLIRP
[-- Attachment #3: Type: text/plain, Size: 1 bytes --]
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-07 4:09 ` Luca Bigliardi
@ 2009-02-10 11:01 ` Tristan Gingold
2009-02-10 17:04 ` [Qemu-devel] SET rezo-actu DIGEST GAYET Thierry
0 siblings, 1 reply; 13+ messages in thread
From: Tristan Gingold @ 2009-02-10 11:01 UTC (permalink / raw)
To: qemu-devel
On Feb 7, 2009, at 5:09 AM, Luca Bigliardi wrote:
> On Wed, Feb 04, 2009 at 11:22 AM, Tristan Gingold wrote:
>
>> Hi,
>
> Hi Tristan,
>
>> this patch add a new network pseudo nic that dump traffic to a
>> tcpdump
>> compatible file. I have found this feature useful to debug network
>> protocols
>> with the user stack.
>
> I don't know if it entirely fits your needs, but qemu already has vde
> support, and vde has a pcap plugin to dump or monitor frames sent
> through
> the switch:
> http://wiki.virtualsquare.org/index.php/VDE_Basic_Networking#Dump_or_Monitor_switch_traffic
Thank you for the tip but it looks like vde runs only on Linux (?) and
is much more complex to set up than
just having a new option. I have the '-net dump' mostly to debug
network setup and therefore I prefer
the simplest methods.
Tristan.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-10 11:00 ` Tristan Gingold
@ 2009-02-10 12:15 ` Jamie Lokier
2009-02-10 12:59 ` Tristan Gingold
2009-02-13 14:01 ` [Qemu-devel] Ping: [Patch] Add -net dump option (v2) Tristan Gingold
` (2 subsequent siblings)
3 siblings, 1 reply; 13+ messages in thread
From: Jamie Lokier @ 2009-02-10 12:15 UTC (permalink / raw)
To: qemu-devel
Tristan Gingold wrote:
> I have fixed this by making slirp client somewhat special: it is
> always the last client. I think this is
> the simplest and most efficient method.
Does this change mean "-net user -net user" no longer crashes after
overflowing the stack? :-)
-- Jamie
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-10 12:15 ` Jamie Lokier
@ 2009-02-10 12:59 ` Tristan Gingold
2009-02-10 22:05 ` Jamie Lokier
0 siblings, 1 reply; 13+ messages in thread
From: Tristan Gingold @ 2009-02-10 12:59 UTC (permalink / raw)
To: qemu-devel
On Feb 10, 2009, at 1:15 PM, Jamie Lokier wrote:
> Tristan Gingold wrote:
>> I have fixed this by making slirp client somewhat special: it is
>> always the last client. I think this is
>> the simplest and most efficient method.
>
> Does this change mean "-net user -net user" no longer crashes after
> overflowing the stack? :-)
This patch makes "-net user -net user" not possible because you can't
have two last clients.
Slightly better ;-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] SET rezo-actu DIGEST
2009-02-10 11:01 ` Tristan Gingold
@ 2009-02-10 17:04 ` GAYET Thierry
0 siblings, 0 replies; 13+ messages in thread
From: GAYET Thierry @ 2009-02-10 17:04 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 251 bytes --]
__________________________________________________________________________________________________
Ne pleurez pas si votre Webmail ferme ! Récupérez votre historique sur Yahoo! Mail ! http://fr.docs.yahoo.com/mail/transfert_mails.html
[-- Attachment #2: Type: text/html, Size: 406 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-10 12:59 ` Tristan Gingold
@ 2009-02-10 22:05 ` Jamie Lokier
0 siblings, 0 replies; 13+ messages in thread
From: Jamie Lokier @ 2009-02-10 22:05 UTC (permalink / raw)
To: qemu-devel
Tristan Gingold wrote:
>
> On Feb 10, 2009, at 1:15 PM, Jamie Lokier wrote:
>
> >Tristan Gingold wrote:
> >>I have fixed this by making slirp client somewhat special: it is
> >>always the last client. I think this is
> >>the simplest and most efficient method.
> >
> >Does this change mean "-net user -net user" no longer crashes after
> >overflowing the stack? :-)
>
> This patch makes "-net user -net user" not possible because you can't
> have two last clients.
> Slightly better ;-)
Much better. :-)
I spent a few hours once wondering why QEMU worked great until the
Windows guest did its first network access, and then QEMU crashed...
Turns out I was passing "-net user" twice on the command line, due to
a typo in my management program.
I'd already had to find workarounds for other crashes in the guest and
a bug in QEMU up to that point, so I wasn't expecting it to be so simple :-)
-- Jamie
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] Ping: [Patch] Add -net dump option (v2)
2009-02-10 11:00 ` Tristan Gingold
2009-02-10 12:15 ` Jamie Lokier
@ 2009-02-13 14:01 ` Tristan Gingold
2009-02-23 15:30 ` [Qemu-devel] Ping*2: [Patch-v2] Add -net dump option Tristan Gingold
2009-02-27 19:09 ` [Qemu-devel] [Patch] " Anthony Liguori
3 siblings, 0 replies; 13+ messages in thread
From: Tristan Gingold @ 2009-02-13 14:01 UTC (permalink / raw)
To: qemu-devel
Ping for the second version of the patch.
Tristan.
On Feb 10, 2009, at 12:00 PM, Tristan Gingold wrote:
>
> Hi,
>
> I have modified my patch according to your comments.
>
> On Feb 6, 2009, at 7:53 PM, Anthony Liguori wrote:
>
>> Tristan Gingold wrote:
>>> Hi,
>>>
>>> this patch add a new network pseudo nic that dump traffic to a
>>> tcpdump
>>> compatible file. I have found this feature useful to debug
>>> network protocols
>>> with the user stack.
>
> ...
>
>> For better results, you should use this option before the @samp{-
>> net user}
>>
>>> +one as the user stack may send replies before the initial packet
>>> was propagated
>>>
>>
>> I'd rather you fix this properly.
>
> I have fixed this by making slirp client somewhat special: it is
> always the last client. I think this is
> the simplest and most efficient method. The other ones are (that
> come to my mind) are:
> * slirp send packets after a small delay - somewhat complex and will
> decrease performances.
> * qemu_send_packet puts packet into a buffer in case of recursion -
> not very good for performances.
>
>>> +static VLANClientState *tcpdump_vc;
>>> +static FILE *tcpdump_file;
>>> +static int tcpdump_caplen;
>>>
>>
>> Instead of it being globals, you should have a proper state. That
>> way you can use this functionality with multiple VLANs.
>
> Done.
>
>>> + fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
>>> + fwrite(buf, caplen, 1, tcpdump_file);
>>>
>>
>> You should have some error checking here.
>
> In case of write error, the dump is now stopped and a message is
> logged.
>
>> Are tcpdump files always native endian?
>
> Yes, the reader will swap.
>
> Thanks,
> Tristan.
>
> Signed-off-by: Tristan Gingold <gingold@adacore.com>
> <dump.patch>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] Ping*2: [Patch-v2] Add -net dump option
2009-02-10 11:00 ` Tristan Gingold
2009-02-10 12:15 ` Jamie Lokier
2009-02-13 14:01 ` [Qemu-devel] Ping: [Patch] Add -net dump option (v2) Tristan Gingold
@ 2009-02-23 15:30 ` Tristan Gingold
2009-02-27 19:09 ` [Qemu-devel] [Patch] " Anthony Liguori
3 siblings, 0 replies; 13+ messages in thread
From: Tristan Gingold @ 2009-02-23 15:30 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 20 bytes --]
Ping * 2
Tristan.
[-- Attachment #2: dump.patch --]
[-- Type: application/octet-stream, Size: 7980 bytes --]
diff --git a/net.c b/net.c
index e7c097e..3cfae56 100644
--- a/net.c
+++ b/net.c
@@ -27,6 +27,7 @@
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "qemu-log.h"
#include "audio/audio.h"
#include <unistd.h>
@@ -324,14 +325,14 @@ static char *assign_name(VLANClientState *vc1, const char *model)
return strdup(buf);
}
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- const char *model,
- const char *name,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque)
+static VLANClientState *qemu_new_vlan_client_common(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
{
- VLANClientState *vc, **pvc;
+ VLANClientState *vc;
vc = qemu_mallocz(sizeof(VLANClientState));
vc->model = strdup(model);
if (name)
@@ -343,10 +344,54 @@ VLANClientState *qemu_new_vlan_client(VLANState *vlan,
vc->opaque = opaque;
vc->vlan = vlan;
- vc->next = NULL;
+ return vc;
+}
+
+VLANClientState *qemu_new_vlan_client(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ /* Append but before last_client. */
pvc = &vlan->first_client;
- while (*pvc != NULL)
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ vc->next = *pvc;
+ break;
+ }
pvc = &(*pvc)->next;
+ }
+ *pvc = vc;
+ return vc;
+}
+
+static VLANClientState *qemu_new_vlan_client_tail(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ vc->last_client = 1;
+ pvc = &vlan->first_client;
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ fprintf(stderr, "Multiple vlan last client (%s and %s)\n",
+ (*pvc)->name, name);
+ exit(1);
+ }
+ pvc = &(*pvc)->next;
+ }
*pvc = vc;
return vc;
}
@@ -503,8 +548,8 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
slirp_inited = 1;
slirp_init(slirp_restrict, slirp_ip);
}
- slirp_vc = qemu_new_vlan_client(vlan, model, name,
- slirp_receive, NULL, NULL);
+ slirp_vc = qemu_new_vlan_client_tail(vlan, model, name,
+ slirp_receive, NULL, NULL);
slirp_vc->info_str[0] = '\0';
return 0;
}
@@ -1058,6 +1103,91 @@ static int net_vde_init(VLANState *vlan, const char *model,
}
#endif
+typedef struct DumpState {
+ VLANClientState *tcpdump_vc;
+ FILE *tcpdump_file;
+ int tcpdump_caplen;
+} DumpState;
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+struct pcap_file_hdr {
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t thiszone;
+ uint32_t sigfigs;
+ uint32_t snaplen;
+ uint32_t linktype;
+};
+
+struct pcap_sf_pkthdr {
+ struct {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } ts;
+ uint32_t caplen;
+ uint32_t len;
+};
+
+static void tcpdump_receive(void *opaque, const uint8_t *buf, int size)
+{
+ DumpState *ds = (DumpState *)opaque;
+ struct pcap_sf_pkthdr hdr;
+ int64_t ts;
+ int caplen;
+
+ /* Early return in case of previous error. */
+ if (ds->tcpdump_file == NULL)
+ return;
+
+ ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
+ caplen = size > ds->tcpdump_caplen ? ds->tcpdump_caplen : size;
+
+ hdr.ts.tv_sec = ts / 1000000000LL;
+ hdr.ts.tv_usec = ts % 1000000;
+ hdr.caplen = caplen;
+ hdr.len = size;
+ if (fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file) != 1
+ || fwrite(buf, caplen, 1, ds->tcpdump_file) != 1) {
+ qemu_log("-net dump write error - stop dump\n");
+ fclose(ds->tcpdump_file);
+ ds->tcpdump_file = NULL;
+ }
+}
+
+static int net_tcpdump_init(VLANState *vlan, const char *device,
+ const char *name, const char *filename, int len)
+{
+ struct pcap_file_hdr hdr;
+ DumpState *ds;
+
+ ds = qemu_malloc (sizeof (DumpState));
+ ds->tcpdump_file = fopen(filename, "wb");
+ if (!ds->tcpdump_file) {
+ fprintf(stderr, "-net dump: can't open %s\n", filename);
+ exit(1);
+ }
+
+ ds->tcpdump_caplen = len;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = 2;
+ hdr.version_minor = 4;
+ hdr.thiszone = 0;
+ hdr.sigfigs = 0;
+ hdr.snaplen = ds->tcpdump_caplen;
+ hdr.linktype = 1;
+
+ fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file);
+
+ ds->tcpdump_vc = qemu_new_vlan_client(vlan, device, name,
+ tcpdump_receive, NULL, ds);
+ snprintf(ds->tcpdump_vc->info_str, sizeof(ds->tcpdump_vc->info_str),
+ "tcpdump to %s (len=%d)", filename, len);
+ return 0;
+}
+
/* network connection */
typedef struct NetSocketState {
VLANClientState *vc;
@@ -1687,6 +1817,20 @@ int net_client_init(const char *device, const char *p)
ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
} else
#endif
+ if (!strcmp(device, "dump")) {
+ int len = 64;
+ if (get_param_value(buf, sizeof(buf), "len", p) > 0) {
+ len = strtol(buf, NULL, 0);
+ }
+
+ if (!get_param_value(buf, sizeof(buf), "file", p)) {
+ if (vlan_id == 0)
+ strcpy(buf, "qemu.tcpdump");
+ else
+ snprintf(buf, sizeof(buf), "qemu-vlan%d.tcpdump", vlan_id);
+ }
+ ret = net_tcpdump_init(vlan, device, name, buf, len);
+ } else
{
fprintf(stderr, "Unknown network device: %s\n", device);
if (name)
diff --git a/net.h b/net.h
index 291807a..a109067 100644
--- a/net.h
+++ b/net.h
@@ -19,6 +19,9 @@ struct VLANClientState {
IOCanRWHandler *fd_can_read;
LinkStatusChanged *link_status_changed;
int link_down;
+ /* If set this client must be the last in the VLAN (currently set only
+ by slirp). */
+ int last_client;
void *opaque;
struct VLANClientState *next;
struct VLANState *vlan;
diff --git a/qemu-doc.texi b/qemu-doc.texi
index efb88d2..3c78b49 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -739,6 +739,11 @@ vde_switch -F -sock /tmp/myswitch
qemu linux.img -net nic -net vde,sock=/tmp/myswitch
@end example
+@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu.tcpdump} by
+default). At most @var{len} bytes (64 by default) by packet are stored. The
+dump can be analyzed with tools such as tcpdump.
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration (@option{-net nic -net user}) which
diff --git a/vl.c b/vl.c
index aff2b2c..2704251 100644
--- a/vl.c
+++ b/vl.c
@@ -3927,6 +3927,8 @@ static void help(int exitcode)
" Use group 'groupname' and mode 'octalmode' to change default\n"
" ownership and permissions for communication port.\n"
#endif
+ "-net dump[,vlan=n][,file=f][,len=n]\n"
+ " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
#ifdef CONFIG_SLIRP
[-- Attachment #3: Type: text/plain, Size: 1715 bytes --]
On Feb 10, 2009, at 12:00 PM, Tristan Gingold wrote:
>
> Hi,
>
> I have modified my patch according to your comments.
>
> On Feb 6, 2009, at 7:53 PM, Anthony Liguori wrote:
>
>> Tristan Gingold wrote:
>>> Hi,
>>>
>>> this patch add a new network pseudo nic that dump traffic to a
>>> tcpdump
>>> compatible file. I have found this feature useful to debug
>>> network protocols
>>> with the user stack.
>
> ...
>
>> For better results, you should use this option before the @samp{-
>> net user}
>>
>>> +one as the user stack may send replies before the initial packet
>>> was propagated
>>>
>>
>> I'd rather you fix this properly.
>
> I have fixed this by making slirp client somewhat special: it is
> always the last client. I think this is
> the simplest and most efficient method. The other ones are (that
> come to my mind) are:
> * slirp send packets after a small delay - somewhat complex and will
> decrease performances.
> * qemu_send_packet puts packet into a buffer in case of recursion -
> not very good for performances.
>
>>> +static VLANClientState *tcpdump_vc;
>>> +static FILE *tcpdump_file;
>>> +static int tcpdump_caplen;
>>>
>>
>> Instead of it being globals, you should have a proper state. That
>> way you can use this functionality with multiple VLANs.
>
> Done.
>
>>> + fwrite(&hdr, sizeof(hdr), 1, tcpdump_file);
>>> + fwrite(buf, caplen, 1, tcpdump_file);
>>>
>>
>> You should have some error checking here.
>
> In case of write error, the dump is now stopped and a message is
> logged.
>
>> Are tcpdump files always native endian?
>
> Yes, the reader will swap.
>
> Thanks,
> Tristan.
>
> Signed-off-by: Tristan Gingold <gingold@adacore.com>
> <dump.patch>
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [Qemu-devel] [Patch] Add -net dump option
2009-02-10 11:00 ` Tristan Gingold
` (2 preceding siblings ...)
2009-02-23 15:30 ` [Qemu-devel] Ping*2: [Patch-v2] Add -net dump option Tristan Gingold
@ 2009-02-27 19:09 ` Anthony Liguori
3 siblings, 0 replies; 13+ messages in thread
From: Anthony Liguori @ 2009-02-27 19:09 UTC (permalink / raw)
To: qemu-devel
Tristan Gingold wrote:
>
> Signed-off-by: Tristan Gingold <gingold@adacore.com>
Please resend either inlining the patch or attachign text/plain.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 13+ messages in thread
* [Qemu-devel] [Patch] Add -net dump option
@ 2009-03-05 10:10 Tristan Gingold
0 siblings, 0 replies; 13+ messages in thread
From: Tristan Gingold @ 2009-03-05 10:10 UTC (permalink / raw)
To: qemu-devel; +Cc: aliguori
Hi,
latest version of the patch inlined.
Signed-off-by: Tristan Gingold <gingold@adacore.com>
Thanks,
Tristan.
Index: vl.c
===================================================================
--- vl.c (revision 6685)
+++ vl.c (working copy)
@@ -3987,6 +3987,8 @@
" Use group 'groupname' and mode 'octalmode' to change default\n"
" ownership and permissions for communication port.\n"
#endif
+ "-net dump[,vlan=n][,file=f][,len=n]\n"
+ " dump traffic on vlan 'n' to file 'f' (max n bytes per packet)\n"
"-net none use it alone to have zero network devices; if no -net option\n"
" is provided, the default is '-net nic -net user'\n"
#ifdef CONFIG_SLIRP
Index: net.c
===================================================================
--- net.c (revision 6685)
+++ net.c (working copy)
@@ -27,6 +27,7 @@
#include "sysemu.h"
#include "qemu-timer.h"
#include "qemu-char.h"
+#include "qemu-log.h"
#include "audio/audio.h"
#include <unistd.h>
@@ -324,14 +325,14 @@
return strdup(buf);
}
-VLANClientState *qemu_new_vlan_client(VLANState *vlan,
- const char *model,
- const char *name,
- IOReadHandler *fd_read,
- IOCanRWHandler *fd_can_read,
- void *opaque)
+static VLANClientState *qemu_new_vlan_client_common(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
{
- VLANClientState *vc, **pvc;
+ VLANClientState *vc;
vc = qemu_mallocz(sizeof(VLANClientState));
vc->model = strdup(model);
if (name)
@@ -343,14 +344,58 @@
vc->opaque = opaque;
vc->vlan = vlan;
- vc->next = NULL;
+ return vc;
+}
+
+VLANClientState *qemu_new_vlan_client(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ /* Append but before last_client. */
pvc = &vlan->first_client;
- while (*pvc != NULL)
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ vc->next = *pvc;
+ break;
+ }
pvc = &(*pvc)->next;
+ }
*pvc = vc;
return vc;
}
+static VLANClientState *qemu_new_vlan_client_tail(VLANState *vlan,
+ const char *model,
+ const char *name,
+ IOReadHandler *fd_read,
+ IOCanRWHandler *fd_can_read,
+ void *opaque)
+{
+ VLANClientState *vc, **pvc;
+
+ vc = qemu_new_vlan_client_common(vlan, model, name, fd_read, fd_can_read,
+ opaque);
+ vc->last_client = 1;
+ pvc = &vlan->first_client;
+ while (*pvc != NULL) {
+ if ((*pvc)->last_client) {
+ fprintf(stderr, "Multiple vlan last client (%s and %s)\n",
+ (*pvc)->name, name);
+ exit(1);
+ }
+ pvc = &(*pvc)->next;
+ }
+ *pvc = vc;
+ return vc;
+}
+
void qemu_del_vlan_client(VLANClientState *vc)
{
VLANClientState **pvc = &vc->vlan->first_client;
@@ -516,8 +561,8 @@
slirp_inited = 1;
slirp_init(slirp_restrict, slirp_ip);
}
- slirp_vc = qemu_new_vlan_client(vlan, model, name,
- slirp_receive, NULL, NULL);
+ slirp_vc = qemu_new_vlan_client_tail(vlan, model, name,
+ slirp_receive, NULL, NULL);
slirp_vc->info_str[0] = '\0';
return 0;
}
@@ -1088,6 +1133,91 @@
}
#endif
+typedef struct DumpState {
+ VLANClientState *tcpdump_vc;
+ FILE *tcpdump_file;
+ int tcpdump_caplen;
+} DumpState;
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+struct pcap_file_hdr {
+ uint32_t magic;
+ uint16_t version_major;
+ uint16_t version_minor;
+ int32_t thiszone;
+ uint32_t sigfigs;
+ uint32_t snaplen;
+ uint32_t linktype;
+};
+
+struct pcap_sf_pkthdr {
+ struct {
+ int32_t tv_sec;
+ int32_t tv_usec;
+ } ts;
+ uint32_t caplen;
+ uint32_t len;
+};
+
+static void tcpdump_receive(void *opaque, const uint8_t *buf, int size)
+{
+ DumpState *ds = (DumpState *)opaque;
+ struct pcap_sf_pkthdr hdr;
+ int64_t ts;
+ int caplen;
+
+ /* Early return in case of previous error. */
+ if (ds->tcpdump_file == NULL)
+ return;
+
+ ts = muldiv64 (qemu_get_clock(vm_clock),1000000, ticks_per_sec);
+ caplen = size > ds->tcpdump_caplen ? ds->tcpdump_caplen : size;
+
+ hdr.ts.tv_sec = ts / 1000000000LL;
+ hdr.ts.tv_usec = ts % 1000000;
+ hdr.caplen = caplen;
+ hdr.len = size;
+ if (fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file) != 1
+ || fwrite(buf, caplen, 1, ds->tcpdump_file) != 1) {
+ qemu_log("-net dump write error - stop dump\n");
+ fclose(ds->tcpdump_file);
+ ds->tcpdump_file = NULL;
+ }
+}
+
+static int net_tcpdump_init(VLANState *vlan, const char *device,
+ const char *name, const char *filename, int len)
+{
+ struct pcap_file_hdr hdr;
+ DumpState *ds;
+
+ ds = qemu_malloc (sizeof (DumpState));
+ ds->tcpdump_file = fopen(filename, "wb");
+ if (!ds->tcpdump_file) {
+ fprintf(stderr, "-net dump: can't open %s\n", filename);
+ exit(1);
+ }
+
+ ds->tcpdump_caplen = len;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = 2;
+ hdr.version_minor = 4;
+ hdr.thiszone = 0;
+ hdr.sigfigs = 0;
+ hdr.snaplen = ds->tcpdump_caplen;
+ hdr.linktype = 1;
+
+ fwrite(&hdr, sizeof(hdr), 1, ds->tcpdump_file);
+
+ ds->tcpdump_vc = qemu_new_vlan_client(vlan, device, name,
+ tcpdump_receive, NULL, ds);
+ snprintf(ds->tcpdump_vc->info_str, sizeof(ds->tcpdump_vc->info_str),
+ "tcpdump to %s (len=%d)", filename, len);
+ return 0;
+}
+
/* network connection */
typedef struct NetSocketState {
VLANClientState *vc;
@@ -1762,6 +1892,20 @@
ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);
} else
#endif
+ if (!strcmp(device, "dump")) {
+ int len = 64;
+ if (get_param_value(buf, sizeof(buf), "len", p) > 0) {
+ len = strtol(buf, NULL, 0);
+ }
+
+ if (!get_param_value(buf, sizeof(buf), "file", p)) {
+ if (vlan_id == 0)
+ strcpy(buf, "qemu.tcpdump");
+ else
+ snprintf(buf, sizeof(buf), "qemu-vlan%d.tcpdump", vlan_id);
+ }
+ ret = net_tcpdump_init(vlan, device, name, buf, len);
+ } else
{
fprintf(stderr, "Unknown network device: %s\n", device);
if (name)
Index: net.h
===================================================================
--- net.h (revision 6685)
+++ net.h (working copy)
@@ -19,6 +19,9 @@
IOCanRWHandler *fd_can_read;
LinkStatusChanged *link_status_changed;
int link_down;
+ /* If set this client must be the last in the VLAN (currently set only
+ by slirp). */
+ int last_client;
void *opaque;
struct VLANClientState *next;
struct VLANState *vlan;
Index: qemu-doc.texi
===================================================================
--- qemu-doc.texi (revision 6685)
+++ qemu-doc.texi (working copy)
@@ -742,6 +742,11 @@
qemu linux.img -net nic -net vde,sock=/tmp/myswitch
@end example
+@item -net dump[,vlan=@var{n}][,file=@var{file}][,len=@var{len}]
+Dump network traffic on VLAN @var{n} to file @var{file} (@file{qemu.tcpdump} by
+default). At most @var{len} bytes (64 by default) by packet are stored. The
+dump can be analyzed with tools such as tcpdump.
+
@item -net none
Indicate that no network devices should be configured. It is used to
override the default configuration (@option{-net nic -net user}) which
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2009-03-05 10:10 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-04 10:22 [Qemu-devel] [Patch] Add -net dump option Tristan Gingold
2009-02-06 18:53 ` Anthony Liguori
2009-02-10 11:00 ` Tristan Gingold
2009-02-10 12:15 ` Jamie Lokier
2009-02-10 12:59 ` Tristan Gingold
2009-02-10 22:05 ` Jamie Lokier
2009-02-13 14:01 ` [Qemu-devel] Ping: [Patch] Add -net dump option (v2) Tristan Gingold
2009-02-23 15:30 ` [Qemu-devel] Ping*2: [Patch-v2] Add -net dump option Tristan Gingold
2009-02-27 19:09 ` [Qemu-devel] [Patch] " Anthony Liguori
2009-02-07 4:09 ` Luca Bigliardi
2009-02-10 11:01 ` Tristan Gingold
2009-02-10 17:04 ` [Qemu-devel] SET rezo-actu DIGEST GAYET Thierry
-- strict thread matches above, loose matches on Subject: below --
2009-03-05 10:10 [Qemu-devel] [Patch] Add -net dump option Tristan Gingold
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.