当试图通过SOCK_RAW套接字发送数据时,需要“目标地址”。

时间:2022-06-23 12:58:57

I am trying to send a packet (not an ip packet, but an EAP-request identity), but the send() function is returning -1.

我尝试发送一个包(不是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;
}

The packet consists of an ethernet packet, and a request identity. I know the packet is fine and every value is at the right place. but the send() function fails.
errno show "Destination address required" and the sockfd value is 4. This is on FreeBSD by the way.
Thanks EDIT: I don't have the IP address of the destination. I only have its MAC address.

包由一个以太网包和一个请求标识组成。我知道这个包很好,每个值都在正确的地方。但是send()函数失败。errno显示“所需的目的地地址”,sockfd值为4。顺便说一下,这是关于FreeBSD的。感谢编辑:我没有目的地的IP地址。我只有它的MAC地址。

3 个解决方案

#1


1  

From the manpage:

从:

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

send()调用只能在套接字处于连接状态时才使用(因此,已知的接收者是已知的)。

I believe you want sendto, not send.

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

#2


1  

When using raw sockets you don't specify the Ethernet address. Raw sockets let you create IP datagrams in which you can send just the payload and the network stack will configure the IP header or you can also specify the IP header if the IP_HDRINCL socket option is enabled. Here you cannot specify an Ethernet address. Read: http://man7.org/linux/man-pages/man7/raw.7.html

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

If you don't have the IP address and only have the Ethernet address, this is another problem that you need to solve in different ways.

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

First, you will need to use Packet sockets http://man7.org/linux/man-pages/man7/packet.7.html and send an Ethernet frame to the other node.

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

The problem is that the other node will pass that frame to the upper layer (the device driver will do this). There, if the upper layer doesn't see its IP address it will drop the message. So you may want to send a RARP message and expect the other node responds you passing its IP address. Other possibility is that you implement your own layer 2 protocol ...

问题是,其他节点将把该框架传递到上层(设备驱动程序将执行此操作)。在那里,如果上层没有看到它的IP地址,它将删除消息。因此,您可能希望发送一个RARP消息,并期望其他节点响应您传递其IP地址。还有一种可能是,您实现了自己的第二层协议……

#3


0  

After these answers and further readings, i figured that there is no way to use socket in FreeBSD for my purpose.
So now I'm using libpcap for this. Using the pcap_sendPacket() I can send packets with the ethernet address.
Thanks for your helps

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

#1


1  

From the manpage:

从:

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

send()调用只能在套接字处于连接状态时才使用(因此,已知的接收者是已知的)。

I believe you want sendto, not send.

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

#2


1  

When using raw sockets you don't specify the Ethernet address. Raw sockets let you create IP datagrams in which you can send just the payload and the network stack will configure the IP header or you can also specify the IP header if the IP_HDRINCL socket option is enabled. Here you cannot specify an Ethernet address. Read: http://man7.org/linux/man-pages/man7/raw.7.html

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

If you don't have the IP address and only have the Ethernet address, this is another problem that you need to solve in different ways.

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

First, you will need to use Packet sockets http://man7.org/linux/man-pages/man7/packet.7.html and send an Ethernet frame to the other node.

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

The problem is that the other node will pass that frame to the upper layer (the device driver will do this). There, if the upper layer doesn't see its IP address it will drop the message. So you may want to send a RARP message and expect the other node responds you passing its IP address. Other possibility is that you implement your own layer 2 protocol ...

问题是,其他节点将把该框架传递到上层(设备驱动程序将执行此操作)。在那里,如果上层没有看到它的IP地址,它将删除消息。因此,您可能希望发送一个RARP消息,并期望其他节点响应您传递其IP地址。还有一种可能是,您实现了自己的第二层协议……

#3


0  

After these answers and further readings, i figured that there is no way to use socket in FreeBSD for my purpose.
So now I'm using libpcap for this. Using the pcap_sendPacket() I can send packets with the ethernet address.
Thanks for your helps

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