tcpdump mailing list archives

Re: pcap and select()


From: Guy Harris <guy () alum mit edu>
Date: Wed, 17 Apr 2013 23:15:46 -0700


On Apr 17, 2013, at 6:56 PM, wen lui <esolvepolito () gmail com> wrote:

       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

       while(1){

         n=fork();
         if(n==0) { // child process
               fd_set rdfds;
               int pcap_fd = pcap_get_selectable_fd(pcap_handler);
               for(;;){
                       FD_ZERO(&rdfds);
                       FD_SET(pcap_fd, &rdfds);
                       FD_SET(sd_proxy, &rdfds);   // here is another fd

                       select(pcap_fd>sd_proxy?pcap_fd+1:sd_proxy+1,&rdfds, NULL, NULL, NULL)

Yes, that's at least a start at writing the kind of code needed for

        http://stackoverflow.com/questions/16067015/blocking-pcap-and-multiple-i-o-select

You should be checking the return value of select() for errors, and reporting errors if they occur, just to be sure.

From the

       struct pcap_pkthdr pcap_header;      // The header that pcap gives us
       const u_char *pcap_packet;           // The actual packet

I suspect you're using pcap_next() or pcap_next_ex().

If you're going to use them with select(), you have to use them in a very specific way.

First of all, you need to put the pcap_t in non-blocking mode.  After the pcap_open_live() call, do:

        if (pcap_setnonblock(handle, 1, errbuf) == -1) {
                fprintf(stderr, "pcap_setnonblock failed: %s\n", errbuf);
                exit(2);
        }

Then, of course, you check rdfds; if the bit for pcap_fd is set, do:

                for (;;) {
                        switch (pcap_next_ex(handle, &pcap_header, &pcap_packet)) {

                        case -1:
                                /* Error */
                                fprintf(stderr, "pcap_next_ex failed: %s\n", pcap_geterr(handle));
                                exit(2);
                                break;

                        case 0:
                                /* No more packets to read for now */
                                goto done;

                        case -2:
                                /* Somebody called pcap_breakloop() */
                                goto done;

                        default:
                                /* Process the packet */
                                do whatever you do with pcap_header and pcap_packet;
                                break;
                }
        done:
                ;

The "case -2" case can be left out if you don't call pcap_breakloop() in your program.

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


Current thread: