Hello everybody,
I have a working code that displays an entry from a given IP address. but, how can i display the entire ARP table? like the option 'arp -a' of the standard linux program.
This is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <net/if.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
char *mac_ntoa(unsigned char *ptr){
static char address[30];
sprintf(address, "%02X:%02X:%02X:%02X:%02X:%02X",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
return(address);
}
int main(int argc, char* argv[]){
int s;
struct arpreq req;
struct hostent *hp;
struct sockaddr_in *sin;
char *host = argv[1];
bzero((caddr_t)&req, sizeof(req));
sin = (struct sockaddr_in *)&req.arp_pa;
sin->sin_family = AF_INET; /* Address Family: Internet */
sin->sin_addr.s_addr = inet_addr(host);
if(sin->sin_addr.s_addr ==-1){
if(!(hp = gethostbyname(host))){
fprintf(stderr, "arp: %s ", host);
herror((char *)NULL);
return(-1);
}
bcopy((char *)hp->h_addr, (char *)&sin->sin_addr, sizeof(sin->sin_addr));
}
if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
perror("socket() failed.");
exit(-1);
} /* Socket is opened.*/
strcpy(req.arp_dev, "eth0");
if(ioctl(s, SIOCGARP, (caddr_t)&req) <0){
if(errno == ENXIO){
printf("%s (%s) -- no entry.\n", host, inet_ntoa(sin->sin_addr));
exit(-1);
} else {
perror("SIOCGARP");
exit(-1);
}
}
close(s); /* Close the socket, we don't need it anymore. */
printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
if(req.arp_flags & ATF_COM){
printf("%s ", mac_ntoa(req.arp_ha.sa_data));
} else {
printf("incomplete");
}
if(req.arp_flags & ATF_PERM){
printf("ATF_PERM");
}
if(req.arp_flags & ATF_PUBL){
printf("ATF_PUBL");
}
if(req.arp_flags & ATF_USETRAILERS){
printf("ATF_USETRAILERS");
}
printf("\n");
return(0);
}
I've looked to /usr/src/linux/net/ipv4/arp.c code before posting and can't find anything that tells me how to do it.
Thanks in advance.