我正在尝试使用libpcap查看往返于我的回送网络适配器的http通信。我只是从网络编程开始,对这个库是全新的。多亏了我以前收到的answer,我已经成功检测到机器的“ lo0”适配器(Mac OSx)上的链路层类型。
//lookup link-layer header type
link_layer_type = pcap_datalink(handle);
if(link_layer_type == DLT_NULL){
printf("DLT_NULL"); // this true in the case of "lo0"
}
Programming with Pcap指南假设每个数据包都将包含一个以太网头。因此,用于查找数据包有效负载的逻辑如下:
ethernet = (struct sniff_ethernet*)(packet);
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
}
payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);
检查来自不存在以太网头的环回接口的数据包内容时,此逻辑将无法正常工作。 Link-Layer Header Types documentation指出链接层类型“ DTL_NULL”包含一个4字节的标头,该标头由包含网络层协议(我为IPv4)的PF_值组成。
鉴于以上信息,我如何正确定位数据包的有效负载位置?
任何指导或信息将不胜感激。谢谢!
最佳答案
鉴于以上信息,我如何正确定位数据包的有效负载位置?
对于DLT_NULL
,您的程序应将数据包数据的前4个字节提取为32位数字。如果要进行实时捕获,则可以按主机的字节顺序提取它,并将其与操作系统的AF_INET
和AF_INET6
值(如果它具有AF_INET6
定义)进行比较;这些天,当前大多数最新的OS版本应该,因为它们应该支持IPv6);如果您正在读取捕获文件,则如果pcap_is_swapped()
返回非零值(您也可以将其用于实时捕获;对于实时捕获始终返回零),则需要字节交换该值。您需要与几个不同的“ IPv6”值(24、28和30)进行比较,每个值在某些特定的OS上都表示“ IPv6”(幸运的是,在所有支持AF_INET
的OS上,DLT_NULL
为2,例如他们都从4.2BSD中获得了该价值)。
如果该值是IPv4值(根据上述值为2),则在这4个字节之后,您将拥有该数据包的IPv4标头。如果它是IPv6值之一,则在这4个字节之后,您将拥有该数据包的IPv6标头。如果不是这些值,则是其他协议。
关于c - TCPDump/libpcap-查找有效载荷数据的存储位置,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17258519/