【问题标题】:How to parse TCP packet payload如何解析 TCP 数据包有效负载
【发布时间】:2011-05-17 05:10:14
【问题描述】:

我正在使用 pcap 来捕获我想要解析其有效负载的 TCP 数据包。我的策略如下:

  1. 获取以太网标头并检查其类型是否为ETHERTYPE_IP(IP 数据包)
  2. 检查IP包是否有协议IPPROTO_TCP(TCP包)
  3. 检查负载大小 > 0 (size = ntohs(ip_header->total_length - ip->header_length*4 - sizeof(struct tcp_header))

  4. 解析payload(获取主机url)

我还没有开始解析有效负载,因为我遇到了差异。下面是使用过滤器"host = www.google.com" 捕获的 10 个 TCP 数据包的有效负载的打印输出。

数据包编号:3:TCP 数据包:源端口:80 目标端口:58723 数据包中没有数据

数据包号:4:TCP 数据包:源端口:58723 目标端口:80 数据包中没有数据

数据包编号:5:TCP 数据包:源端口:58723 目标端口:80 有效负载: 获取/HTTP/1.1 主机:www.google.com 用户代理:Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4 接受:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5 接受语言:en-us 接受编码:gzip,放气 饼干:THICNT=25; SID=DQAAAKIAAAB2ktMrEftADifGm05WkZmlHQsiy1Z2v- 连接:保持活动

数据包编号:6:TCP 数据包:源端口:80 目标端口:58723 数据包中没有数据

数据包编号:7:TCP 数据包:源端口:80 目标端口:58723 有效负载: \272نu\243\255\375\375}\336H\221\227\206\312~\322\317N\236\255A\343#\226\370֤\245[\327`\306ըnE\263\204\ 313\356\3268 )p\344\301_Y\255\267\240\222x\364

数据包号:8:TCP 数据包:源端口:58723 目标端口:80 数据包中没有数据

数据包编号:9:TCP 数据包:源端口:80 目标端口:58723 有效负载: HTTP/1.1 200 正常 日期:2010 年 11 月 29 日星期一 10:11:36 GMT 过期:-1 缓存控制:私有,max-age=0 内容类型:文本/html;字符集=UTF-8 内容编码:gzip 服务器:gws 内容长度:8806 X-XSS-防护:1;模式=块 \213

为什么负载和端口存在差异?理想情况下,我只想解析数据包 5 之类的数据包。如何忽略数据包 7 和 9?

【问题讨论】:

  • 不清楚您要过滤数据包的哪一部分。我假设它是源端口或目标端口。
  • 我想获取主机地址。我发现通过使用目标端口 80 过滤数据包,我设法“清除”了不需要的数据包,但是当有人访问非标准端口上的 url 时会发生什么?
  • 例如 ssh & ssl 加密数据。这些数据包看起来像您不想要的数据包。 FWIW 的大量流量可能是这样的。使用正则表达式 (regex.h) 选择数据包 - regcomp、regexec 等。查找具有可读字符块的数据包。

标签: c++ c tcp pcap packet-sniffers


【解决方案1】:

您的大小计算不正确-您不能在网络主机顺序中进行减法,您必须先将每个字段转换为主机字节顺序:

size = ntohs(ip_header->total_length) - ntohs(ip->header_length) * 4 - sizeof(struct tcp_header))

但是,正如Remy Lebeau 指出的那样,您实际上需要检查 TCP 标头中的 offset 字段以了解有效负载的开始位置。

数据包5和数据包7的区别在于前者是客户端,服务器,而后者是从服务器到服务器的响应客户。这就是端口切换的原因 - 源地址和目标地址也将切换。

如果您只想查看来自客户端的数据包,请检查源地址是否等于客户端的地址。

【讨论】:

    【解决方案2】:

    与 IP 标头一样,TCP 标头也是可变长度的。你没有考虑到这一点。与其盲目地从总包大小中减去sizeof(struct tcp_header)),不如在IP数据中定位TCP头,然后使用它的长度字段(需要乘以4,就像IP头长度字段一样)知道实际数据负载所在的位置。

    【讨论】:

      【解决方案3】:

      仅通过分析内容。 IP 或 TCP 标头中没有可以标记“HTTP 请求”数据包的内容。即使是“连接中的第一个数据包”也行不通,因为存在持久连接。

      此外,要完全确定捕获所有 URI,您需要重新组装 TCP 流并解析 HTTP 请求:URI 可以拆分为两个或多个数据包。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-28
        • 2016-10-25
        • 1970-01-01
        • 2012-12-21
        • 2015-02-02
        • 1970-01-01
        • 2022-08-18
        • 1970-01-01
        相关资源
        最近更新 更多