This is a C program compiled on gcc compiler that tries to set a new
entry in the arp cache,get an entry and also delete an entry from it.I
have run this program but in the set function Set_Entry function a call
to ether_aton(a, n) is made but the value of sa_data is not being
updated.This is why I think tht i am getting the error of invalid
argument in ioctl func..Plzz help me out.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <sys/ioctl.h>
#if __GLIBC__ >= 2 && __GLIBC_MINOR >= 1
#include <netpacket/packet.h>
#include <net/ethernet.h>
#else
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#endif
int main()
{
int i=Set_Entry();
return 0;
}
/*
void Del_Entry()
{
int sd;
struct arpreq arpreq;
struct sockaddr_in *sin;
struct in_addr ina;
char ip[] = "172.26.29.98";
unsigned char hw_addr[]="0:a:f4:36:12:e1";
int rc;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0)
{
perror("socket() error\n");
exit(1);
}
sin = (struct sockaddr_in *) &arpreq.arp_pa;
memset(sin, 0, sizeof(struct sockaddr_in));
sin->sin_family = AF_INET;
ina.s_addr = inet_addr(ip);
memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr));
strcpy(arpreq.arp_dev, "eth0");
/*
sin_h = (struct sockaddr_in *) &arpreq.arp_ha;
memset(sin_h, 0, sizeof(struct sockaddr_in));
sin_h->sin_family =AF_INET;
ina_h.s_addr = inet_addr(ip);
memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr));*/
//arpreq.arp_flags=ATF_PERM;
//arpreq.arp_ha.sa_family=AF_INET;
/*rc = ioctl(sd, SIOCSARP, &arpreq);
if (rc < 0)
{
perror("Entry not available in cache...\n");
}
else
{
printf("\nentry has been successfully retreiveed");
hw_addr = (unsigned char *) arpreq.arp_ha.sa_data;
printf("HWAddr found : %x:%x:%x:%x:%x:%x\n", hw_addr[0],
hw_addr[1], hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
}
}
*/
int Set_Entry()
{
int sd;
struct arpreq arpreq;
struct sockaddr_in *sin;
struct in_addr ina;
char ip[] = "172.26.28.77";
char eaddr[]="0:14:22:42:48:e6";//00-14-22-42-48-E6
int rc;
u_char *ea;
sd = socket(AF_INET,SOCK_DGRAM,0);
if (sd < 0)
{
perror("socket() error\n");
exit(1);
}
sin = (struct sockaddr_in *) &arpreq.arp_pa;
memset(sin, 0, sizeof(struct sockaddr_in));
sin->sin_family=AF_INET;
ina.s_addr = inet_addr(ip);
memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr));
ea =(char*)arpreq.arp_ha.sa_data;
if(ether_aton(eaddr, ea))
{
printf("\nreturning 1");
return (1);
}
printf("ea = %s",ea);
arpreq.arp_flags=ATF_PERM;
strcpy(arpreq.arp_dev, "eth0");
printf("sa_data = %s",arpreq.arp_ha.sa_data);
rc = ioctl(sd, SIOCSARP, &arpreq);
if (rc < 0)
{
perror("Entry not set...\n");
}
else
{
printf("\nentry has been successfully set");
}
return 0;
}
int Get_Entry()
{
int sd;
struct arpreq arpreq;
struct sockaddr_in *sin;
struct in_addr ina;
char ip[] = "172.26.28.77";
unsigned char *hw_addr;
int rc;
sd = socket(AF_INET, SOCK_DGRAM, 0);
if (sd < 0)
{
perror("socket() error\n");
exit(1);
}
/* Try to find an entry in arp cache for the ip address specified */
printf("Find arp entry for IP : %s\n", ip);
sin = (struct sockaddr_in *) &arpreq.arp_pa;
memset(sin, 0, sizeof(struct sockaddr_in));
sin->sin_family = AF_INET;
ina.s_addr = inet_addr(ip);
memcpy(&sin->sin_addr, (char *)&ina, sizeof(struct in_addr));
strcpy(arpreq.arp_dev, "eth0");
arpreq.arp_ha.sa_family = AF_UNSPEC;
rc = ioctl(sd, SIOCGARP, &arpreq);
if (rc < 0)
{
perror("Entry not available in cache...\n");
}
else
{
printf("\nentry has been successfully retreived");
hw_addr = (unsigned char *) arpreq.arp_ha.sa_data;
printf("HWAddr found : %x:%x:%x:%x:%x:%x\n", hw_addr[0], hw_addr[1],
hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
}
return 0;
}
ether_aton(a, n)
char *a;
char *n;
{
int i, o[6];
i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o[0], &o[1], &o[2],
&o[3], &o[4], &o[5]);
printf("\n i=%d\n",i);
printf("%x %x %x %x %x %x",o[0],o[1],o[2],o[3],o[4],o[5]);
if (i != 6) {
perror("arp: invalid Ethernet address");
return (1);
}
for (i=0; i<6; i++)
n[i]=o[i];
printf("\n");
for(i=0;i<6;i++)
printf("%x ",n[i]);
printf("\n");
return (0);
}