从 Packet MMAP 读取 tpacket3_hdr 并获取负载主体

Reading tpacket3_hdr from Packet MMAP and getting payload body

我有一个 tpacket3_hdr *ppd 指针对象。我知道如何提取 iphdr 和 tcphdr,但是如果我需要数据包的主体部分怎么办。我正在尝试这样

  struct iphdr *ip = (struct iphdr *) ((uint8_t *) eth + ETH_HLEN);
  struct tcphdr *tcp=(struct tcp *)((uint8_t *)ip+sizeof(struct iphdr));
  char *payload_body=(char *)(tcp+sizeof(struct tcphdr));
  printf("%s\n",payload_body);//Printing wrong Not containing what I am checking by simply downloading html

我认为这样做不正确。来自 MMAP 的 Rx Ring 的完整代码在此处给出 https://elixir.bootlin.com/linux/latest/source/tools/testing/selftests/net/psock_tpacket.c

[改编自 Cormen 和 Stevens,10.4 TCP 段格式]

    /* The offset of the payload data (in 32bit words))
    ** is tucked into the upper 4 bits of an unsigned character.
    ** Typically (0x5x & 0xf0) >>2 := 0x20
    */

#define TCP_HLEN(p) (((p)->tcp_offset & 0xf0) >> 2)

char *payload_body=(char *)((uint8_t *)tcp + TCP_HLEN(tcp)) ;

ip 结构在其 ip_verlen 字段中有一个类似的长度字段(版本:=4 位,lengh_in_words:= 4 位)。

对于 IP,相应的计算将是:

#define IPMHLEN 20 /* minimum IP header length (in bytes) */
#define IP_HLEN(pip) (((pip)->ip_verlen & 0xf) <<2)

这就是 TCP header 开始的偏移量(以字节为单位)。偏移IPMHLENIPHLEN(pip)之间的space(如果有的话)被IP-options.

占用

RFC:

IP structure

TCP structure


这是原始片段在网上传播时的布局。我假设您的文件存储这种格式 as-is.

[我会 在任何 offset/size 计算中使用 sizeof,因为 in-memory 结构可能包含填充和对齐。]