[英]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.