Struct value changes after passing to method
I am writing a packet parser using libpcap and encounter strange behaviour when trying to read the packet length form the pcap header.
The first printf
statement below prints out the correct packet length, whereas the second one prints out a number such as 362791.
struct pcap_pkthdr header;
pcap_t *handle;
const u_char *packet;
...
while((packet = pcap_next(handle, &header)) != NULL) {
printf("[%d]\n", header.len);
process_packet(&header, packet);
}
...
}
void process_packet(struct pcap_开发者_运维问答pkthdr *header, const u_char *packet) {
printf("[%d] %d bytes\n", header->ts, header->len);
}
The definition of struct pcap_pkthdr
is:
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
};
The prototype for pcap_next
is u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
Is there any reason that this is happening?
I think the root problem is that in the code
printf("[%d] %d bytes\n", header->ts, header->len);
the ts
data section whose type is struct timeval
is not just a simple integer data, or at least the sizeof(timeval) is not the same as sizeof(int). This will cause the printf uses the wrong address offset when trying to fetch the second parameter in a var arguments list.
So I think printf("[%d] %d bytes\n", header->len, header->ts );
should work correct, but you cannot simply exchange them.
your C code looks valid, I can't see any problem with the syntax. So it might be something not related to C itself.
The only thing that currently comes to mind is that something is running concurrently in the background and slamming your struct. I don't know a lot about pcap, so I can't help you with the specifics...
BUT, When I have such oddities, I usually create a stats function which prints out every conceivable thing about a structure... and call the stats function everywhere... this is like a mini in-line unit test.
I'd like you to refurbish your code into this and try it out:
void hdr_stats(struct pcap_pkthdr *header){
unsigned int i;
printf("address of header: %p\n", header);
printf("caplen: %d\n", header->caplen);
i = header->caplen;
printf("caplen: %d\n", i);
printf("len: %d\n", header->len);
i = header->len;
printf("len: %d\n", i);
//-------
// add header->ts.xxxx debugging here, might give other clues...
//-------
}
...
while((packet = pcap_next(handle, &header)) != NULL) {
printf("[%d]\n", header.len);
hdr_stats(&header);
process_packet(&header, packet);
hdr_stats(&header);
}
...
void process_packet(struct pcap_pkthdr *header, const u_char *packet) {
hdr_stats(header);
printf("[%d]\n", header->len);
hdr_stats(header);
}
this might help you corner your bug.
... are you comparing apples to oranges?
/* header.len in brackets */
printf("[%d]\n", header.len);
/* header->ts in brackets */
printf("[%d] %d bytes\n", header->ts, header->len);
精彩评论