Code example to get ARP cache entry
USAGE:
- Call this function several times, with a slight delay between attempts (e.g., 1 second). Be sure to give up after an excessive number of failed attempts (e.g., 20 attempts), just in case the device never responds to ARPs.
- If no ARP cache entry exists, the function will return an error; but the stack should (transparently) generate an associated ARP Request.
- If needed, I can provide a code example for the calling sequence as well.
- NOTE: I am having a minor issue with this code implementation; but generally it works OK (see LinuxQuestion #2126715 from me, w6nct).
int getMac(char *dev, unsigned long ip, unsigned char *mac)
{
struct sockaddr addr;
struct arpreq myreq;
int sockfd, i;
// default Mac to zero, in case we return an error
for (i = 0; i < 6; i++) {
mac[i] = 0;
}
memset(&addr, '\0', sizeof(addr));
addr.sa_family = AF_INET;
memcpy(&addr.sa_data[2], &ip, 4);
memset(&myreq, '\0', sizeof(myreq));
memcpy(&myreq.arp_pa, &addr, sizeof(addr));
memcpy(&myreq.arp_dev, dev, sizeof(myreq.arp_dev));
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
printf("getMac: error from socket call (%s, 0x%08X)", dev, ip);
return (-1);
}
// try to get an ARP mapping (if available)
if (ioctl(sockfd, SIOCGARP, (char *) &myreq) < 0) {
printf("getMac: error from ioctl call (%s, 0x%08X)", dev, ip);
close(sockfd);
return (-1);
}
for (i = 0; i < 6; i++)
mac[i] = myreq.arp_ha.sa_data[i];
printf("getMac: %s, 0x%08X, %02X:%02X:%02X:%02X:%02X:%02X",
dev, ip, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
close(sockfd);
return 0;
}
<<< EOM >>>
Last edited by w6nct; 04-03-2006 at 11:30 AM.
|