0
votes

I would like to use libpcap to capture on multiple specific interfaces (not 'any') to the same file

I have the following code (error handling and some args removed):

static gpointer pkt_tracing_thread(gpointer data)
{
    while (1)
    {
        pcap_dispatch(g_capture_device1, .., dump_file1);
        pcap_dispatch(g_capture_device2, .., dump_file2);
    }
}

fp1 = calloc(1, sizeof(struct bpf_program));
fp2 = calloc(1, sizeof(struct bpf_program));
cap_dev1 = pcap_open_live(interface1,...
cap_dev2 = pcap_open_live(interface2,...
pcap_compile(cap_dev1, fp1, ...
pcap_compile(cap_dev2, fp2, ...
pcap_setfilter(cap_dev1, fp1);
pcap_setfilter(cap_dev2, fp2);
dump_file1 = pcap_dump_open(g_capture_device1, filename);
dump_file2 = pcap_dump_open(g_capture_device2, filename);

g_thread_create_full(pkt_tracing_thread, (gpointer)fp1, ...
g_thread_create_full(pkt_tracing_thread, (gpointer)fp2, ...

This does not work. What I see in filename is just packets on one of the interfaces. I'm guessing there could be threading issues in the above code.

I've read https://seclists.org/tcpdump/2012/q2/18 but I'm still not clear.

I've read that libpcap does not support writing in pcapng format, which would be required for the above to work, although I'm not clear about why.

Is there any way to capture multiple interfaces and write them to the same file?

2

2 Answers

0
votes

Is there any way to capture multiple interfaces and write them to the same file?

Yes, but 1) you have to open the output file only once, with one call to pcap_dump_open() (otherwise, as with your program, you may have two threads writing to the same file independently and stepping on each other) and 2) you would need to have some form of mutex to prevent both threads from writing to the file at the same time.

Also, you should have one thread reading only from one capture device and the other thread reading from the other capture device, rather than having both threads reading from both devices.

0
votes

As user9065877, you have to open the output file only once and write to it only from one thread at a time.

However, since you'd be serializing everything anyway, you may prefer to ask libpcap for pollable file descriptors for the interfaces and poll in a round-robin fashion for packets, using a single thread and no mutexes.