c - TCPDump/libpcap - 查找有效负载数据的内存位置

标签 c tcp network-programming libpcap tcpdump

我正在尝试使用 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指南假设每个数据包将包含以太网 header 。因此,用于查找数据包有效负载的逻辑如下:

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

在检查源自不存在以太网 header 的环回接口(interface)的数据包内容时,此逻辑显然不起作用。 Link-Layer Header Types documentation声明“DTL_NULL”的链路层类型包含一个 4 字节 header ,该 header 由包含网络层协议(protocol)的 PF_ 值组成(我猜在我的情况下是 IPv4)。

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

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

最佳答案

Given the above information.. how can I properly locate the packet's payload location?

对于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 header 。如果它是 IPv6 值之一,那么在这 4 个字节之后,您将获得数据包的 IPv6 header 。如果不是这些值中的任何一个,则它是其他协议(protocol)。

关于c - TCPDump/libpcap - 查找有效负载数据的内存位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17258519/

相关文章:

c++ - 在Python中解析.c/.cpp/.py源文件以获取包含的函数列表

c - 我的代码有问题,我不确定我是否正确编写了它

c - 热衷于将 TXT 文件转换为结构数组 - 段错误?

c - 如何在内核中放置微秒延迟?

sockets - netcat 如何从两个不同的终端监听同一主机上的同一端口?

c++ - 使用 emscripten 将位图缓冲区渲染到 HTML5 Canvas 中

ssl - 为什么 QUIC 协议(protocol)使用在 TCP 上运行的 TLS 数据包时却被说是基于 UDP 构建的?

IPX/SPX 和 TCP/IP 的性能

c# - C# 中 networkstream.read() 的奇怪行为

Java向我的世界服务器发送握手包