2013-06-23 46 views
0

我想查看使用libpcap往返于我的环回网络适配器的http流量。我只是从网络编程开始,对这个库完全陌生。感谢我之前收到的answer,我已经成功地检测到我的机器的“lo0”适配器(Mac OSx)上的链接层类型。TCPDump/libpcap - 找到有效载荷数据的内存位置

//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); 

此逻辑结算不会检查数据包从那里以太网头不存在loopback接口始发的内容时工作。 Link-Layer Header Types documentation指出链接层类型的“DTL_NULL”包含一个由包含网络层协议的PF_值组成的4字节头(在我的例子中,我猜IPv4)。

鉴于上述信息..我如何正确定位数据包的有效载荷位置?

任何指导或信息将不胜感激。谢谢!

回答

0

鉴于上述信息,我该如何正确定位数据包的有效载荷位置?

对于DLT_NULL,程序应该将数据包的前4个字节提取为32位数字。如果您正在进行实时捕获,则可以按主机的字节顺序提取它,并将其与您的操作系统值AF_INETAF_INET6(如果它具有AF_INET6定义进行比较;如今它们应该支持大多数当前操作系统版本IPv6的);如果您正在读取捕获文件,那么如果pcap_is_swapped()返回非零值(您也可以将其用于实时捕获;实时捕获总是返回零),则需要对该值进行字节交换。需要与几个不同的“IPv6”值(24,28和30)进行比较,其中每个值在某些特定操作系统上均表示“IPv6”(幸运的是,AF_INET在支持DLT_NULL的所有操作系统上均为2,因为它们都从该值4.2BSD)。

如果该值是IPv4值(2,如上所述),那么在这4个字节之后,您将拥有该数据包的IPv4标头。如果它是其中一个IPv6值,那么在这4个字节之后,您将拥有该数据包的IPv6标头。如果它不是这些值中的任何一个,则是其他协议。