tcpdump mailing list archives

Re: some questions about libpcap , especially with fork() called


From: wen lui <esolvepolito () gmail com>
Date: Mon, 8 Apr 2013 15:13:37 +0200

thanks, I have another question
if I want to capture packets with ACK flag set for EACH INCOMING TCP
connection
so I put accept() in a loop

        // proxy server listen, waiting for receiver's tcp request
        listen(listenfd, 1024);

        while(1) {
        connfd = accept(listenfd, (struct sockaddr *)&sender_addr,
&sock_len);
        pcap_packet = pcap_next(handle, &pcap_header);

        pid=fork();
        if(pid=0)  // child process
         {
          pcap_packet = pcap_next(handle, &pcap_header);
         }
         blabla.....
        }


in this way, if I put the following code block before accept(), then all
incoming TCP connections may share the same pcap handler
but if I put the following code block in each child process after fork(),
the handler may miss some TCP packets

        handle = pcap_open_live(dev, BUFSIZ, 0, 0, errbuf);
        pcap_compile(handle, &fp, filter_exp, 0, mask) == -1
        pcap_setfilter(handle, &fp);
        struct pcap_pkthdr pcap_header;      // The header that pcap gives
us
        const u_char *pcap_packet;           // The actual packet


are there any solutions like: just create 1 handler, but split the related
FIFO queue into multip FIFO queues, each of which corresponds to one tcp
connection, and then pcap_next() in each child process just fetch packets
from its corresponding sub-FIFO queue?
or any other solutions?

thanks!


2013/4/8 Guy Harris <guy () alum mit edu>


On Apr 7, 2013, at 3:25 PM, wen lui <esolvepolito () gmail com> wrote:

1 I don't know how pcap handler works, my understanding is: when
pcap_open_live() function is called and the filter is set, it will
capture
all matching packets and put them in a FIFO queue somewhere. Then, each
time I call pcap_next(), the packet in the head of the FIFO queue is
fetched. Is it correct or not?

It's basically correct.  pcap_open_live() starts the capture process, and
setting the filter changes the filter used by the capture process
(discarding some not-yet-read packets); the packets that arrive are put
into a FIFO buffer (there might be separate OS-level buffers and
libpcap-level buffers, but the overall effect is that of a FIFO buffer).
 pcap_next() will extract the oldest packet from the buffer.

2 how is the granularity of the packet?if there are IP fragmentation, are
they IP packets or TCP/UDP packets?

They're *probably* link-layer packets, so, if there's IP fragmentation,
each fragment will be a separate packet.

However, if the network adapter is doing IP reassembly or TCP reassembly,
you might get a packet that looks like a link-layer packet but is really a
"fake" link-layer packet with a fully-reassembled IP datagram or with
multiple TCP segments, so that multiple link-layer packets are combined
into one packet.

how to get only 4-th layer packets?

By using something other than libpcap or the mechanism it uses, or by
doing whatever reassembly is involved by yourself.  There's no way to do
that in libpcap unless your adapter happens to do it for you.

3 when there are incoming TCP connections, for each connection  I want to
capture the final ACK packet and the following data packets and FIN/ACK
packets, which are all with ACK flag set to 1 , so the filter_exp is
something like "port 54000 and tcp[tcpflags] & (tcp-ack) != 0"

the problems is, when in the child process, will the pcap handler still
work?

On *most* platforms, it should work in the child process; do *NOT*,
however, do anything with the pcap_t in the parent process until the child
process has exited, and don't use monitor mode on a Wi-Fi device if you're
going to do any forking.

I'm not sure whether it'll work on Linux if the memory-mapped capture
mechanism is being used; the memory-mapped capture mechanism will be used
on current versions of Linux.  I *think* it should work, as the region is
mapped MAP_SHARED and hasn't been flagged as MADV_DONTFORK.  Again, once
the child process has been forked, don't do *anything* in the parent
process.


_______________________________________________
tcpdump-workers mailing list
tcpdump-workers () lists tcpdump org
https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers


Current thread: