簡體   English   中英

C中的原始sockets,不是連接冗余嗎?

[英]Raw sockets in C, isn't connect redundant?

我正在編寫一個簡單的程序,它創建一個以太網 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)

問題是,對我來說,stuff 是一個有效的 eth 幀,已經包含了將數據包發送到目的地所需的一切。 那么連接步驟不是多余的嗎? 我錯過了什么?

祝你今天過得愉快。

連接不僅是“冗余”,而且是一個錯誤——根據 Linux 手冊頁:

數據包 sockets 不支持 connect(2) 操作。

所以連接可能失敗但實際上沒有做任何事情。 由於您忽略了 connect 的返回值,因此您不會注意到失敗。

如上所述,連接步驟錯誤。

我將在這篇文章中詳細說明我是如何解決它的,以防有需要的人看到:(這是我的理解,請隨時糾正我)

對於用戶空間中真正的原始通信,您必須了解三個概念:

  1. Sockets 類似於文件描述符。
  2. 綁定套接字就像打開一個文件。
  3. 您無法讀取或寫入套接字,請讓 kernel 為您完成。

我遵循的過程如下:

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);

正如你所看到的,我們並沒有真正使用 connect,因為它確實是一個錯誤。

ps獲取完整示例: https://github.com/TretornESP/RAWRP

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM