在 windows 中发送原始 arp 回复数据包

Send Raw arp reply packet in windows

我目前正在学习如何使用 windows 原始套接字。

我创建了一个原始的 arp 回复帧(包括所有 headers(以太网+arp headers)),当我使用 sendto 函数发送它时, 它失败并且 return SOCKET_ERROR 错误代码 10047.

我用来创建socket的参数如下:

socket s = socket(AF_INET,SOCK_RAW,IPPROTO_RAW);

我还更改了套接字选项如下:

int on=1;
setsockopt(s,IPPROTO_IP, 2,(char*)&on,sizeof(on));

(对了,'2'等于IP_HDRINCL,不知为何,visual studio没认出来..)

我尝试按如下方式发送数据包:

socketaddr sa = { 0 };
int SentBytesCount = sendto(s, (char*)&arp_raw_msg,sizeof(Arp_Frame),0,&sa,sizeof(sa));

其中 Arp_Frame 是一个包含 ethernet header+arp header+18 字节用于填充的结构。

调用后我得到 SentBytesCount 等于 SOCKET_ERROR(-1),没有数据包被发送。

感谢您的帮助!

Winsock 错误 10047 是 WSAEAFNOSUPPORT:

Address family not supported by protocol family.

An address incompatible with the requested protocol was used. All sockets are created with an associated address family (that is, AF_INET for Internet Protocols) and a generic protocol type (that is, SOCK_STREAM). This error is returned if an incorrect protocol is explicitly requested in the socket call, or if an address of the wrong family is used for a socket, for example, in sendto.

您创建了一个 AF_INET (IPv4) 套接字,但您没有传递 sendto() 包含 IPv4 地址和端口的有效 sockaddr_in,因此出现错误。您传递给它的是一个空的 socketaddr(那是什么?)。

任何与套接字一起使用的 sockaddr_... 结构必须与套接字的地址族所期望的相匹配,正如 socket() 调用所设置的(在您的情况下,AF_INET,它使用 sockaddr_in 个地址)。

sockaddr_in sa;
memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET;
sa.sin_addr.s_addr = inet_addr("destination IP address");
sa.sin_port = htons(Destination port number);

int SentBytesCount = sendto(s, (char*)&arp_raw_msg, sizeof(Arp_Frame), 0, (struct sockaddr*)&sa, sizeof(sa));

至于IP_HDRINCL,定义在ws2tcpip.h.