【发布时间】:2016-07-11 20:43:11
【问题描述】:
我的 RAW-Socket 有一个小问题。我必须在网络中捕获数据包才能修改它们。为此,我必须添加特殊数据,例如时间戳。一切正常,但我的 MTU (Linux) 有问题。
如果上层的某些应用程序产生接近MTU的数据包,我无法添加我的数据。所以我决定缩小系统的 MTU。所以我得到了更小的数据包,可以添加我的数据。但是,当我尝试使用 RAW-Socket 发送数据包时,它无法正常工作。
我发现(通过谷歌,在旧的 Stackoverflow 线程和 linux 手册页中)选项 IP_MTU_DISCOVER 可以提供帮助。但是当我将它与 setsockopt 一起使用时,没有任何变化。
if ((s = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL)) < 0) {
printf("Error: could not open socket\n");
return -1;
}
char socket_mtu = IP_PMTUDISC_DONT;
setsockopt(s,IPPROTO_IP,IP_MTU_DISCOVER,socket_mtu, 1);
也许这很重要。 MTU 的缩小已经完成,因为当我添加自己的数据时,生成的数据包不会大于 1500 + ETH-Header。我的问题是,让原始套接字忽略我的 Linux 系统的本地 MTU。
- IP_MTU_DISCOVER 是忽略 MTU 中设置的值的正确方法吗?
- 我的 RAW-SOCKET 真的可以使用 IP_MTU_DISCOVER 吗?
- 还有其他方法可以减少第 3 层及更高层协议的分段大小吗?
我读到,当大小太大时,sendto() 返回 EMSGSIZE (=90)。所以我做了以下测试。
int k = sendto(s, frame.buffer, frame_len, 0,
(struct sockaddr*)&saddrll, sizeof(saddrll));
printf("K:%i\n", k);
调用 sendto() 后,“k”包含“-1”。但是如果取决于数据包的大小,不应该是“90”吗??
当我将我喜欢发送的数据包的大小设置为小于 MTU 时,它可以正常工作....有点奇怪。
任何帮助都会很好:-)
亲切的问候, 安德烈亚斯
【问题讨论】:
标签: c linux network-programming