struct tcphdr中没有成员th_seq(使用pcap)

时间:2014-02-19 22:09:01

标签: c pcap

我正在进行一项任务,其中一部分涉及使用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上的代码,都给出了错误。

任何人都知道如何解决这个问题?

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有什么标题,并根据需要编辑它们,或编写自己的结构定义。