【问题标题】:Reading tpacket3_hdr from Packet MMAP and getting payload body从 Packet MMAP 读取 tpacket3_hdr 并获取有效负载主体
【发布时间】:2021-06-09 06:45:02
【问题描述】:

我有一个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

【问题讨论】:

  • 提示:你为什么在前两行写(uint8_t *)
  • @JosephSible-ReinstateMonica 指向 eth 地址和 ip 地址的开始。为什么有问题?

标签: c linux mmap packet


【解决方案1】:

[改编自 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 位,长度为 4 位)。

对于 IP,相应的计算是:

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

这就是 TCP 标头开始的偏移量(以字节为单位)。偏移量IPMHLENIPHLEN(pip)(如果有)之间的空间被IP 选项占用。

RFC:

IP structure

TCP structure


这是原始段的布局,因为它在网络上传播。我假设您的文件按原样存储此格式。

[我不会在任何偏移/大小计算中使用sizeof,因为内存中的结构可能包含填充和对齐。]

【讨论】:

  • 感谢您的回答。我在哪里可以获得from Cormen and Stevens, 10.4 TCP Segment Format的链接
  • 这是一本书。您可以在书店或图书馆中获得它,它基本上包含 rfc-editor.org/rfc/rfc791.txtrfc-editor.org/rfc/rfc793.txt(和其他)的幼稚实现
  • 书名是Internetworking with TCP/IP Vol.1: Principles, Protocols, and Architecture (4th Edition)可以确认一下吗。如果不是,那么这本书的全名是什么?
  • 不,你需要第 2 卷:“设计、实施和内部”
  • 不,当然不是。有效负载可能包含二进制 NUL(或不是 NUL 终止的),因此 strlen() 通常是一个糟糕的选择。
猜你喜欢
  • 2017-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
  • 2019-06-22
相关资源
最近更新 更多