如何解析TCP数据包的负载部分

3
我正在使用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. 解析有效载荷(获取主机url)

我还没有开始解析有效载荷,因为我得到了不一致的结果。以下是使用过滤器"host = www.google.com"捕获的10个TCP数据包的有效载荷打印输出。

数据包编号:3:TCP数据包:源端口:80 目标端口:58723 无数据包

数据包编号:4:TCP数据包:源端口:58723 目标端口:80 无数据包

数据包编号:5:TCP数据包:源端口:58723 目标端口:80 有效载荷: GET / HTTP/1.1 Host: www.google.com User-Agent: 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 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,/;q=0.5 Accept-Language: en-us Accept-Encoding: gzip, deflate Cookie: THICNT=25; SID=DQAAAKIAAAB2ktMrEftADifGm05WkZmlHQsiy1Z2v- Connection: keep-alive

数据包编号: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 OK 日期: Mon, 29 Nov 2010 10:11:36 GMT 过期时间: -1 缓存控制: private, max-age=0 内容类型: text/html; charset=UTF-8 内容编码: gzip 服务器: gws 内容长度: 8806 X-XSS-Protection: 1; mode=block \213

为什么有效载荷和端口存在差异?理想情况下,我只想解析像第5个数据包那样的数据包。如何忽略像7和9这样的数据包?


不清楚您想要过滤数据包的哪个部分。我猜测是源端口或目标端口。 - sashang
我想要获取主机的 URL。我发现通过筛选目标端口为 80 的数据包,我可以“淘汰”不需要的数据包,但是当有人访问非标准端口的 URL 时会发生什么? - David
例如,ssh和ssl加密数据。这些数据包看起来可能与您不想要的类似。顺便说一句,大量流量可能是这样的。使用正则表达式(regex.h)选择数据包- regcomp、regexec等。寻找带有可读字符块的数据包。 - jim mcnamara
3个回答

7

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

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


4

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


3

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

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

然而,正如Remy Lebeau所指出的那样,您实际上需要检查TCP头中的offset字段才能知道有效载荷的起始位置。
数据包5和数据包7之间的区别在于前者是从客户端发送到服务器的,而后者是服务器对客户端的响应。这就是为什么端口会交换 - 源地址和目标地址也会交换。
如果您只想查看来自客户端的数据包,请检查源地址是否等于客户端的地址。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接