繁体   English   中英

尝试在原始IP数据包上发送数据时的EMSGSIZE

[英]EMSGSIZE when trying to send data on raw IP packet

我的代码将原始IP数据包发送到12.12.12.12 ,由于EMSGSIZE而失败。 我认为它根据以太网MTU限制了我的数据包,但是它应该发送<= 65,535字节(IPv4 MTU)的数据包。

我尝试将数据包发送到127.0.0.1并且效果很好,但是当我将数据包发送到非本地IP时出现错误。

#include <assert.h>
#include <string.h>

#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main(void) {
    int fd;
    assert((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) != -1);

    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(1818);
    assert(inet_aton("12.12.12.12", &addr.sin_addr) != -1);
    assert(connect(fd, (struct sockaddr *)&addr, sizeof(addr)) != -1);

    char buffer[2000];
    memset(buffer, '\0', sizeof(buffer));
    assert(send(fd, buffer, sizeof(buffer), 0) == sizeof(buffer));

    assert(close(fd) != -1);
}

我希望代码可以正常工作,因为我发送的数据包小于IP MTU。 使用strace对代码进行故障排除:

socket(AF_INET, SOCK_RAW, IPPROTO_RAW)  = 3
connect(3, {sa_family=AF_INET, sin_port=htons(1818), sin_addr=inet_addr("12.12.12.12")}, 16) = 0
sendto(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 2000, 0, NULL, 0) = -1 EMSGSIZE (Message too long)
a.out: compile.c:22: main: Assertion `send(fd, buffer, sizeof(buffer), 0) == sizeof(buffer)' failed.
--- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=8814, si_uid=0} ---
+++ killed by SIGABRT (core dumped) +++
Aborted

我认为它根据以太网MTU限制了我的数据包,但是它应该发送<= 65,535字节(IPv4 MTU)的数据包。

由于默认情况下PMTU是打开的,因此它将仅发送适合MTU的数据包。 您的包裹没有。 raw(7)

默认情况下,原始套接字执行路径MTU (最大传输单元)发现。 这意味着内核将跟踪到特定目标IP地址的MTU,并在原始数据包写入超出该值时返回EMSGSIZE 发生这种情况时,应用程序应减小数据包的大小。
也可以使用IP_MTU_DISCOVER套接字选项或/ proc / sys / net / ipv4 / ip_no_pmtu_disc文件关闭路径MTU发现 ,有关详细信息,请参见ip(7)。 关闭时,原始套接字将对超出接口MTU的传出数据包进行分段。 但是,出于性能和可靠性的原因,不建议禁用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM