Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault on pcap_next with libpcap 0.9.8 #664

Closed
lalibpcapcamarchepas opened this issue Nov 20, 2017 · 3 comments
Closed

Segmentation fault on pcap_next with libpcap 0.9.8 #664

lalibpcapcamarchepas opened this issue Nov 20, 2017 · 3 comments
Assignees

Comments

@lalibpcapcamarchepas
Copy link

lalibpcapcamarchepas commented Nov 20, 2017

Hello,
I am maintaining a C++ application using libpcap 0.9.8. A process receiving MAC/LLC data from the network crashes randomly on a call to pcap_next or pcap_open_live after a call to pcap_close.
To isolate the problem i wrote a small program that creates threads that receive data with pcap next. The main thread calls pcap_close while the other threads are calling pcap_next.
When I execute the program, sometimes it finishes without error, sometimes it crashed on pcap_next.
Is this a bug of this version (0.9.8) of libpcap or am I not supposed to call pcap_close while a thread is calling pcap_next ?
Here is the source code :

#include <queue>
#include <iostream>
#include <sstream>
#include <pcap.h>

pcap_t* adapter;

void * Receive(void * param)
{
    pcap_t* adapt = (pcap_t*) param;
    while (true)
    {
        struct pcap_pkthdr header;
        const u_char* data;
        usleep(10000);
        data = pcap_next(adapt, &header);
        std::cout << "Reception" << std::endl;
    }
    pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
    char errbuf[PCAP_ERRBUF_SIZE];
    adapter = pcap_open_live("eth0",65536,1,-1,errbuf);
    if (adapter == 0)
    {
        std::cout << "Failure when opening card" << std::endl;
        return -1;
    }
    std::cout << "Card opened" << std::endl;

    std::ostringstream  filtre;
    filtre << "not tcp and not udp";
    struct bpf_program filter;
    bpf_u_int32 maskp= 0xffffff;
    if (pcap_compile(adapter, &filter, filtre.str().c_str(), 0, maskp) == -1)
    {
        std::cout << "Failure : pcap_compile" << std::endl;
        return -1;
    }
    if (pcap_setfilter(adapter, &filter) == -1)
    {
        std::cout << "Failure : pcap_setfilter" << std::endl;
        return -1;
    }

    pthread_t threadReception;
    pthread_create(&threadReception, NULL, Receive, (void*)adapter);

    usleep(15000);
    for (int i =0; i< 100; i++)
    {
        std::cout << "LOOP " << i <<std::endl;

        std::cout << "Closing card" << std::endl;
        pcap_close(adapter);

        adapter = pcap_open_live("eth1",65536,1,-1,errbuf);
        if (adapter == 0)
        {
            std::cout << "Failure when opening card" << std::endl;
            return -1;
        }
        std::cout << "Card opened" << std::endl;

        std::ostringstream  filtre;
        filtre << "not tcp and not udp";
        struct bpf_program filter;
        bpf_u_int32 maskp= 0xffffff;
        if (pcap_compile(adapter, &filter, filtre.str().c_str(), 0, maskp) == -1)
        {
            std::cout << "Failure : pcap_compile" << std::endl;
            return -1;
        }
        if (pcap_setfilter(adapter, &filter) == -1)
        {
            std::cout << "Failure : pcap_setfilter" << std::endl;
            return -1;
        }

        pthread_t threadReception;
        pthread_create(&threadReception, NULL, Receive, (void*)adapter);

        usleep(10000);
    }
    return 0;
}
@lalibpcapcamarchepas lalibpcapcamarchepas changed the title Segmentation fault on pcap_next with libpcap 0.8.9 Segmentation fault on pcap_next with libpcap 0.9.8 Nov 20, 2017
@infrastation
Copy link
Member

There were a few similar reports, AFAIR, they ended up as either a bug in the main software (not libpcap) or a bug specific to an old libpcap version (recent libpcap is thread-safe).

@guyharris
Copy link
Member

or am I not supposed to call pcap_close while a thread is calling pcap_next

You are definitely not supposed to be calling pcap_close() on a pcap_t * while another thread is calling pcap_next() - or any other libpcap function! - on the same pcap_t *.

There is no thread interlocking in a pcap_t. Once you've gotten a pcap_t *, use it only within one thread.

@guyharris
Copy link
Member

Once you've gotten a pcap_t *, use it only within one thread.

...which means that, once you've started a thread to read from that pcap_t *, do NOT do anything with that pcap_t *, other than perhaps calling pcap_breakloop() or making calls to fetch data such as its selectable descriptor on UN*X or its event handle on Windows, until the thread reading from that pcap_t * has indicated that it's done with the pcap_t * (e.g., by exiting).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants