簡體   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