From patchwork Thu Jul 15 20:22:58 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miguel Di Ciurcio Filho X-Patchwork-Id: 59042 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 5E52FB6F1A for ; Fri, 16 Jul 2010 06:27:12 +1000 (EST) Received: from localhost ([127.0.0.1]:53473 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OZV1R-0003Wv-Ao for incoming@patchwork.ozlabs.org; Thu, 15 Jul 2010 16:27:09 -0400 Received: from [140.186.70.92] (port=56905 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OZUxZ-0002Ly-R8 for qemu-devel@nongnu.org; Thu, 15 Jul 2010 16:23:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OZUxX-0006Qb-9g for qemu-devel@nongnu.org; Thu, 15 Jul 2010 16:23:09 -0400 Received: from mail-gy0-f173.google.com ([209.85.160.173]:56471) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OZUxX-0006QJ-3a for qemu-devel@nongnu.org; Thu, 15 Jul 2010 16:23:07 -0400 Received: by gyf2 with SMTP id 2so916386gyf.4 for ; Thu, 15 Jul 2010 13:23:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=c/XgHlR1tVSO+zggOGwg9bkTenPCQJrn+RJpHwwByCA=; b=K43dF3l6brMSzT/Gp7bXFvjKy+cu+3nuwJe0gBhKn8CGMwlvqDVQQBjIGphncVmF/m CO5C0h6ywoKT4mnxFXrUCq8+D46QV0rA72BBuPCUz8BZS+WqleFHb/oCz38sPiOap0Uz BHq53VG+nFEU4pEa9Dw/Nsx+svmjVTwyCV9m4= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=gArJm9jVAsBxkDTNDeFPDeQMnj9YNQEIuITg/FnaFG6Hj/8C4ioHo+0ue5oIH8Y3lT TiIO9Ac/erMbv1HiDJwT+oh6bNIZ5PVpP6Cr8tMBXDROEuGaEHANmO8mQNCP0hlR3u/F gCui+TBFjXE1vaxMDkAEw0XQJiVddKwwv5/zY= Received: by 10.151.13.3 with SMTP id q3mr524510ybi.30.1279225386549; Thu, 15 Jul 2010 13:23:06 -0700 (PDT) Received: from localhost.localdomain (curitiba.ic.unicamp.br [143.106.7.130]) by mx.google.com with ESMTPS id 3sm7365611ybi.13.2010.07.15.13.23.03 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 15 Jul 2010 13:23:06 -0700 (PDT) From: Miguel Di Ciurcio Filho To: qemu-devel@nongnu.org Date: Thu, 15 Jul 2010 17:22:58 -0300 Message-Id: <1279225380-28790-3-git-send-email-miguel.filho@gmail.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1279225380-28790-1-git-send-email-miguel.filho@gmail.com> References: <1279225380-28790-1-git-send-email-miguel.filho@gmail.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Cc: Miguel Di Ciurcio Filho , jan.kiszka@web.de, armbru@redhat.com, avi@redhat.com Subject: [Qemu-devel] [PATCH RFC 2/4] net: Introduce NetClientDump and auxiliary functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Miguel Di Ciurcio Filho --- 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;