Subject: Gratuitous ARP

From: "Rajnish Madan" <[email-masked]>
Date: Sat, 2 Dec 2000 19:35:07 +0530

Hi All,

I am trying to send a Gratuitous ARP on NetBSD 1.4.1, but facing some problems.
While capturing the packet using tcpdump i am receiving the packet as the 
arp-whohas HOSTA tell HOSTB, instead of HOSTA tell HOSTA.

I checked up the fields of the ethernet frame but it seems to be correct.
Even if  memset the buffer to 0 and send the buffer using RAW socket
same behaviour is happening. The HOSTA showed by tcpdump resides in my
subnet (!!!!). I am attaching the part of my program which does this work.

The tcpdump shows the message only if i run my program, i checked this up and
it seems somewhere something wrong is happening which i am unable to figure out??

Pls suggest/guide in this regard.
Thanks in advance 
Rajnish

#define BUFLEN sizeof(struct ether_arp) + sizeof(struct ether_header)
int send_grat_arp(char *buff, int buffLen)
{
    struct sockaddr from;
    int len;
    int sockFd = -1;
    char ifName[6];
    int cnt = -1;
    u_int8_t eth_shost[6];
    u_int8_t eth_dhost[6];
    struct in_addr ip_shost, ip_dhost;

    char buf[BUFLEN];
    struct ether_header *packethdr = (struct ether_header *) buf;
    struct ether_arp *packet = (struct ether_arp *) (packethdr + 1);
    struct sockaddr dst;

    ip_shost.s_addr = inet_addr("157.227.12.105");
    ip_dhost.s_addr = inet_addr("157.227.12.105");
   eth_dhost[0]=0xFF;
    eth_dhost[1]=0xFF;
    eth_dhost[2]=0xFF;
    eth_dhost[3]=0xFF;
    eth_dhost[4]=0xFF;
    eth_dhost[5]=0xFF;

    eth_shost[0]=0x00;
    eth_shost[1]=0x10;
    eth_shost[2]=0x5a;
    eth_shost[3]=0xa9;
    eth_shost[4]=0x17;
    eth_shost[5]=0xa5;
    bzero(buf, BUFLEN);
    memcpy(&(packethdr->ether_dhost), eth_dhost, 6);
    memcpy(&(packethdr->ether_shost), eth_shost, 6);
    packethdr->ether_type = htons(ETHERTYPE_ARP);
    packet->arp_hrd = htons(ARPHRD_ETHER);
    packet->arp_pro = htons(0x0800);
    packet->arp_hln = 6;
    packet->arp_pln = 4;

   packet->arp_op = htons(ARPOP_REQUEST);
    memcpy(&(packet->arp_sha), eth_shost, 6);
    memcpy(&(packet->arp_tha), eth_dhost, 6);
    *((struct in_addr *) (&(packet->arp_spa))) = ip_shost;
    *((struct in_addr *) (&(packet->arp_tpa))) = ip_dhost;
    memset((char *)&from, 0, sizeof(from));
    memset(ifName, '\0', 6);

    /* Again No Idea why we are setting the Interface Name here */
    strcpy(from.sa_data, "ex0");

    /* Setting the Family as AF_INET not sure why...???*/
    from.sa_family = AF_INET;

       sockFd = socket(PF_INET, SOCK_RAW, htons(0x0806));

if (sockFd < 0)
    {
        printf("Error in Opening the RAW Socket %d\n", errno);
        return -1;
    }

    /* print the Buffer to see all the fileds are correct ..*/

    /* send the G-ARP */
    len = sendto(sockFd, buf, sizeof(buf), 0, (struct sockaddr *)&from, sizeof(f
rom));

    printf("Errno Set is %d\n", errno);
    close (sockFd);
    return len;
}

---

From: "Danny J. Mitzel" <[email-masked]>
Date: Mon, 04 Dec 2000 15:03:20 -0800

>> arp-whohas HOSTA tell HOSTB, instead of HOSTA tell HOSTA.

'whohas' would appear to be ARP request while 'tell' is

>>    packet->arp_op = htons(ARPOP_REQUEST);

so to get tcpdump output with 'tell' try changing op to reply(2).

---

From: "Rajnish Madan" <[email-masked]>
Date: Tue, 5 Dec 2000 10:09:09 +0530

Hi Danny,

I tried the modifications as u suggested. But i'am getting the following
output in from tcpdump

"09:51:41.493636 0:10:5a:a9:17:a5 Broadcast arp 42: arp who-has 157.227.2.96
tell dynarc."

I had checked up and found out that 157.227.2.96 is the default router set
on the NetBSD.
I also removed the entry from the routing table for the default route and
the program responded
with the error condition as NO default route specified.

I am bit confused as while sending the Gratutious ARP why its trying to get
the MAC address of
the default router.

When I specify the default route as 157.227.2.96 and send the buffer
following output is appeared
on the tcpdump.

"10:12:18.566947 0:10:5a:a9:17:a5 Broadcast arp 42: arp who-has 157.227.2.96
tell dynarc.
  10:12:18.567238 0:60:8:98:72:ff 0:10:5a:a9:17:a5 arp 60: arp reply
157.227.2.96 is-at 0:60:8:98:72:ff
  10:12:18.567263 0:10:5a:a9:17:a5 0:60:8:98:72:ff ip 76: dynarc. >
48.0.0.0: egp: [version 255]"

First two lines are for the arp-request and reply for the default router.
Not sure about the third output.
Hope this information will help you in figuring out where i am wrong.

Thanks in advance
Rajnish