EMSGSIZE when trying to send data on raw IP packet

蹲街弑〆低调 提交于 2021-02-05 06:50:12

问题


My code sends a raw IP packet to 12.12.12.12 and fails because of EMSGSIZE. I think that it limits my packet according to Ethernet MTU, but it should send packets <= 65,535 bytes (IPv4 MTU).

I've tried to send a packet to 127.0.0.1 and this worked well, but the error occurs when I send a packet to a non-local 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);
}

I expect that the code will work without any errors because I send a packet that is less than IP MTU. Troubleshoot the code with 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

回答1:


I think that it limits my packet according to Ethernet MTU, but it should send packets <= 65,535 bytes (IPv4 MTU).

Since PMTU is on by default it will only send packets fitting in the MTU. Your packet doesn't. From raw(7):

By default, raw sockets do path MTU (Maximum Transmission Unit) discovery. This means the kernel will keep track of the MTU to a specific target IP address and return EMSGSIZE when a raw packet write exceeds it. When this happens, the application should decrease the packet size.
Path MTU discovery can be also turned off using the IP_MTU_DISCOVER socket option or the /proc/sys/net/ipv4/ip_no_pmtu_disc file, see ip(7) for details. When turned off, raw sockets will fragment outgoing packets that exceed the interface MTU. However, disabling it is not recommended for performance and reliability reasons.



来源:https://stackoverflow.com/questions/57214403/emsgsize-when-trying-to-send-data-on-raw-ip-packet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!