Hello all.

As promised I'll start to provide patches for modifications I've made to the 
Qemu source code as part of the project. Attached you find the first of these 
patches - an option to dump the traffic on a virtual interface to a tcpdump 
compatible file. I welcome any feedback since this is the first time I 
contributed actual code to an open source project. My main concern is that the 
code performing the actual dump is bound to the vlan not to the interface (it 
does the saving in the "qemu_send_packet" procedure). While this is generally 
speaking ok (since there is usually one vlan per interface per virtual 
computer), I welcome any suggestion where the code should be put.

Best regards,
Cd-MaN




        
        
                
___________________________________________________________ 
New Yahoo! Mail is the ultimate force in competitive emailing. Find out more at 
the Yahoo! Mail Championships. Plus: play games and win prizes. 
http://uk.rd.yahoo.com/evt=44106/*http://mail.yahoo.net/uk 
Index: vl.c
===================================================================
RCS file: /sources/qemu/qemu/vl.c,v
retrieving revision 1.306
diff -u -r1.306 vl.c
--- vl.c	10 Jun 2007 19:21:04 -0000	1.306
+++ vl.c	21 Jun 2007 19:13:32 -0000
@@ -3157,6 +3157,12 @@
     while (*pvlan != NULL)
         pvlan = &(*pvlan)->next;
     *pvlan = vlan;
+	
+	//initialize the packet capture options
+	vlan->pcap_file = NULL;	
+	vlan->last_written_time = 0;
+	vlan->packet_serial_num = 0;
+	
     return vlan;
 }
 
@@ -3200,6 +3206,22 @@
 {
     VLANState *vlan = vc1->vlan;
     VLANClientState *vc;
+	PCAPRecordHeader pcap_record_header;
+	
+	if (vlan->pcap_file) {
+		pcap_record_header.ts_sec = time(NULL);
+		if (pcap_record_header.ts_sec == vlan->last_written_time) {
+			pcap_record_header.ts_usec = vlan->last_written_time;
+			if (vlan->last_written_time < 9999) vlan->last_written_time++;
+		} else {
+			pcap_record_header.ts_usec = 0;
+			vlan->last_written_time = 0;
+		}		
+		pcap_record_header.orig_len = size;
+		pcap_record_header.incl_len = (size > 0xFFFF) ? 0xFFFF : size;
+		fwrite(&pcap_record_header, sizeof(pcap_record_header), 1, vlan->pcap_file);
+		fwrite(buf, pcap_record_header.incl_len, 1, vlan->pcap_file);		
+	}
 
 #if 0
     printf("vlan %d send:\n", vlan->id);
@@ -4194,6 +4216,24 @@
         if (get_param_value(buf, sizeof(buf), "model", p)) {
             nd->model = strdup(buf);
         }
+		if (get_param_value(buf, sizeof(buf), "pcap", p)) {
+			vlan->pcap_file = fopen(buf, "wb");
+			if (!vlan->pcap_file) {
+				fprintf(stderr, "failed to open pcap file: %d\n", errno);
+				return -1;
+			}
+			//write out the standard tcpdump file header
+			//reference: http://wiki.wireshark.org/Development/LibpcapFileFormat
+			PCAPHeader hdr;
+			hdr.magic_number = 0xa1b2c3d4;
+			hdr.version_major = 2;
+			hdr.version_minor = 4;
+			hdr.thiszone = 0;
+			hdr.sigfigs = 0;
+			hdr.snaplen = 0xFFFF;
+			hdr.network = 1;
+			fwrite(&hdr, sizeof(hdr), 1, vlan->pcap_file);			
+		}
         nd->vlan = vlan;
         nb_nics++;
         vlan->nb_guest_devs++;
@@ -6585,7 +6625,7 @@
            "-name string    set the name of the guest\n"
            "\n"
            "Network options:\n"
-           "-net nic[,vlan=n][,macaddr=addr][,model=type]\n"
+           "-net nic[,vlan=n][,macaddr=addr][,model=type][,pcap=file]\n"
            "                create a new Network Interface Card and connect it to VLAN 'n'\n"
 #ifdef CONFIG_SLIRP
            "-net user[,vlan=n][,hostname=host]\n"
Index: vl.h
===================================================================
RCS file: /sources/qemu/qemu/vl.h,v
retrieving revision 1.252
diff -u -r1.252 vl.h
--- vl.h	18 Jun 2007 18:55:46 -0000	1.252
+++ vl.h	21 Jun 2007 19:14:11 -0000
@@ -390,6 +390,12 @@
     VLANClientState *first_client;
     struct VLANState *next;
     unsigned int nb_guest_devs, nb_host_devs;
+		
+	//used to perform packed capture
+	//and to set the time stamps on the captured packets
+	FILE *pcap_file;
+	time_t last_written_time;
+	int packet_serial_num;
 } VLANState;
 
 VLANState *qemu_find_vlan(int id);
@@ -402,6 +408,24 @@
 void qemu_handler_true(void *opaque);
 
 void do_info_network(void);
+/* PCAP file structures */
+
+typedef struct PCAPHeader { 
+        unsigned int magic_number;   /* magic number */
+        unsigned short int version_major;  /* major version number */
+        unsigned short int version_minor;  /* minor version number */
+        int  thiszone;       /* GMT to local correction */
+        unsigned int sigfigs;        /* accuracy of timestamps */
+        unsigned int snaplen;        /* max length of captured packets, in octets */
+        unsigned int network;        /* data link type */
+} PCAPHeader;
+
+typedef struct PCAPRecordHeader { 
+        unsigned int ts_sec;         /* timestamp seconds */
+        unsigned int ts_usec;        /* timestamp microseconds */
+        unsigned int incl_len;       /* number of octets of packet saved in file */
+        unsigned int orig_len;       /* actual length of packet */
+} PCAPRecordHeader;
 
 /* TAP win32 */
 int tap_win32_init(VLANState *vlan, const char *ifname);

Reply via email to