libpcap 读取数据包大小

Posted

技术标签:

【中文标题】libpcap 读取数据包大小【英文标题】:libpcap read packet size 【发布时间】:2013-06-18 02:37:16 【问题描述】:

我开始编写一个应用程序,它将从现有的 .pcap 文件中读取 RTP/H.264 视频数据包,我需要读取数据包大小。 我尝试使用 packet->len 或 header->len,但它从不显示正确的数据包字节数(我使用 wireshark 来验证数据包大小 -在长度列下)。怎么做? 这是我的代码的一部分:

while (packet = pcap_next(handle,&header)) 

  u_char *pkt_ptr = (u_char *)packet;
  struct ip *ip_hdr = (struct ip *)pkt_ptr; //point to an IP header structure 
  struct pcap_pkthdr  *pkt_hdr =(struct pcap_pkthdr *)packet;

  unsigned int packet_length = pkt_hdr->len;
  unsigned int ip_length = ntohs(ip_hdr->ip_len);
  printf("Packet # %i IP Header length: %d bytes, Packet length: %d bytes\n",pkt_counter,ip_length,packet_length);


Packet # 0 IP Header length: 180 bytes, Packet length: 104857664 bytes
Packet # 1 IP Header length: 52 bytes, Packet length: 104857600 bytes
Packet # 2 IP Header length: 100 bytes, Packet length: 104857600 bytes
Packet # 3 IP Header length: 100 bytes, Packet length: 104857664 bytes
Packet # 4 IP Header length: 52 bytes, Packet length: 104857600 bytes
Packet # 5 IP Header length: 100 bytes, Packet length: 104857600 bytes

我尝试的另一个选项是使用: pkt_ptr-> 我明白了:

read_pcapfile.c:67:43: 错误:在不是结构或联合的东西中请求成员“len”

【问题讨论】:

【参考方案1】:
while (packet = pcap_next(handle,&header)) 

  u_char *pkt_ptr = (u_char *)packet;

不要那样做;你扔掉了const,你真的应该修改pcap_next()的返回值指向。

  struct ip *ip_hdr = (struct ip *)pkt_ptr; //point to an IP header structure

如果pcap_datalink(handle) 返回DLT_RAW,它将指向一个IP 标头结构,它可能不会在大多数设备上这样做。

如果,例如,pcap_datalink(handle) 返回 DLT_EN10MBpacket 将指向一个 Ethernet 标头(10MB 是历史性的 - 它用于除古代以外的所有以太网速度Xerox 的历史 3MB 实验性以太网,具有不同的标头类型)。

有关可能的DLT_ 类型列表,请参阅the list of link-layer header type values。

  struct pcap_pkthdr  *pkt_hdr =(struct pcap_pkthdr *)packet;

那也行不通。数据包的struct pcap_pkthdr 位于header

  unsigned int packet_length = pkt_hdr->len;

根据我之前的评论,这是行不通的。请改用header.len

(请记住,如果在pcap_open_live() 调用中指定的“快照长度”小于最大数据包大小,或者在pcap_create()pcap_activate() 调用之间的pcap_set_snaplen() 调用中指定, header.caplen 可能小于header.len,并且实际上只有header.caplen 字节的数据包数据可用。)

  unsigned int ip_length = ntohs(ip_hdr->ip_len);

而且,根据我之前的评论,这可能也行不通。

【讨论】:

【参考方案2】:

您应该使用header.len

unsigned int packet_length = header.len;

【讨论】:

以上是关于libpcap 读取数据包大小的主要内容,如果未能解决你的问题,请参考以下文章

UDP数据包字节读取粒度?

使用 libpcap,有没有办法从离线 pcap 文件中确定捕获的数据包的文件偏移量?

解析 WiFi 数据包 (libpcap)

tcpdump 常用例子

基于Libpcap实现一个网络数据包嗅探器

如何使用 libpcap 在原始数据包的 TCP 标头中打印标志