Caching packets captured from pcap

2019-07-03 23:18发布

问题:

This is a follow-up question to this: Rebuilding a packet to inject via pcap

What I want to accomplish:

  1. functionA: Capture packets with pcap. Modify source/destination addresses. Recalculate checksums. Inject with pcap.

  2. functionB: Create two threads. Thread 1 sends a magic packet to wake sleeping client. Thread 2 captures packets with pcap and caches the packets into an array of u_char *'s, since pcap puts the packet data serially into "u_char * packet". When both threads terminate, I then change the headers then inject each of the cached packets.

What I need help with:

  1. functionA: I can do everything but calculate checksums. I tried to verify the original checksum by calculating it myself with a function but they never match. However, this issue is not as important because I don't need it to demo my final project. I understand that if IP checksums are incorrect, the receiving computer will discard the packet. But when I demo, so long as my client computer can be shown to have received this incorrect packet, I have proven my overall concept and will not fail. :)

  2. functionB: I guess this is the more important problem. I don't know of an easy way to cache my captured packets. What I'm working on right now is as follows:

functionB creates a pointer to an array that stores u_char * called cachedPackets. So cachedPackets basically points to an array that stores "strings".

It'll be something like this? u_char ** cachedPackets[100], enough array elements for 100 packets.

After this, I start two threads. Thread1 to wake my sleeping client. Thread2 to open another pcap session so no data is lost while client is waking. Thread1 is easy, I've already tested my send magic packet function independently. Thread2 is where I'm screwing up.

Thread2 eventually calls int pcap_loop(pcap_t *p, int cut, pcap_handler callback, u_char *user).

callback is the function that will be run after each packet is captured. It is where I will be caching the packet into the array.

callback takes parameters ( u_char* user, const struct pcap_pkthdr* packet_header, const u_char* packet_data )

user is the same string in the 4th argument of pcap_loop.

So I was thinking, I could sneakily give my callback function the pointer to the array of string by type casting it.

pcap_loop(asdf, asdf, callback, (u_char *)cachedPackets);

Since I don't know how big the incoming packets will be, I'll dynamically allocate enough space in the callback function. I will also keep track of my position in the array with a static int.

this is what the callback looks like:

void cacheCall(u_char * user, const struct pcap_pkthdr * header, const u_char * packet)

    static int cacheindex = 0;

    u_char ** cachethis = (u_char **)user; 

    //u_char * cachething = *cachethis;
    (*cachethis)[cacheindex] = (u_char *) malloc(header->len); <--- 497


    int i = 0;

    for(i = 0; i < header->len; i++)
    {
        (*cachethis)[cacheindex][i] = packet[i]; <-------------------503
    }

    //memcpy(cachething[cacheindex], packet, header->len);
    cacheindex++;

but when I compile, i get

497: warning: assignment makes integer from pointer without a cast
503: error: subscripted value is neither array nor pointer

That was pretty longwinded, hopefully my knowledge of what I'm doing isn't completely misinformed. Any help would be awesome! :)

回答1:

u_char ** cachethis;

cachethis is a pointer-to-pointer-to-u_char.

So:

*cachethis

is a pointer-to-u_char, and:

(*cachethis)[i]

is a plain u_char.

So line 497 tries to store a pointer into an u_char, and line 503 tries to subscript a u_char, both of which are invalid.

Looks like what you want is simply:

cachethis[i]

and

cachethis[i][j]