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.

+3


source to share





All Articles