我正在撰寫一個簡單的程式,它創建一個以太網 I 幀并通過介面將其發送到指定的 MAC。
正如我所讀到的,在 UNIX 中連接到套接字的程序有點像:
int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
struct sockaddr_ll sll;
/* populate sll with the target and interface info */
connect(sockfd, (struct sockaddr*)&sll, sizeof(sll));
write(sockfd, stuff, sizeof(stuff));
close(sockfd)
事情是,對我來說,東西是一個有效的 eth 幀,已經包含將資料包發送到目的地所需的一切。那么連接步驟不是多余的嗎?我錯過了什么?
祝你今天過得愉快。
uj5u.com熱心網友回復:
根據 Linux手冊頁,連接不僅是“冗余的”,而且是錯誤的:
資料包套接字不支持 connect(2) 操作。
所以連接可能失敗了,但實際上沒有做任何事情。由于您忽略了 connect 的回傳值,因此您不會注意到失敗。
uj5u.com熱心網友回復:
如上所述,連接步驟是錯誤的。
我將在這篇文章中詳細說明我是如何解決它的,以防有需要的人看到這個:(這是我的理解,請隨時糾正我)
對于用戶空間中真正原始的通信,您必須了解三個概念:
- 套接字類似于檔案描述符。
- 系結套接字就像打開一個檔案。
- 您無法讀取或寫入套接字,請讓內核為您執行此操作。
我遵循的程序如下:
int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
struct sockaddr_ll sll;
sll.sll_family = AF_PACKET;
sll.sll_ifindex = index; //This is the index of your network card
//Can be obtained through ioctl with SIOCGIFINDEX
sll.sll_protocol = htons(ETH_P_ALL);
bind(sockfd, (struct sockaddr*)&sll, sizeof(sll));
size_t send_len = write(sockfd, data, size);
如您所見,我們并沒有真正使用連接,因為它確實是一個錯誤。
ps 一個完整的例子:https : //github.com/TretornESP/RAWRP
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/371990.html
