Search code examples
cwindowssocketsarp

Send Raw arp reply packet in windows


I am currently learning how to use the windows raw sockets.

I created a raw arp reply frame(includes all headers (ethernet+arp headers)), and when I send it using sendto function, It fails and return SOCKET_ERROR with error code 10047.

The parameters I used to create the socket are as follows:

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

and also I changed the socket options as follows:

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

(By the way, '2' is equal to IP_HDRINCL, for some reason, visual studio didn't recognize it..)

I try to send the packet as follows:

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

Where Arp_Frame is a struct that includes ethernet header+arp header+18 Bytes for padding.

After this call I get that SentBytesCount is equal to SOCKET_ERROR(-1), and no packet is sent.

Thank you for your help!


Solution

  • Winsock error 10047 is 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.

    You created an AF_INET (IPv4) socket, but you are not passing sendto() a valid sockaddr_in containing an IPv4 address and port, hence the error. You are passing it an empty socketaddr (what is that?) instead.

    Any sockaddr_... struct you use with a socket must match what the socket's address family expects, as set by the socket() call (in your case, AF_INET, which uses sockaddr_in addresses).

    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));
    

    As for IP_HDRINCL, it is defined in ws2tcpip.h.