LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Programming w/ pcap (http://www.linuxquestions.org/questions/programming-9/programming-w-pcap-507926/)

Rawjoe 12-06-2006 11:47 AM

Programming w/ pcap
 
I'm trying to program a multi-threaded program that uses pcap. In my pcap file I have my main thread that does something this:

Code:

while (capture_flag) {
  packet = pcap_next(handle, &header);
  //more code after this
}

which works great and all. Also, in the same file, I have a function called on by other threads to stop the capture:

Code:

void stop_capture(){
        capture_flag = 0;
        pcap_breakloop(handle);
}

Of course I have handle declared as a global variable.

Now, when I call stop_capture(), it seems to wait until pcap_next captures one more packet, and does not exit out of pcap_next right away. Does pcap_breakloop not actually break you out of pcap_next, and if so, how can I actually get pcap_next to stop waiting on a capture.

Thanks in advance,
Joe

Rawjoe 12-06-2006 02:51 PM

To update, I read a few things on how you should use an signal, and call pcap_breakloop from the signal handler. But I still get it there, waiting for one last packet. Here is my updated code:

Code:

static sem_t pcap_sem;
static char filter_exp[100];
static unsigned char capture_packets;
pcap_t* handle;


static void sig15(int sig) {
        capture_packets = 0;
        pcap_breakloop(handle);
}

void pcap_cb (u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data) {
        if (pkt_data) syslog(LOG_INFO, "Got packet: %d bytes captured:", pkt_header->caplen);
}

void * pcap_main(int *a) {

        char *dev, errbuf[PCAP_ERRBUF_SIZE];
        bpf_u_int32 mask, net;
        struct bpf_program fp;

        if (signal(15, sig15) == SIG_ERR) {
                perror("SIGNAL");
                syslog(LOG_INFO, "Error installing sig15 handler %m");
                exit(-1);
        }
        siginterrupt(15, 1);

        capture_packets = 0;

        if (sem_init(&pcap_sem, 0, 1) <0)
                syslog(LOG_INFO,"pcap_main: Failure to initialize semaphore\n");
        sem_wait(&pcap_sem);

        dev = pcap_lookupdev(errbuf);

        handle = pcap_open_live(dev, BUFSIZ, 1, 1000, errbuf);

        while (1) {
                sem_wait(&pcap_sem);

                if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
                        syslog(LOG_INFO,"Couldn't parse filter %s: %s", filter_exp, pcap_geterr(handle));
                        capture_packets = 0;
                } else if (pcap_setfilter(handle, &fp) == -1) {
                        syslog(LOG_INFO,"Couldn't install filter %s: %s", filter_exp, pcap_geterr(handle));
                        capture_packets = 0;
                }

                while (capture_packets > 0) {
                        syslog(LOG_INFO, "Waiting to capture packet");
                        pcap_loop(handle, -1, pcap_cb, NULL);
                        syslog(LOG_INFO, "Done capturing packets");
                }

                pcap_freecode(&fp);
        }
}

void start_capture(unsigned long ccAddr, char* filter) {
        strcpy(filter_exp, filter);
        capture_packets = 0x0F;  //anything greater than 0
        sem_post(&pcap_sem);
}

void stop_capture(){
        raise(15);
}


Rawjoe 12-07-2006 08:55 AM

Ok, so raise() was sending the signal to the parent thread, not this child thread handling pcap, so pcap loop was never being interrupted. I guess I should learn more about these signals and threads.


All times are GMT -5. The time now is 02:23 AM.