【问题标题】:libpcap packet sizelibpcap 数据包大小
【发布时间】:2011-02-05 09:03:53
【问题描述】:

我在 linux (centos) 上使用 C 语言中的 libpcap,我正在关注 this guide 我想简单地在 ascii 中打印出整个数据包,并且我设法通过将其转换为 u_char* 来使其工作在“my_callback”函数中。但我不知道如何获取数据的长度。 strstr 没有工作。标头有一个 len 成员,您可以访问它以获取大小,但我找不到与传递的 *packet 类似的任何东西。任何帮助表示赞赏。

【问题讨论】:

  • 因为我不知道,所以我不会将其作为答案发布......但从标题中的一些注释中可以看出,caplen 成员将是数据的长度。
  • 数据包不会是 ASCII,因此将所有数据字节视为 ASCII 字符串是行不通的;特别是,在上面使用strstr() 是个坏主意。阅读该指南中的代码,它将数据包数据处理为二进制数据。爱因斯坦的答案是正确的;使用struct pcap_pkthdrcaplen字段作为包数据的字节数。

标签: c linux gcc libpcap


【解决方案1】:

在您的回调中,pkthdr 变量的 caplen 成员(参见 struct pcap_pkthdr)包含捕获的数据包的大小。

例如假设一个数据包被捕获。帧的总长度为 1024 字节。但是,捕获驱动程序仅捕获帧的前 128 个字节,并使其可用于您的回调。

在这种情况下,您应该期望 pkthdr->caplen 为 128,header->len 为 1024。

【讨论】:

    【解决方案2】:

    数据包总大小位于 ip 标头 (http://en.wikipedia.org/wiki/IPv4_header#Total_Length) 的“总长度”字段中。

    如何使用 libpcap 获取该值可以在此示例中找到:http://www.tcpdump.org/sniffex.c

    您只需要从此变量中获取引用“总长度”(名为 ip_len)的字段的值:

    const struct sniff_ip *ip;              /* The IP header */
    

    【讨论】:

    • 不,这是一个 IPv4 数据包的总长度;并非所有数据包都是 IPv4 数据包(它们可能是 IPv6 数据包、ARP 数据包或各种其他类型的数据包),并且在大多数情况下,IPv4 数据包的长度并不是网络上整个数据包的长度 - 例如,对于以太网,还有 14 字节的以太网报头,如果 IPv4 数据包 + 14 的长度小于 60,那么还有一个以太网尾部将数据包填充到 60 字节(如果包含 CRC,则为 64 字节)以太网段。
    • 有什么方法可以使用 libpcap 获取数据包长度,而与数据包类型(ip、arp、icmp...)无关?
    • 是的 - struct pcap_pkthdrlen 字段是数据包在线路/空中的实际长度(尽管,对于“空中”,请注意在大多数平台上,除非您在监控模式下捕获,否则 802.11 数据包将转换为“假以太网”数据包,并且“len”字段给出了假以太网数据包的假长度,而不是“空中”802.11 数据包的真实长度) .但是,NOT 不一定是您在捕获中拥有的实际数据包数据量 - 那是 caplen
    • 不知道该怎么办,我想删除我的答案,因为它是错误的,但可能对其他人有用。
    • 此外,数据包可能有一个“伪标头”,其中包含有关数据包的“元数据”,位于实际的“在线”/“空中”链路层标头之前。例如,在 802.11 接口上以监控模式捕获的数据包可能具有radiotap header 提供信号强度等信息。如果存在这样的标头,则caplenlen 中的值包括元数据标头的长度以及“在线”/“空中”数据包的长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 2010-11-20
    • 2011-01-11
    • 2014-03-12
    • 2015-10-23
    相关资源
    最近更新 更多