简体   繁体   English

pcap_loop 中的回调方法

[英]callback method in pcap_loop

I am trying to use the pcap_loop function in libpcab library in Linux with this prototype:我正在尝试使用以下原型在 Linux 中的 libpcab 库中使用 pcap_loop 函数:

int pcap_loop(pcap_t *, int, pcap_handler, u_char *);

pcap_pkthdr is a function pointer: pcap_pkthdr 是一个函数指针:

typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *, const u_char *);

In my program, I have defined the following method in class SniffEthernet:在我的程序中,我在类 SniffEthernet 中定义了以下方法:

void SniffEthernet::got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

Now calling pcap_loop as below现在调用 pcap_loop 如下

pcap_loop(handle, num_packets, this->got_packet, NULL);

gives me the following compile-time error:给了我以下编译时错误:

SniffEthernet.cc:139:58: error: cannot convert ‘VENTOS::SniffEthernet::got_packet’ from type ‘void (VENTOS::SniffEthernet::)(u_char*, const pcap_pkthdr*, const u_char*) {aka void (VENTOS::SniffEthernet::)(unsigned char*, const pcap_pkthdr*, const unsigned char*)}’ to type ‘pcap_handler {aka void (*)(unsigned char*, const pcap_pkthdr*, const unsigned char*)}’

What am I doing wrong here?我在这里做错了什么?

Edit: I found a similar post here .编辑:我在这里找到了一个类似的帖子。

Your callback function cannot be a member function (method).您的回调函数不能是成员函数(方法)。 Don't forget that member functions always have the hidden parameter this .不要忘记成员函数总是有隐藏参数this

Your callback function must be either a namespace-level function or a static member of your class.您的回调函数必须是命名空间级函数或类的静态成员。

If you want to have your object available for your CB function, you can use the user member (the last argument of pcap_loop() , first member of the callback function), with proper type casts, to pass arbitrary data, which, in your case, shall be the object you're using for the capture.如果你想让你的对象可用于你的 CB 函数,你可以使用user成员( pcap_loop()的最后一个参数,回调函数的第一个成员),通过适当的类型转换,传递任意数据,在你的case,应该是您用于捕获的对象。

The code below is incomplete and untested , but might give you an idea.下面的代码不完整未经测试,但可能会给您一个想法。

class SniffEther {
    private:
        pcap_t *cap_handler;
        char errbuf[PCAP_ERRBUF_SIZE];
        /* capture-related data members (properties) */

    public:
        static friend void pkt_callback(u_char *user, const pcap_pkthdr *hdr, const u_char *bytes){
            SniffEther *sniffer=reinterpret_cast<SniffEther *>(user);
            /*
                Process header and bytes.

                You can call things like sniffer->somemethod(), and also
                access sniffer->someproperty.
            */
        }

        // constructor
        SniffEther(const char *if_name){
            cap_handler=pcap_create(if_name, errbuf);
            if(!cap_handler)
                throw runtime_error(errbuf);
            /* Set the many pcap_options (see pcap(3)). */
            if(pcap_activate(cap_handler)!=0){
                string error(pcap_geterr(cap_handler));
                pcap_close(cap_handler);
                throw runtime_error(error);
            }
        }

        ~SniffEther(){
            if(cap_handler)
                pcap_close(cap_handler);
        }

        void capture_loop(int pkt_count=-1){
            if(
                pcap_loop(
                    cap_handler, pkt_count, pkt_callback,
                    reinterpret_cast<u_char *>(this)
                )==-1
            )
                throw runtime_error(pcap_geterr(cap_handler));
        }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM