简体   繁体   中英

How to pass multiple arguments to pcap_loop()/pcap_handler()?

I need to pass two pointers of different types to pcap_loop() so that the pcap_handler can read/modify that data.

pcap_loop() looks like:

int pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user);

...and takes arguments through u_char * user and passes those arguments on to pcap_handler callback which looks like:

void pcap_handler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes);

So how can I pass multiple arguments through a single u_char pointer? I tried passing them as an array of u_char pointers...

#include <pcap/pcap.h>

...

void callback(u_char *arg_array, const struct pcap_pkthdr *h, const u_char *bytes) {

    class1 * c1_ptr = (class1 *)arg_array[0];
    class2 * c2_ptr = (class2 *)arg_array[1];

}

void main() {

...

class1 c1;
class2 c2;
u_char * arg_array[2];

arg_array[0] = (u_char *)&c1;
arg_array[1] = (u_char *)&c2;

pcap_loop(p, cnt, callback, arg_array);

}

...but (not surprisingly) got u_char * array[] -> u_char * conversion errors. I also got warned about casting from a smaller type ( u_char * ) to a larger type ( class1 * , class2 * ).

What's the correct way to be doing this?

The problem here is that you are trying to pass an array of u_char pointers ( u_char** ) to a parameter that expects an u_char array/pointer ( u_char* ). (I'm a bit surprised they use u_char pointers as usually these kind of callbacks rely on void pointers, but that's beside the point.)

What you need to do is one of two: Either you encapsulate your pointers in a struct. Or, you do a bit of "creative casting".

Struct:

struct cb_struct {
   class1 *c1;
   class2 *c2;
};

//... In main or wherever

class1 c1;
class2 c2;

cb_struct cb_s = { &c1, &c2 };

pcap_loop( p, cnt, callback, reinterpret_cast<u_char*>(cb_s));

Or you become a bit more creative with the array:

void * arg_arr[2] = { &c1, &c2 }; // Prefer void array so noone actually tries to use your pointers as what u_chars.

pcap_loop( p, cnt, callback, reinterpret_cast<u_char*>(arg_arr));

Once you are casting back you need to use something like:

void callback(u_char *arg_array, const struct pcap_pkthdr *h, const u_char *bytes) {
   void ** arg_arr = reinterpret_cast<void**>(arg_array);
   class1 * c1_ptr = reinterpret_cast<class1*>(arg_arr[0]);
   class2 * c2_ptr = reinterpret_cast<class2*>(arg_arr[1]);
}

Or something similar for the struct.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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