繁体   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