Winapi: send arp response
I am new to Winapi and am currently trying to send arp packets using raw sockets. Here is my code:
#include "winsock2.h"
#include "windows.h"
#include "time.h"
#include "stdio.h"
#include "ws2tcpip.h"
#include "conio.h"
#define ETH_HW_ADDR_LEN 6
#define IP_ADDR_LEN 4
#define ARP_FRAME_TYPE 0x0806
#define ETHER_HW_TYPE 1
#define IP_PROTO_TYPE 0x0800
#define OP_ARP_REPLY 2
struct arp_packet {
u_short hw_type; // Hardware type (HTYPE)
u_short prot_type; // Protocol type (PTYPE)
u_char hw_addr_size; // Hardware length (HLEN)
u_char prot_addr_size; // Protocol length (PLEN)
u_short op; // Operation
u_char sndr_hw_addr[ETH_HW_ADDR_LEN]; // Sender hardware address (SHA)
u_char sndr_ip_addr[IP_ADDR_LEN]; // Sender protocol address (SPA)
u_char rcpt_hw_addr[ETH_HW_ADDR_LEN]; // Target hardware address (THA)
u_char rcpt_ip_addr[IP_ADDR_LEN]; // Target protocol address (TPA)
};
void get_ip_addr( struct in_addr* in_addr, char* str ){
struct hostent *hostp;
in_addr->s_addr = inet_addr(str);
if ( in_addr->s_addr == -1 ){
if( (hostp = gethostbyname(str)))
{memcpy (in_addr, hostp->h_addr, hostp->h_length);}
else {
fprintf( stderr, "send_arp: unknown host [%s].\n", str ) ;
exit(1);
}
}
} ; // get_ip_addr
int main()
{
struct in_addr src_in_addr, targ_in_addr;
struct arp_packet pkt;
char *sender_mac = "AA-AA-AA-AA-AA-AA";
char *receiver_mac = "88-9F-FA-6E-64-3Q";
SOCKET s;
int optval;
hostent *server;
WSADATA wsock;
if (WSAStartup(MAKEWORD(2,2),&wsock) != 0)
{
fprintf(stderr,"WSAStartup() failed");
exit(EXIT_FAILURE);
}
printf("Initialised successfully.\n");
if((s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==SOCKET_ERROR)
{
printf("Creation of raw socket failed %d\n.", WSAGetLastError());
return 0;
}
printf("Raw TCP Socket Created successfully.\n");
if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&optval, sizeof(optval))==SOCKET_ERROR)
{
printf("failed to set socket in raw mode %d\n.", WSAGetLastError());
return 0;
}
printf("Successful.\n");
pkt.hw_type = htons(ETHER_HW_TYPE);
pkt.prot_type = htons(IP_PROTO_TYPE);
pkt.hw_addr_size = ETH_HW_ADDR_LEN;
pkt.prot_addr_size = IP_ADDR_LEN;
pkt.op = htons(OP_ARP_REPLY);
strcpy((char *)pkt.sndr_hw_addr, sender_mac);
strcpy((char *)pkt.rcpt_hw_addr, receiver_mac);
get_ip_addr( &src_in_addr, "192.168.1.53");
get_ip_addr( &targ_in_addr, "192.168.1.113");
memcpy( pkt.sndr_ip_addr, &src_in_addr, IP_ADDR_LEN);
memcpy( pkt.rcpt_ip_addr, &targ_in_addr, IP_ADDR_LEN);
if((sendto(s , (const char* )&pkt , sizeof(pkt), 0, 0, 0))==SOCKET_ERROR)
{
printf("Error sending Packet : %d\n", WSAGetLastError());
}
return 0;
}
Since this is for educational purposes only, I hardcoded the MAC address and IP addresses. As you can see, I am trying to send an ARP response to some ip address.
I am using cygwin
to compile and the output is
$ ./test.exe
Initialised successfully.
Raw TCP Socket Created successfully.
Successful.
Error sending Packet : 10057
I have searched and 10057
means Socket is not connected.
But I dont know why I am getting this error. Then I decided to change the function sendto
to this:
SOCKADDR_IN dest;
if((sendto(s , (const char* )&pkt , sizeof(pkt), 0, (SOCKADDR *)&dest, sizeof(dest)))==SOCKET_ERROR)
to see what would happen, I still had the error, but it was different 10047
. This means Address family not supported by protocol family.
But in the msdn documentation I saw that This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified
I am using Windows 7. Thanks.
source to share
No one has answered this question yet
Check out similar questions: