C 中的原始套接字,连接不是多余的吗?



我正在编写一个简单的程序,该程序创建一个以太网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帧,已经包含了将数据包发送到目的地所需的一切。那么,连接步骤不是多余的吗?我错过了什么?

祝你今天愉快。

连接;"冗余";,这是一个错误——根据Linux手册页:

数据包套接字不支持connect(2(操作。

所以连接可能失败了,但实际上什么都没做。由于您忽略了connect的返回值,因此不会注意到失败。

如上所述,连接步骤是错误的。

我将在这篇文章中给出我如何解决它的细节,以防有人看到这一点:(这是我所理解的,请随时纠正我(

对于用户空间中真正原始的通信,您必须理解三个概念:

  1. 套接字类似于文件描述符
  2. 绑定套接字就像打开文件一样
  3. 您不能对套接字进行读取或写入,只需请求内核为您完成即可

我遵循的过程如下:

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,因为它确实是一个错误。

完整示例的p.s.:https://github.com/TretornESP/RAWRP

最新更新