src/app/ixy-pcap.c
Capture received packets to a pcap file.
filesrc/app/ixy-pcap.c
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include "driver/device.h"
const int BATCH_SIZE = 32;
// From https://wiki.wireshark.org/Development/LibpcapFileFormat
typedef struct pcap_hdr_s {
uint32_t magic_number; /* magic number */
uint16_t version_major; /* major version number */
uint16_t version_minor; /* minor version number */
int32_t thiszone; /* GMT to local correction */
uint32_t sigfigs; /* accuracy of timestamps */
uint32_t snaplen; /* max length of captured packets, in octets */
uint32_t network; /* data link type */
} pcap_hdr_t;
typedef struct pcaprec_hdr_s {
uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */
uint32_t incl_len; /* number of octets of packet saved in file */
uint32_t orig_len; /* actual length of packet */
} pcaprec_hdr_t;
int main(int argc, char* argv[]) {
if (argc < 3 || argc > 4) {
printf("Usage: %s <pci bus id> <output file> [n packets]\n", argv[0]);
return 1;
}
struct ixy_device* dev = ixy_init(argv[1], 1, 1, 0);
FILE* pcap = fopen(argv[2], "wb");
if (pcap == NULL) {
error("failed to open file %s", argv[2]);
}
int64_t n_packets = -1;
if (argc == 4) {
n_packets = atol(argv[3]);
printf("Capturing %ld packets...\n", n_packets);
} else {
printf("Capturing packets...\n");
}
pcap_hdr_t header = {
.magic_number = 0xa1b2c3d4,
.version_major = 2,
.version_minor = 4,
.thiszone = 0,
.sigfigs = 0,
.snaplen = 65535,
.network = 1, // Ethernet
};
fwrite(&header, sizeof(header), 1, pcap);
struct pkt_buf* bufs[BATCH_SIZE];
while (n_packets != 0) {
uint32_t num_rx = ixy_rx_batch(dev, 0, bufs, BATCH_SIZE);
struct timeval tv;
gettimeofday(&tv, NULL);
for (uint32_t i = 0; i < num_rx && n_packets != 0; i++) {
pcaprec_hdr_t rec_header = {
.ts_sec = tv.tv_sec,
.ts_usec = tv.tv_usec,
.incl_len = bufs[i]->size,
.orig_len = bufs[i]->size
};
fwrite(&rec_header, sizeof(pcaprec_hdr_t), 1, pcap);
fwrite(bufs[i]->data, bufs[i]->size, 1, pcap);
pkt_buf_free(bufs[i]);
// n_packets == -1 indicates unbounded capture
if (n_packets > 0) {
n_packets--;
}
}
}
fclose(pcap);
return 0;
}