我正在使用libpcap编写数据包解析器,并在尝试从pcap头读取数据包长度时遇到奇怪的行为。
下面的第一个printf
语句打印出正确的数据包长度,而第二个语句打印出一个数字,如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);
}
struct pcap_pkthdr
的定义是:
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) */
};
pcap_next
的原型是u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
有没有理由发生这种情况?
答案 0 :(得分:3)
我认为根本问题在于代码
printf("[%d] %d bytes\n", header->ts, header->len);
类型为ts
的{{1}}数据部分不仅仅是一个简单的整数数据,或者至少sizeof(timeval)与sizeof(int)不同。这将导致printf在尝试获取var参数列表中的第二个参数时使用错误的地址偏移量。
所以我认为struct timeval
应该正确,但你不能简单地交换它们。
答案 1 :(得分:0)
您的C代码看起来有效,我看不出语法有任何问题。所以它可能与C本身无关。
目前唯一想到的是,某些事情在后台同时运行并且砰击你的结构。我对pcap了解不多,所以我不能帮你详细说明......
但是,当我有这样的奇怪之处时,我通常创建一个stats函数,打印出关于结构的所有可想象的东西......并在任何地方调用stats函数......这就像一个迷你的在线单元测试。 / p>
我希望您将代码重新整理并尝试一下:
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);
}
这可能会帮助你改变你的错误。
答案 2 :(得分:0)
...你在比较苹果和橘子吗?
/* header.len in brackets */
printf("[%d]\n", header.len);
/* header->ts in brackets */
printf("[%d] %d bytes\n", header->ts, header->len);