如何使用sendto通过原始以太网套接字发送数据而不使用sockaddr_ll?

Euk*_*des 6 c sockets ose

我正在开发一个项目,我们使用Enea OSE,这是一个实时嵌入式操作系统.我猜你们很多人都不熟悉这个操作系统,但我认为无论如何你都可以回答我的问题.我想使用接口"eth1"在2张卡之间发送原始以太网帧,这些接口通过以太网电缆(无交换机或任何东西)直接连接到另一个."eth1"接口未分配任何IP地址.

我可以简单地使用socket声明一个套接字

int s = socket(AF_INET, RAW_SOCKET, ...)
Run Code Online (Sandbox Code Playgroud)

然后我可以使用以下命令将套接字绑定到相应的设备接口:

setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth1", 4);
Run Code Online (Sandbox Code Playgroud)

为了将数据从一张卡发送到另一张卡,我的计划是手动填写带有源和目标MAC地址的以太网缓冲区阵列.然后使用sendto(....)发送数据

但是sendto例程还需要一个带有信息的sockaddr结构:

  sendto(int sockfd, const void *buf, size_t len, int flags,
           const struct sockaddr *dest_addr, socklen_t addrlen);
Run Code Online (Sandbox Code Playgroud)

在我已经在互联网上找到的例子中使用SOCKADDR_IN当IP地址是已知的,sockaddr_ll的原始帧.但是,OSE不提供sockaddr_ll结构.但它提供了sockaddr我不知道如果我可以用于原始以太网帧?

struct sockaddr {
    unsigned short    sa_family;    // address family, AF_xxx
    char              sa_data[14];  // 14 bytes of protocol address
};
Run Code Online (Sandbox Code Playgroud)

我也尝试使用NULL,当调用sendto()时,对于sockaddr字段,发送失败.这让我想到了我的问题.我可以使用简单的sockaddr结构来填充目标MAC地址而不使用任何IP吗?那怎么样?(我没有看到任何显示此代码的代码).为什么我们甚至必须提供sockaddr结构?以太网数据缓冲区是否已包含此信息?最后,如果没有为网络设备分配IP地址,我是否正在努力实现?

我知道我想要做的事情看起来很奇怪,但有一个原因吧:)如果你能告诉我如何在不使用sockaddr_ll结构的情况下完成这项工作,我会很高兴的.

Ser*_* L. 3

据我所知 Enea OSE 附带这些标头

#include <sys/socket.h>
#include <netpacket/packet.h>
Run Code Online (Sandbox Code Playgroud)

后者声明struct sockaddr_ll它应该允许您将以太网数据包发送到类型的套接字

int sockfd = socket(AF_PACKET, type, protocol);
Run Code Online (Sandbox Code Playgroud)

类型可以是SOCK_DGRAMor SOCK_RAW(您需要自己创建以太网标头)。

我找不到以太网协议的正确标头。您需要在标头中搜索ETH_*定义并找到正确的以太网标头