我正在进行一项任务,其中一部分涉及使用pcap捕获数据包。 我跟着一个tutorial,现在我正在尝试一些我发现here的代码,类似于此:
//#define __USE_BSD
//#define __FAVOR_BSD
#define MAXBYTES2CAPTURE 2048
#define SIZE_ETHERNET 14
#include <stdio.h>
#include <stdlib.h>
#include <libnet.h>
#include <string.h>
#include <pcap.h>
#include <netinet/tcp.h>
#include <netinet/ip.h>
int main(){
int count = 0;
bpf_u_int32 netaddr=0, mask=0;
pcap_t *descr = NULL;
struct bpf_program filter;
struct ip *iphdr = NULL;
struct tcphdr *tcphdr = NULL;
struct pcap_pkthdr pkthdr;
const unsigned char *packet = NULL;
char pcap_errbuf[PCAP_ERRBUF_SIZE];
descr = pcap_open_live("eth0", MAXBYTES2CAPTURE, 0, 512, pcap_errbuf );
pcap_lookupnet("eth0", &netaddr, &mask, pcap_errbuf );
pcap_compile( descr, &filter, "port 111", 1, mask );
pcap_setfilter( descr, &filter);
packet = pcap_next(descr, &pkthdr );
iphdr = (struct ip *)(packet+14);
tcphdr = (struct tcphdr *)(packet+14+20);
printf("SEQ: %d:\n", ntohl(tcphdr->th_seq) );
pcap_close(descr);
return(0);
}
问题是我收到编译错误:
'struct tcphdr'没有名为'th_seq'的成员。
我发现有更多人询问此事,一些回复建议包括:
#define __USE_BSD
#define __FAVOR_BSD
但无论是否添加,我都会收到错误。 th_seq应该包含在netinet/tcp.h
中吗?我测试了Ubuntu 12.04和linux 3.2上的代码,都给出了错误。
任何人都知道如何解决这个问题?
答案 0 :(得分:1)
这是一个古老的问题,但我可以在你的OWN代码中回答它,如果定义了__FAVOR_BSD(不自己定义),则使用tcphdr-&gt; th_off;如果不是,则使用tcphdr-&gt; doff。像这样:
#if (defined (__FAVOR_BSD))
len -= sizeof (uint32_t) * tcp->th_off;
packet += sizeof (uint32_t) * tcp->th_off;
#else
len -= sizeof (uint32_t) * tcp->doff;
packet += sizeof (uint32_t) * tcp->doff;
#endif
如果你这样做,你可能会遇到许可问题,但对于我正在做的事情,我不在乎 - 这是内部代码,不是产品的一部分,如果我们不得不使用GPL,我们很乐意这样做。
两个版本的tcphdr工作得很好,出于某种原因,它们的命名方式不同。如果你这么做的话,你也可以制作宏。我只是跳过标题,直到我获取数据包中的数据进行检查。
答案 1 :(得分:0)
任何人都知道如何解决这个问题?
好吧,tcpdump通过不依赖OS的头来定义数据包布局来解决这个问题。它有自己的标题,或者在源文件中定义布局。
您可能想要做同样的事情,从具有相应许可证的操作系统中复制标头(tcpdump是BSD许可的,并从BSD获取其标头;如果您希望您的程序获得GPL许可,您可能希望看看Linux有什么标题,并根据需要编辑它们,或编写自己的结构定义。