|
《UNP》卷一第三版 ARP高速缓存操作
在这一节里有一程序是为了展示读取ARP 高速缓存的SIOCGARP的ioctl的调用方法,但是例子在debian5 下不能成功运行,我把源程序贴一下:
<code>
#include "unpifi.h"
#include <net/if_arp.h>
int
main(int argc, char ** argv)
{
int sockfd;
struct ifi_info *ifi;
unsigned char *ptr;
struct arpreq arpreq;
struct sockaddr_in *sin;
sockfd = Socket(AF_INET, SOCK_DGRAM, 0);
for (ifi = get_ifi_info(AF_INET, 0); ifi != NULL; ifi = ifi->ifi_next) {
printf("%s: ", Sock_ntop(ifi->ifi_addr, sizeof(struct sockaddr_in)));
sin = (struct sockaddr_in *) &arpreq.arp_pa;
memcpy(sin, ifi->ifi_addr, sizeof(struct sockaddr_in));
if (ioctl(sockfd, SIOCGARP, &arpreq) <0) {
err_ret("ioctl SIOCGARP");
continue;
}
ptr = &arpreq.arp_ha.sa_data[0];
printf("%x:%x:%x:%x:%x:%x\n", *ptr, *(ptr + 1), *(ptr +2), *(ptr + 3), *(ptr + 4), *(ptr + 5));
}
exit(0);
}
</code>
这个程序使用了get_ifi_info()这个函数,它返回的是本机的一些接口列表。运行这个程序会出现:ioctl SIOCGAR: No such device。运行不出想要的结果,我参照别人的一个程序写的一个例子,为了给和我一样的菜鸟一些帮助,代码如下:
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/if_ether.h>
/* This function is need the interface name and the on the interface's ip address */
int
get_arp_entry(char *ip, char *eth_name)
{
int sockfd;
struct arpreq arpreq;
struct sockaddr_in *sin;
unsigned char *hw_addr;
int rc;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 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);
/* you must add this because some system will return "Invlid argumetn" because some argument isn't zero */
memset(&arpreq, 0, sizeof(struct arpreq));
sin = (struct sockaddr_in *) &arpreq.arp_pa;
memset(sin, 0, sizeof(struct sockaddr_in));
sin->sin_family = AF_INET;
inet_pton(AF_INET, ip, &sin->sin_addr);
strcpy(arpreq.arp_dev, eth_name);
rc = ioctl(sockfd, SIOCGARP, &arpreq);
if (rc < 0) {
perror("Entry not available in cache...\n");
} else {
printf("\nentry has been successfuly retreived\n");
hw_addr = (unsigned char *) arpreq.arp_ha.sa_data;
printf("HWAddr found: %02x:%02x:%02x:%02x:%02x:%02x\n",
hw_addr[0], hw_addr[1], hw_addr[2], hw_addr[3], hw_addr[4], hw_addr[5]);
}
return 0;
}
int main(int argc, char ** argv)
{
char *ip;
char *eth_name;
if (argc != 3){
perror("usage:get_arp_entry <ip> <eth_name>");
exit(1);
}
if (argv[1] != NULL){
ip = malloc(sizeof(argv[1]));
strcpy(ip, argv[1]);
} else {
perror("invalid argument");
exit(1);
}
if (argv[2] != NULL) {
eth_name = malloc(sizeof(argv[2]));
strcpy(eth_name, argv[2]);
} else {
perror("invalid argument");
exit(1);
}
get_arp_entry(ip, eth_name);
return 0;
}
运行的时候我们不输入本机的IP 而输入在本接口 网络内的其它IP地址,例如我的网络我的IP:10.1.6.205,我的网关是:10.1.6.206, 输入的时候我输 get_arp_entry 10.1.6.206 eth0 |
|