Mac更改IP总长度字段



我在Mac 10.6.8中使用套接字进行编程。每当我收到一个数据包时,它都会从IP头开始。我一直在使用Wireshark来分析传入的数据包,我注意到我的机器的套接字实现会持续更改IP标头中的"总长度"字段。具体来说,它将减去IP标头长度并反转字节(从网络到主机的顺序)。

例如,以下是Wireshark报告的IP标头的开头:

45 c0 00 38 ...

其分解如下:

  • 4位(0x4):IP版本:4
  • 4位(0x5):IP标头长度:5个字(20字节)
  • 8位(0xc0):区分服务标志
  • 16位(0x0038):总长度:56字节

但是,当我为同一个数据包打印recvfrom填充的缓冲区的内容时,我会得到不同的lede:

ssize_t recvbytes = recvfrom(sock->fd, buffer, size, /*flags=*/0,
(struct sockaddr*)src, &src_len);

返回

45 c0 24 00 ...
  • 4位(0x4):IP版本:4
  • 4位(0x5):IP标头长度:5个字(20字节)
  • 8位(0xc0):区分服务标志
  • 16位(0x2400):总长度:9216字节(?!)

我发现,在访问缓冲区之前,套接字实现是读取总长度,减去IP标头长度,然后按主机顺序(机器上的小端序)而不是网络顺序(大端序)将其写回。在本例中,这意味着:

  • 读取总长度:0x0038=56
  • 减去标头长度:56-20=36
  • 按主机顺序写回:36=0x0024(big-endian)=0x2400(little-endian=我机器上的主机顺序)

问题越来越严重。它不会仅仅改变最外层IP头的总长度。它还将更改内部IP标头的总长度字段,例如,ICMP"超时"消息中隐藏的字段(必须包括丢弃数据包的原始IP标头)。更有趣的是,它不会从内部报头中减去IP报头长度;它只是颠倒字节顺序。

这种情况发生在其他人身上吗?这是我不知道的标准的一部分吗?有没有办法修复我机器的套接字实现,以停止篡改数据包?Wireshark是如何解决这个问题的?

提前感谢您的考虑。

编辑:我的代码和Makefile可以在GitHub上找到。我编写了一个fixip_osx函数来允许验证IP校验和:

https://github.com/thejohnfreeman/netutils/blob/master/lib/ip.c

void fixip_osx(struct ip* ip) {
/* Something on my Mac subtracts the header length from `ip_len` and stores
* it in host order (little endian). */
u16_t ip_hdrlen = ip->ip_hl << 2;
u16_t ip_totlen = ip->ip_len + ip_hdrlen;
ip->ip_len = htons(ip_totlen);
}

然而,当有效负载包含另一个IP标头时,验证ICMP校验和仍然是一个问题。

无论我是用Clang 3.2(从主干编译)还是GCC 4.7(MacPorts端口)编译,问题都存在,所以我认为问题在于套接字实现(与Mac OS打包)或Mac OS X本身。

BSD平台套件(不包括OpenBSD)以主机字节顺序显示IP偏移量和长度。接收到的网络字节顺序中存在的所有其他平台。这是一个"特性",在IP(4)-互联网协议(FreeBSD,OSX)的手册页中有提及。

ip_len和ip_off字段必须按主机字节顺序提供。所有其他字段必须按网络字节顺序提供。

在FreeBSD/NetBSD中,IP长度可以等于packet length - IP header length

参考:Stevens/Fenner/Rudolph,Unix网络编程第1卷,第739页

我必须用PGM网络协议的用户空间实现来处理这些异常,具体代码:

https://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/packet_parse.c#76

事实上,检测AutoConf很烦人,我认为所有的包都是在每个平台的基础上进行硬编码的。本周我看到了一个关于这个问题的错误报告(头字节顺序配置选项检测不正确)。

Mac本身不太可能这么做。这将从根本上破坏IP协议。更可能的是,无论是捕获数据包并将其发送到recvfrom()(大概你正在进行一次混乱的网络捕获,对吧?),都是在Mac处理完数据后对数据进行转换的。ireshark在较低级别上运行,可以访问实际的网络数据。

最新更新