/*
* Copyright (c) 1998 JSC Rinet, Novosibirsk, Russia
*
* Redistribution and use in source forms, with and without modification,
* are permitted provided that this entire comment appears intact.
* Redistribution in binary form may occur without any restrictions.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' WITHOUT ANY WARRANTIES OF ANY KIND.
*/
/* getarptab.c -- translate MAC addresses to IP addresses using ARP table */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_RTF_LLINFO /* BSD systems */
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#ifdef ETHER_ADDR_LEN
#define MAC_ADDR_LEN ETHER_ADDR_LEN
#else
#define MAC_ADDR_LEN 6
#endif
u_char *
getarptab(ep)
u_char *ep;
{
int mib[6];
size_t needed;
char *lim, *buf, *next;
struct rt_msghdr *rtm;
static 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)
error(1, "getarptab: sysctl");
if ((buf = (char *)malloc(needed)) == NULL)
error(1, "getarptab: malloc");
if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
error(1, "getarptab: sysctl");
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (sdl->sdl_alen &&
!memcmp(ep, (u_char *)LLADDR(sdl), MAC_ADDR_LEN)) {
free(buf);
return ((u_char *)&sin->sin_addr);
}
}
free(buf);
return (u_char *)0;
}
#elif HAVE_PROC_NET_ARP /* Linux systems */
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
u_char *
getarptab(ep)
u_char *ep;
{
FILE *fp;
char *req, *ip, *mac, buf[100];
static struct in_addr addr;
if ((fp = fopen("/proc/net/arp", "r")) != NULL) {
req = (char *)entoa(ep);
while (fgets(buf, sizeof(buf), fp) != NULL) {
buf[sizeof(buf)-1] = '\0';
if ((ip = strtok(buf, " \t")) == NULL)
continue;
while ((mac = strtok(NULL, " \t")) != NULL) {
if (!strcasecmp(req, mac)) {
if (inet_aton(ip, &addr)) {
(void) fclose(fp);
return ((u_char *)&addr);
}
break;
}
}
}
(void) fclose(fp);
}
return (u_char *)0;
}
#else /* XXX. Get ARP table not implemented yet for SYSV systems */
u_char *
getarptab(ep)
u_char *ep;
{
return (u_char *)0;
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1