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);