* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).