"Destination address required" 尝试通过 SOCK_RAW 套接字发送数据时

"Destination address required" when attempting to send data over a SOCK_RAW socket

我正在尝试发送数据包(不是 ip 数据包,而是 EAP 请求标识),但是 send() 函数返回 -1。

    int sockfd = socket(AF_INET, SOCK_RAW, 0);
printf("socket: %d\n", sockfd);
struct sockaddr_in sock;
printf("creating packet\n");
char packet[27];
memcpy(packet + 0, (u_char* ) ethernet->ether_dhost, 6);
memcpy(packet + 6, (u_char* ) ethernet->ether_shost, 6);
memcpy(packet + 12, (u_char* ) ethernet + 12, 2);
memcpy(packet + 14, (u_char *)reqid, 1);
memcpy(packet + 15, (u_char *)reqid+1, 1);
memcpy(packet + 16, (u_char *)reqid+2, 4);
memcpy(packet + 20, (u_char *)reqid+6, 1);
memcpy(packet + 21, (u_char *)reqid+7, 1);
memcpy(packet + 22, (u_char *)reqid+8, 4);
memcpy(packet + 26, (u_char *)reqid+12, 1);
printf("sending packet\n");
if(send(sockfd, packet, sizeof(packet), 0) == -1)
{
     printf("packet not sent\n");
     //return;
}

数据包由以太网数据包和请求标识组成。 我知道数据包很好,每个值都在正确的位置。但是 send() 函数失败了。
errno show "Destination address required" 并且 sockfd 值为 4。 顺便说一句,这是在 FreeBSD 上。
谢谢 编辑: 我没有目的地的 IP 地址。我只有它的 MAC 地址。

来自联机帮助页:

The send() call may be used only when the socket is in a connected state (so that the intended recipient is known).

我相信你想要 sendto,而不是 send

使用原始套接字时,您无需指定以太网地址。原始套接字允许您创建 IP 数据报,您可以在其中仅发送有效负载,网络堆栈将配置 IP header 或者如果 IP_HDRINCL 套接字选项是,您也可以指定 IP header启用。您不能在此处指定以太网地址。阅读:http://man7.org/linux/man-pages/man7/raw.7.html

如果您没有IP地址而只有以太网地址,这是您需要通过不同方式解决的另一个问题。

首先,您需要使用数据包套接字http://man7.org/linux/man-pages/man7/packet.7.html并将以太网帧发送到另一个节点。

问题是另一个节点会将那个帧传递给上层(设备driver会这样做)。在那里,如果上层没有看到它的 IP 地址,它将丢弃消息。因此,您可能希望发送 RARP 消息并期望其他节点响应您并传递其 IP 地址。另一种可能性是您实现自己的第 2 层协议 ...

在这些答案和进一步的阅读之后,我认为没有办法在 FreeBSD 中使用套接字来达到我的目的。
所以现在我为此使用 libpcap。使用 pcap_sendPacket() 我可以发送带有以太网地址的数据包。
感谢您的帮助