Can anybody correct this code that is used to get/set ARP entries and uses ioctl( )

Discussion in 'Linux Networking' started by jeniffer, Apr 25, 2006.

  1. jeniffer

    jeniffer Guest

    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=o;
    printf("\n");
    for(i=0;i<6;i++)
    printf("%x ",n);
    printf("\n");
    return (0);
    }
     
    jeniffer, Apr 25, 2006
    #1
    1. Advertisements

  2. Your code is just loaded with problems. It does not use the
    facilities of ANSI/ISO Standard C, which suggests it dates back
    prior to perhaps 1990 or so.

    Instead of using the example you are, look up the code for /arp/
    from any current Linux distribution. You can, for example,
    download net-tools-1.60.tar.bz2 from ftp.oss.cc.gatech.edu.
    You'll find it on that server at,

    /pub/linux/distributions/slackware/slackware-10.2/source/n/tcpip/net-tools-1.60.tar.bz2

    And turn your compiler warnings up as high as you can. The
    least you would want is a command line like this:

    gcc -W -Wall -O2 -o foo foo.c

    There are actually several other warnings that can also be enabled
    most of the time. The point is to let the compiler help you write
    better code. For example, I test short programs with a "generic"
    Makefile that uses this command to compile:

    gcc -ggdb -O2 -std=c99 -pedantic -Wall -W -Wcast-align \
    -Wcast-qual -Wmissing-prototypes -Wshadow \
    -Wnested-externs -Wstrict-prototypes -Waggregate-return \
    -Wpointer-arith -c foo.c
     
    Floyd L. Davidson, Apr 25, 2006
    #2
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.