[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH RFC 2/4] net: Introduce NetClientDump and auxiliary
From: |
Miguel Di Ciurcio Filho |
Subject: |
[Qemu-devel] [PATCH RFC 2/4] net: Introduce NetClientDump and auxiliary functions |
Date: |
Thu, 15 Jul 2010 17:22:58 -0300 |
Signed-off-by: Miguel Di Ciurcio Filho <address@hidden>
---
net.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
net.h | 8 +++++
qemu-common.h | 1 +
3 files changed, 99 insertions(+), 0 deletions(-)
diff --git a/net.c b/net.c
index 8ddf872..6f125f8 100644
--- a/net.c
+++ b/net.c
@@ -42,6 +42,36 @@ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
int default_net = 1;
+static void pcap_dump(NetClientDump *net_client_dump, const uint8_t *buf,
size_t size)
+{
+ struct pcap_sf_pkthdr hdr;
+ int64_t ts;
+ int caplen;
+
+ if (!net_client_dump) {
+ return;
+ }
+
+ /* Early return in case of previous error. */
+ if (net_client_dump->fd < 0) {
+ return;
+ }
+
+ ts = muldiv64(qemu_get_clock(vm_clock), 1000000, get_ticks_per_sec());
+ caplen = size > net_client_dump->pcap_caplen ?
net_client_dump->pcap_caplen : size;
+
+ hdr.ts.tv_sec = ts / 1000000;
+ hdr.ts.tv_usec = ts % 1000000;
+ hdr.caplen = caplen;
+ hdr.len = size;
+ if (write(net_client_dump->fd, &hdr, sizeof(hdr)) != sizeof(hdr) ||
+ write(net_client_dump->fd, buf, caplen) != caplen) {
+ error_report("Error writing pcap dump, closing descriptor.");
+ close(net_client_dump->fd);
+ net_client_dump->fd = -1;
+ }
+}
+
/***********************************************************/
/* network device redirectors */
@@ -495,6 +525,7 @@ static ssize_t
qemu_send_packet_async_with_flags(VLANClientState *sender,
NetPacketSent *sent_cb)
{
NetQueue *queue;
+ NetClientDump *dump;
#ifdef DEBUG_NET
printf("qemu_send_packet_async:\n");
@@ -507,6 +538,14 @@ static ssize_t
qemu_send_packet_async_with_flags(VLANClientState *sender,
if (sender->peer) {
queue = sender->peer->send_queue;
+ if (sender->dump || sender->peer->dump) {
+ if (sender->dump) {
+ dump = sender->dump;
+ } else {
+ dump = sender->peer->dump;
+ }
+ pcap_dump(dump, buf, size);
+ }
} else {
queue = sender->vlan->send_queue;
}
@@ -621,6 +660,8 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender,
NetPacketSent *sent_cb)
{
NetQueue *queue;
+ NetClientDump *dump;
+ int i;
if (sender->link_down || (!sender->peer && !sender->vlan)) {
return calc_iov_length(iov, iovcnt);
@@ -628,6 +669,17 @@ ssize_t qemu_sendv_packet_async(VLANClientState *sender,
if (sender->peer) {
queue = sender->peer->send_queue;
+ if (sender->dump || sender->peer->dump) {
+ if (sender->dump) {
+ dump = sender->dump;
+ } else {
+ dump = sender->peer->dump;
+ }
+ /* XXX handle vnet_hdr headers or dump will be corrupt */
+ for (i = 0; i < iovcnt; i++) {
+ pcap_dump(dump, (const uint8_t*)iov[i].iov_base,
iov[i].iov_len);
+ }
+ }
} else {
queue = sender->vlan->send_queue;
}
@@ -1347,6 +1399,44 @@ static int net_init_netdev(QemuOpts *opts, void *dummy)
return net_client_init(NULL, opts, 1);
}
+NetClientDump *net_client_create_dump(const char *filename, int len) {
+ NetClientDump *net_client_dump;
+ struct pcap_file_hdr hdr;
+ int fd;
+
+ fd = open(filename, O_CREAT | O_WRONLY | O_BINARY, 0644);
+ if (fd < 0) {
+ error_report("Cannot create dump file: %s", filename);
+ return NULL;
+ }
+
+ if (!len) {
+ len = 65536;
+ }
+
+ hdr.magic = PCAP_MAGIC;
+ hdr.version_major = 2;
+ hdr.version_minor = 4;
+ hdr.thiszone = 0;
+ hdr.sigfigs = 0;
+ hdr.snaplen = len;
+ hdr.linktype = 1;
+
+ if (write(fd, &hdr, sizeof(hdr)) < sizeof(hdr)) {
+ error_report("Error writing dump file error: %s", strerror(errno));
+ close(fd);
+ return NULL;
+ }
+
+ net_client_dump = qemu_malloc(sizeof(NetClientDump));
+ net_client_dump->fd = fd;
+ net_client_dump->pcap_caplen = len;
+ pstrcpy(net_client_dump->filename, sizeof(char[128]), filename);
+
+ return net_client_dump;
+
+}
+
int net_init_clients(void)
{
if (default_net) {
diff --git a/net.h b/net.h
index 518cf9c..9a95db5 100644
--- a/net.h
+++ b/net.h
@@ -55,6 +55,12 @@ typedef struct NetClientInfo {
NetPoll *poll;
} NetClientInfo;
+struct NetClientDump {
+ int fd;
+ int pcap_caplen;
+ char filename[128];
+};
+
struct VLANClientState {
NetClientInfo *info;
int link_down;
@@ -66,6 +72,7 @@ struct VLANClientState {
char *name;
char info_str[256];
unsigned receive_disabled : 1;
+ NetClientDump *dump;
};
typedef struct NICState {
@@ -81,6 +88,7 @@ struct VLANState {
NetQueue *send_queue;
};
+NetClientDump *net_client_create_dump(const char *filename, int len);
VLANState *qemu_find_vlan(int id, int allocate);
VLANClientState *qemu_find_netdev(const char *id);
VLANClientState *qemu_new_net_client(NetClientInfo *info,
diff --git a/qemu-common.h b/qemu-common.h
index 3fb2f0b..7354775 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -212,6 +212,7 @@ typedef struct CharDriverState CharDriverState;
typedef struct MACAddr MACAddr;
typedef struct VLANState VLANState;
typedef struct VLANClientState VLANClientState;
+typedef struct NetClientDump NetClientDump;
typedef struct i2c_bus i2c_bus;
typedef struct i2c_slave i2c_slave;
typedef struct SMBusDevice SMBusDevice;
--
1.7.1
- [Qemu-devel] [PATCH RFC 0/4] Dumping traffic when using netdev devices, Miguel Di Ciurcio Filho, 2010/07/15
- [Qemu-devel] [PATCH RFC 1/4] net/dump: Make pcap structures public, Miguel Di Ciurcio Filho, 2010/07/15
- [Qemu-devel] [PATCH RFC 2/4] net: Introduce NetClientDump and auxiliary functions,
Miguel Di Ciurcio Filho <=
- [Qemu-devel] [PATCH RFC 3/4] net/tap: Suggested support for NetClientDump, Miguel Di Ciurcio Filho, 2010/07/15
- [Qemu-devel] [PATCH RFC 4/4] net/slirp: Suggested support for NetClientDump, Miguel Di Ciurcio Filho, 2010/07/15
- [Qemu-devel] Re: [PATCH RFC 0/4] Dumping traffic when using netdev devices, Jan Kiszka, 2010/07/16
- [Qemu-devel] Re: [PATCH RFC 0/4] Dumping traffic when using netdev devices, Anthony Liguori, 2010/07/16
- [Qemu-devel] Re: [PATCH RFC 0/4] Dumping traffic when using netdev devices, Jan Kiszka, 2010/07/16