Reputation: 652
I am getting this warning:
cast to pointer from integer of different size
when attempting to compile my program. This particular piece of code is pretty much lifted from an example TCP connection program and I am just a hobby programmer, so I'm guessing the solution is quite obvious, yet it's driving me mad.
My understanding of the pcap_loop function is that the u_char *
points to the first argument of the recieve function, right? If that is the case why do get a warning?
As I'm not really sure what's wrong i've included what I believe are the relevant functions in their entirety, and I really hope some of you will find it in you to help me out here.
void receive(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *buffer)
{
const int one = 1;
int LEN = *args;
struct ipheader *ip;
struct tcpheader *tcp;
ip = (struct ipheader *)(buffer + LEN);
tcp = (struct tcpheader *)(buffer + LEN + sizeof (struct ipheader));
printf("%d\n", LEN);
printf("Packet received. ACK number: %d\n", ntohl (tcp->tcph_seqnum));
printf("Packet received. SEQ number: %d\n", nthol (tcp->tcph_acknum));
s_seq = nthol (tcp->tcph_seqnum);
send_syn_ack(s_seq, dip, sip, dport, sport);
sleep(100);
}
void capture()
{
pcap_t *pd;
bpf_u_int32 netmask;
bpf_u_int32 localnet;
char *filter = ("ip dest host %s", dstip);
char *dev = NULL;
char errbuf[PCAP_ERRBUF_SIZE];
struct bpf_program filterprog;
int dl = 0, dl_len = 0;
if ((pd = pcap_open_live(dev, 1514, 1, 500, errbuf)) == NULL)
{
fprintf(stderr, "cannot open device %s: %s\n", dev, errbuf);
exit(1);
}
pcap_lookupnet(dev, &localnet, &netmask, errbuf);
pcap_compile(pd, &filterprog, filter, 0, localnet);
if (pcap_setfilter(pd, &filterprog) == - 1)
{
fprintf(stderr, "cannot set pcap filter %s: %s\n", filter, errbuf);
exit(1);
}
pcap_freecode(&filterprog);
dl = pcap_datalink(pd);
switch(dl) {
case 1:
dl_len = 14;
break;
default:
dl_len = 14;
break;
}
if (pcap_loop(pd, -1, receive, (u_char *)dl_len) < 0) /* THIS IS THE LINE IN QUESTION */
{
fprintf(stderr, "cannot get raw packet: %s\n", pcap_geterr(pd));
exit(1);
}
}
Thanks a lot both of you! @pb2q I am a bit confused. when you say:
you'll need to pass it's address, and make sure that the variable is dynamically allocated or remains in scope >when the callback executes.
I am afraid I'm not sure how that translate into code in this example, and I do not wish for the code to be sloppy, although what has been suggested below seemed to work.
Upvotes: 1
Views: 432
Reputation: 59617
The function is expecting a pointer to user data, to pass through to a callback function. Your supplied argument is an integer, and not a pointer, and it will be interpreted as a memory address if it's used in the callback. This isn't what you want.
If you want to pass dl_len
through to the callback, and be able to look at it's value (looks like it's only ever 14), you'll need to pass it's address, and make sure that the variable is dynamically allocated or remains in scope when the callback executes.
Pass a pointer like so - note the &
:
if (pcap_loop(pd, -1, receive, (u_char *) &dl_len) < 0)
Upvotes: 2
Reputation: 10937
My understanding of the pcap_loop function is that the u_char * points to the first argument of the recieve function, right? If that is the case why do get a warning?
Correct. I imagine you are running on x64, the issue is in this piece of code (u_char *)dl_len)
. You are trying to convert an int (most likely 4 bytes on your platform) to a pointer (most likely 4 bytes on your platform).
The quick fix for your case would be change the type of dl_len
to a long
.
A more prefereable solution would be to change (u_char *)dl_len)
to reinterpret_cast<char*>(dl_len)
.
You also need to change int LEN = *args;
to int LEN = args
, as you don't want to deference this false memory pointer.
Upvotes: 1