从FreeBSD4.5的arp命令的源代码中获得,可以在macos10.6上编译,运行。
gcc -o arp -Wall arp.c
#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_types.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <nlist.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
void
ether_print(u_char * cp)
{
printf("%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
}
void
print_entry(struct sockaddr_dl * sdl, struct sockaddr_inarp * sin, struct rt_msghdr * rtm)
{
const char *host;
struct hostent *hp;
char ifname[IF_NAMESIZE];
hp = 0;
host = "?";
printf("%s (%s) at ", host, inet_ntoa(sin->sin_addr));
if (sdl->sdl_alen) {
ether_print((u_char *) LLADDR(sdl));
} else {
printf("(incomplete)");
}
if (if_indextoname(sdl->sdl_index, ifname) != NULL) {
printf(" on %s", ifname);
}
if (rtm->rtm_rmx.rmx_expire == 0) {
printf(" permanent");
}
if (sin->sin_other & SIN_PROXY) {
printf(" published (proxy only)");
}
if (rtm->rtm_addrs & RTA_NETMASK) {
sin = (struct sockaddr_inarp *) (ROUNDUP(sdl->sdl_len) + (char *) sdl);
if (sin->sin_addr.s_addr == 0xffffffff) {
printf(" published");
}
if (sin->sin_len != 8) {
printf("(weird)");
}
}
switch (sdl->sdl_type) {
case IFT_ETHER:
printf(" [ethernet]");
break;
case IFT_ISO88025:
printf(" [token-ring]");
break;
case IFT_L2VLAN:
printf(" [vlan]");
break;
}
printf("/n");
}
void
search(u_long addr, void (*action) (struct sockaddr_dl * sdl, struct sockaddr_inarp * sin, struct rt_msghdr * rtm))
{
int mib[6];
size_t needed;
char *lim, *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
errx(1, "route-sysctl-estimate");
}
if ((buf = malloc(needed)) == NULL) {
errx(1, "malloc");
}
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
errx(1, "actual retrieval of routing table");
}
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *) next;
sin = (struct sockaddr_inarp *) (rtm + 1);
(char *) sdl = (char *) sin + ROUNDUP(sin->sin_len);
if (addr) {
if (addr != sin->sin_addr.s_addr) {
continue;
}
}
(*action) (sdl, sin, rtm);
}
free(buf);
}
int
main()
{
search(0, print_entry);
return 0;
}
显示arp缓存的程序
最新推荐文章于 2023-06-04 22:57:25 发布