Re: ioctl SIOCGARP question

From: Guillaume Morin (guillaume@morinfr.org)
Date: Sun Jan 20 2002 - 05:45:20 EST


Dans un message du 20 jan à 3:28, Bernd Eckenfels écrivait :
>
> In article <20020119192045.GA25668@morinfr.org> you wrote:
> > memset(&a,0,sizeof(a));
> > strcpy(a.arp_dev,INTERFACE);
> > sin = (struct sockaddr_in *) &(a.arp_pa);
> > sin->sin_family = AF_INET;
>
> You have to set the flags to ATF_PUB or ATF_DONTPUB.

I've modified this :
 
strcpy(a.arp_dev,INTERFACE);
sin = (struct sockaddr_in *) &(a.arp_pa);
sin->sin_family = AF_INET;
a.arp_flags = ATF_PUBL;

I still get EINVAL.

Your remark is weird, because in net/ipv4/arp.c arp_ioctl()

if (!(r.arp_flags & ATF_PUBL) &&
     (r.arp_flags & (ATF_NETMASK|ATF_DONTPUB)))
         return -EINVAL;

This condition should be false if arp_flags == 0

BTW, the other situation which returns EINVAL should not happen here:

 if (!r.arp_ha.sa_family)
      r.arp_ha.sa_family = dev->type;
 err = -EINVAL;
 if ((r.arp_flags & ATF_COM) && r.arp_ha.sa_family != dev->type)
      goto out;

Indeed the memset sets arp_ha.sa_family to 0.

Any other ideas ? I am really puzzled ...

For reference, here is the complete program

#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if_arp.h>
#include <stdio.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <string.h>

#define IP "62.4.22.236"
#define INTERFACE "eth1"

int main(int argc, char ** argv) {
        int s;
        struct arpreq a;
        struct sockaddr_in * sin;
        struct in_addr addr;
        if ((s = socket(AF_INET,SOCK_DGRAM,0) == -1)) {
                perror("socket");
                return -1;
        }
        memset(&a,0,sizeof(a));
        strcpy(a.arp_dev,INTERFACE);
        sin = (struct sockaddr_in *) &(a.arp_pa);
        sin->sin_family = AF_INET;
        a.arp_flags = ATF_PUBL;
        if (! inet_aton(IP,&addr)) {
                puts("Cannot convert " IP ".");
                return -1;
        }

        memcpy(&sin->sin_addr,&addr,sizeof(struct in_addr));
        if (ioctl(s,SIOCGARP,&a)) {
                perror("ioctl");
                return -1;
        }

        printf("HWADDR: %x\n",*a.arp_ha.sa_data);
        return 0;
}

/* EOF */

TIA.

-- 
Guillaume Morin <guillaume@morinfr.org>

If it doesn't work, force it. If it breaks, it needed replacing anyway. - To unsubscribe from this list: send the line "unsubscribe linux-net" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html



This archive was generated by hypermail 2b29 : Wed Jan 23 2002 - 21:01:13 EST