Sync with latest KAME.

Obtained from:	KAME
This commit is contained in:
kris 2000-07-05 10:14:11 +00:00
parent 4f67f09225
commit c8251f31e2
8 changed files with 334 additions and 166 deletions

View File

@ -15,7 +15,7 @@
PROG= rtsold
SRCS= rtsold.c rtsol.c if.c probe.c dump.c
CFLAGS+=-DINET6
CFLAGS+=-DINET6 -DHAVE_GETIFADDRS
LDADD+= -lkvm
DPADD+= ${LIBKVM}

View File

@ -31,7 +31,9 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/icmp6.h>
@ -47,6 +49,7 @@ static FILE *fp;
extern struct ifinfo *iflist;
static void dump_interface_status __P((void));
static char *sec2str __P((time_t));
char *ifstatstr[] = {"IDLE", "DELAY", "PROBE", "DOWN", "TENTATIVE"};

View File

@ -35,12 +35,23 @@
#include <sys/ioctl.h>
#include <net/if.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <net/if_var.h>
#endif /* __FreeBSD__ >= 3 */
#include <net/if_types.h>
#include <net/route.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#ifdef __FreeBSD__
# include <net/ethernet.h>
#endif
#ifdef __NetBSD__
#include <net/if_ether.h>
#endif
#if defined(__bsdi__) || defined(__OpenBSD__)
# include <netinet/in.h>
# include <netinet/if_ether.h>
#endif
#include <netinet/in.h>
#include <netinet/icmp6.h>
@ -53,25 +64,27 @@
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <kvm.h>
#include <nlist.h>
#include <limits.h>
#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
#endif
#include "rtsold.h"
extern int rssock;
static int ifsock;
static int getifa __P((char *name, struct in6_ifaddr *ifap));
static int get_llflag __P((const char *name));
#ifndef HAVE_GETIFADDRS
static unsigned int if_maxindex __P((void));
#endif
static void get_rtaddrs __P((int addrs, struct sockaddr *sa,
struct sockaddr **rti_info));
int
ifinit()
{
if ((ifsock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
return(-1);
}
ifsock = rssock;
return(0);
}
@ -80,7 +93,7 @@ int
interface_up(char *name)
{
struct ifreq ifr;
struct in6_ifaddr ifa;
int llflag;
strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
@ -100,24 +113,24 @@ interface_up(char *name)
warnmsg(LOG_DEBUG, __FUNCTION__, "checking if %s is ready...", name);
if (getifa(name, &ifa) < 0) {
llflag = get_llflag(name);
if (llflag < 0) {
warnmsg(LOG_WARNING, __FUNCTION__,
"getifa() failed, anyway I'll try");
"get_llflag() failed, anyway I'll try");
return 0;
}
if (!(ifa.ia6_flags & IN6_IFF_NOTREADY)) {
if (!(llflag & IN6_IFF_NOTREADY)) {
warnmsg(LOG_DEBUG, __FUNCTION__,
"%s is ready", name);
return(0);
}
else {
if (ifa.ia6_flags & IN6_IFF_TENTATIVE) {
} else {
if (llflag & IN6_IFF_TENTATIVE) {
warnmsg(LOG_DEBUG, __FUNCTION__, "%s is tentative",
name);
return IFS_TENTATIVE;
}
if (ifa.ia6_flags & IN6_IFF_DUPLICATED)
if (llflag & IN6_IFF_DUPLICATED)
warnmsg(LOG_DEBUG, __FUNCTION__, "%s is duplicated",
name);
return -1;
@ -258,6 +271,8 @@ if_nametosdl(char *name)
if ((sa = rti_info[RTAX_IFP]) != NULL) {
if (sa->sa_family == AF_LINK) {
sdl = (struct sockaddr_dl *)sa;
if (strlen(name) != sdl->sdl_nlen)
continue; /* not same len */
if (strncmp(&sdl->sdl_data[0],
name,
sdl->sdl_nlen) == 0) {
@ -297,86 +312,136 @@ getinet6sysctl(int code)
/*------------------------------------------------------------*/
static struct nlist nl[] = {
#define N_IFNET 0
{ "_ifnet" },
{ "" },
};
#define KREAD(x, y, z) { \
if (kvm_read(kvmd, (u_long)x, (void *)y, sizeof(z)) != sizeof(z)) { \
warnmsg(LOG_ERR, __FUNCTION__, "kvm_read failed"); \
goto bad; \
} \
}
/* get ia6_flags for link-local addr on if. returns -1 on error. */
static int
getifa(char *name, struct in6_ifaddr *ifap)
get_llflag(const char *name)
{
u_short index;
kvm_t *kvmd = NULL;
char buf[_POSIX2_LINE_MAX];
struct ifnet *ifp;
struct ifnet ifnet;
struct in6_ifaddr *ifa;
#ifdef HAVE_GETIFADDRS
struct ifaddrs *ifap, *ifa;
struct in6_ifreq ifr6;
struct sockaddr_in6 *sin6;
int s;
if (!ifap)
if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "socket(SOCK_DGRAM): %s",
strerror(errno));
exit(1);
index = (u_short)if_nametoindex(name);
if (index == 0) {
warnmsg(LOG_ERR, __FUNCTION__, "if_nametoindex failed for %s",
name);
goto bad;
}
if ((kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf)) == NULL) {
warnmsg(LOG_ERR, __FUNCTION__, "kvm_openfiles failed");
goto bad;
}
if (kvm_nlist(kvmd, nl) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "kvm_nlist failed");
goto bad;
}
if (nl[N_IFNET].n_value == 0) {
warnmsg(LOG_ERR, __FUNCTION__, "symbol \"%s\" not found",
nl[N_IFNET].n_name);
goto bad;
if (getifaddrs(&ifap) != 0) {
warnmsg(LOG_ERR, __FUNCTION__, "etifaddrs: %s",
strerror(errno));
exit(1);
}
KREAD(nl[N_IFNET].n_value, &ifp, struct ifnet *);
while (ifp) {
KREAD(ifp, &ifnet, struct ifnet);
if (ifnet.if_index == index)
break;
ifp = TAILQ_NEXT(&ifnet, if_link);
}
if (!ifp) {
warnmsg(LOG_ERR, __FUNCTION__, "interface \"%s\" not found",
name);
goto bad;
for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
if (strlen(ifa->ifa_name) != strlen(name)
|| strncmp(ifa->ifa_name, name, strlen(name)) != 0)
continue;
if (ifa->ifa_addr->sa_family != AF_INET6)
continue;
sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
continue;
memset(&ifr6, 0, sizeof(ifr6));
strcpy(ifr6.ifr_name, name);
memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len);
if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
warnmsg(LOG_ERR, __FUNCTION__,
"ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno));
exit(1);
}
ifa = (struct in6_ifaddr *)TAILQ_FIRST(&ifnet.if_addrhead);
while (ifa) {
KREAD(ifa, ifap, *ifap);
if (ifap->ia_addr.sin6_family == AF_INET6
&& IN6_IS_ADDR_LINKLOCAL(&ifap->ia_addr.sin6_addr)) {
kvm_close(kvmd);
return 0;
freeifaddrs(ifap);
close(s);
return ifr6.ifr_ifru.ifru_flags6;
}
ifa = (struct in6_ifaddr *)
TAILQ_NEXT((struct ifaddr *)ifap, ifa_link);
}
warnmsg(LOG_ERR, __FUNCTION__, "no IPv6 link-local address for %s",
name);
bad:
if (kvmd)
kvm_close(kvmd);
freeifaddrs(ifap);
close(s);
return -1;
#else
int s;
unsigned int maxif;
struct ifreq *iflist;
struct ifconf ifconf;
struct ifreq *ifr, *ifr_end;
struct sockaddr_in6 *sin6;
struct in6_ifreq ifr6;
maxif = if_maxindex() + 1;
iflist = (struct ifreq *)malloc(maxif * BUFSIZ); /* XXX */
if (iflist == NULL) {
warnmsg(LOG_ERR, __FUNCTION__, "not enough core");
exit(1);
}
if ((s = socket(PF_INET6, SOCK_DGRAM, 0)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "socket(SOCK_DGRAM): %s",
strerror(errno));
exit(1);
}
memset(&ifconf, 0, sizeof(ifconf));
ifconf.ifc_req = iflist;
ifconf.ifc_len = maxif * BUFSIZ; /* XXX */
if (ioctl(s, SIOCGIFCONF, &ifconf) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGIFCONF): %s",
strerror(errno));
exit(1);
}
/* Look for this interface in the list */
ifr_end = (struct ifreq *) (ifconf.ifc_buf + ifconf.ifc_len);
for (ifr = ifconf.ifc_req;
ifr < ifr_end;
ifr = (struct ifreq *) ((char *) &ifr->ifr_addr
+ ifr->ifr_addr.sa_len)) {
if (strlen(ifr->ifr_name) != strlen(name)
|| strncmp(ifr->ifr_name, name, strlen(name)) != 0)
continue;
if (ifr->ifr_addr.sa_family != AF_INET6)
continue;
sin6 = (struct sockaddr_in6 *)&ifr->ifr_addr;
if (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
continue;
memset(&ifr6, 0, sizeof(ifr6));
strcpy(ifr6.ifr_name, name);
memcpy(&ifr6.ifr_ifru.ifru_addr, sin6, sin6->sin6_len);
if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) < 0) {
warnmsg(LOG_ERR, __FUNCTION__,
"ioctl(SIOCGIFAFLAG_IN6): %s", strerror(errno));
exit(1);
}
free(iflist);
close(s);
return ifr6.ifr_ifru.ifru_flags6;
}
free(iflist);
close(s);
return -1;
#endif
}
#ifndef HAVE_GETIFADDRS
static unsigned int
if_maxindex()
{
struct if_nameindex *p, *p0;
unsigned int max = 0;
p0 = if_nameindex();
for (p = p0; p && p->if_index && p->if_name; p++) {
if (max < p->if_index)
max = p->if_index;
}
if_freenameindex(p0);
return max;
}
#endif
static void
get_rtaddrs(int addrs, struct sockaddr *sa, struct sockaddr **rti_info)
{

View File

@ -36,7 +36,9 @@
#include <sys/uio.h>
#include <net/if.h>
#if defined(__FreeBSD__) && __FreeBSD__ >= 3
#include <net/if_var.h>
#endif /* __FreeBSD__ >= 3 */
#include <netinet/in.h>
#include <netinet6/in6_var.h>
@ -49,6 +51,7 @@
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <stdlib.h>
#include "rtsold.h"
@ -57,11 +60,19 @@ static struct iovec sndiov[2];
static int probesock;
static void sendprobe __P((struct in6_addr *addr, int ifindex));
int
probe_init()
{
static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
int scmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int));
static u_char *sndcmsgbuf = NULL;
if (sndcmsgbuf == NULL &&
(sndcmsgbuf = (u_char *)malloc(scmsglen)) == NULL) {
warnmsg(LOG_ERR, __FUNCTION__, "malloc failed");
return(-1);
}
if ((probesock = socket(AF_INET6, SOCK_RAW, IPPROTO_NONE)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
@ -79,7 +90,7 @@ probe_init()
sndmhdr.msg_iov = sndiov;
sndmhdr.msg_iovlen = 1;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
sndmhdr.msg_controllen = scmsglen;
return(0);
}

View File

@ -63,7 +63,7 @@ static struct iovec rcviov[2];
static struct iovec sndiov[2];
static struct sockaddr_in6 from;
static int rssock;
int rssock;
static struct sockaddr_in6 sin6_allrouters = {sizeof(sin6_allrouters), AF_INET6};
@ -73,11 +73,21 @@ sockopen()
int on;
struct icmp6_filter filt;
static u_char answer[1500];
static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int))];
int rcvcmsglen, sndcmsglen;
static u_char *rcvcmsgbuf = NULL, *sndcmsgbuf = NULL;
sndcmsglen = rcvcmsglen = CMSG_SPACE(sizeof(struct in6_pktinfo)) +
CMSG_SPACE(sizeof(int));
if (rcvcmsgbuf == NULL && (rcvcmsgbuf = malloc(rcvcmsglen)) == NULL) {
warnmsg(LOG_ERR, __FUNCTION__,
"malloc for receive msghdr failed");
return(-1);
}
if (sndcmsgbuf == NULL && (sndcmsgbuf = malloc(sndcmsglen)) == NULL) {
warnmsg(LOG_ERR, __FUNCTION__,
"malloc for send msghdr failed");
return(-1);
}
memset(&sin6_allrouters, 0, sizeof(struct sockaddr_in6));
if (inet_pton(AF_INET6, ALLROUTER,
&sin6_allrouters.sin6_addr.s6_addr) != 1) {
@ -93,21 +103,39 @@ sockopen()
/* specify to tell receiving interface */
on = 1;
#ifdef IPV6_RECVPKTINFO
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on,
sizeof(on)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_RECVPKTINFO: %s",
strerror(errno));
exit(1);
}
#else /* old adv. API */
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_PKTINFO, &on,
sizeof(on)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_PKTINFO: %s",
strerror(errno));
exit(1);
}
#endif
on = 1;
/* specify to tell value of hoplimit field of received IP6 hdr */
#ifdef IPV6_RECVHOPLIMIT
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &on,
sizeof(on)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_RECVHOPLIMIT: %s",
strerror(errno));
exit(1);
}
#else /* old adv. API */
if (setsockopt(rssock, IPPROTO_IPV6, IPV6_HOPLIMIT, &on,
sizeof(on)) < 0) {
warnmsg(LOG_ERR, __FUNCTION__, "IPV6_HOPLIMIT: %s",
strerror(errno));
exit(1);
}
#endif
/* specfiy to accept only router advertisements on the socket */
ICMP6_FILTER_SETBLOCKALL(&filt);
@ -127,14 +155,14 @@ sockopen()
rcvmhdr.msg_iov = rcviov;
rcvmhdr.msg_iovlen = 1;
rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf;
rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf);
rcvmhdr.msg_controllen = rcvcmsglen;
/* initialize msghdr for sending packets */
sndmhdr.msg_namelen = sizeof(struct sockaddr_in6);
sndmhdr.msg_iov = sndiov;
sndmhdr.msg_iovlen = 1;
sndmhdr.msg_control = (caddr_t)sndcmsgbuf;
sndmhdr.msg_controllen = sizeof(sndcmsgbuf);
sndmhdr.msg_controllen = sndcmsglen;
return(rssock);
}

View File

@ -25,7 +25,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" $Id: rtsold.8,v 1.4 1999/09/30 00:57:15 jinmei Exp $
.\" $Id: rtsold.8,v 1.9 2000/07/04 14:44:38 jinmei Exp $
.\" $FreeBSD$
.\"
.Dd May 17, 1998
@ -53,11 +53,26 @@ If a node (re)attaches to a link,
sends some Router Solicitations on the link destined to the link-local scope
all-routers multicast address to discover new routers
and to get non link-local addresses.
.Lp
.Pp
If you invoke the program as
.Nm rtsol ,
it will transmit probes from the specified
.Ar interface ,
without becoming a daemon.
In other words,
.Nm rtsol
behaves as
.Do
.Nm
.Fl f1
.Ar interfaces
.Dc .
.Pp
Specifically,
.Nm
sends at most 3 Router Solicitations on an interface
after one of the following events:
.Pp
.Bl -bullet -compact
.It
Just after invocation of
@ -66,32 +81,32 @@ daemon.
.It
The interface is up after a temporary interface failure.
.Nm Rtsold
detects it by periodically probing if the status of the
interface is active or not.
Note that some network cards and drivers do not allow users
to extract link state.
detects such failures by periodically probing to see if the status
of the interface is active or not.
Note that some network cards and drivers do not allow the extraction
of link state.
In such cases,
.Nm
cannot detect the change of the interface status.
.It
Every one minute if
Every 60 seconds if the
.Fl m
option is specified and
option is specified and the
.Nm
daemon cannot get the interface status.
This feature does not conform to IPv6 neighbor discovery
specification, but is provided for mobile stations.
Default interval of router advertisements, which is on the order of 10
Default interval for router advertisements, which is on the order of 10
minutes, is slightly long for mobile stations.
This feature is provided
for such stations so that they can find new routers as soon as possible
when they attach another link.
when they attach to another link.
.El
.Lp
Once
.Nm
sends a Router Solicitation, and receives a valid Router Advertisement,
it desists from sending additional solicitations on that interface, until
it refrains from sending additional solicitations on that interface, until
the next time one of the above events occurs.
.Lp
When sending a Router Solicitation on an interface,
@ -103,7 +118,7 @@ Upon receipt of signal
.Dv SIGUSR1 ,
.Nm
will dump the current internal state into
.Pa /var/tmp/rtsold.dump.
.Pa /var/run/rtsold.dump.
.\"
.Sh OPTIONS
.Bl -tag -width indent
@ -134,18 +149,9 @@ periodically sends Router Solicitation on an interface that does not support
ioctl.
.It Fl 1
Perform only one probe.
Transmit Router Solcitation packet until valid Router Advertisement packet
Transmit Router Solicitation packet until valid Router Advertisement packet
arrives all the interfaces more than once, then exit.
.El
.Pp
If you invoke the program as
.Nm rtsol ,
it will behave as
.Do
.Nm
.Fl f1
.Ar interfaces
.Dc .
.Sh RETURN VALUES
The program exits with 0 on success, non-zero on failures.
.\"
@ -154,7 +160,7 @@ The program exits with 0 on success, non-zero on failures.
.It Pa /var/run/rtsold.pid
the pid of the currently running
.Nm rtsold .
.It Pa /var/tmp/rtsold.dump
.It Pa /var/run/rtsold.dump
dumps internal state on.
.El
.\"
@ -165,11 +171,22 @@ dumps internal state on.
.Sh HISTORY
The
.Nm
command is based on
command is based on the
.Nm rtsol
command, which first appeared in WIDE/KAME IPv6 protocol stack kit.
.Nm rtsol
is now integrated into
.Xr rtsold 8 .
.\" .Sh BUGS
.\" (to be written)
.\"
.Sh BUGS
In some operating systems, when a PCMCIA network card is removed
and reinserted, the corresponding interface index is changed.
However,
.Nm
does not assume such changes, and always uses the index that
it got at invocation. As a result,
.Nm
may not work if you reinsert a network card.
In such a case,
.Nm
should be killed and restarted.

View File

@ -31,7 +31,9 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
@ -81,10 +83,13 @@ int main __P((int argc, char *argv[]));
/* static variables and functions */
static int mobile_node = 0;
static int do_dump;
static char *dumpfilename = "/var/tmp/rtsold.dump"; /* XXX: should be configurable */
static char *dumpfilename = "/var/run/rtsold.dump"; /* XXX: should be configurable */
static char *pidfilename = "/var/run/rtsold.pid"; /* should be configurable */
static int ifconfig __P((char *ifname));
#if 0
static int ifreconfig __P((char *ifname));
#endif
static int make_packet __P((struct ifinfo *ifinfo));
static struct timeval *rtsol_check_timer __P((void));
static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b,
@ -92,7 +97,7 @@ static void TIMEVAL_ADD __P((struct timeval *a, struct timeval *b,
static void TIMEVAL_SUB __P((struct timeval *a, struct timeval *b,
struct timeval *result));
static void rtsold_set_dump_file __P(());
static void rtsold_set_dump_file __P((void));
static void usage __P((char *progname));
int
@ -161,8 +166,10 @@ main(argc, argv)
setlogmask(LOG_UPTO(log_upto));
}
#ifndef HAVE_ARC4RANDOM
/* random value initilization */
srandom((u_long)time(NULL));
#endif
/* warn if accept_rtadv is down */
if (!getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
@ -172,19 +179,23 @@ main(argc, argv)
if (signal(SIGUSR1, (void *)rtsold_set_dump_file) < 0)
errx(1, "failed to set signal for dump status");
/*
* Open a socket for sending RS and receiving RA.
* This should be done before calling ifinit(), since the function
* uses the socket.
*/
if ((s = sockopen()) < 0)
errx(1, "failed to open a socket");
/* configuration per interface */
if (ifinit())
errx(1, "failed to initilizatoin interfaces");
while (argc--) {
if (ifconfig(*argv))
errx(1, "failed to initilize %s", *argv);
errx(1, "failed to initialize %s", *argv);
argv++;
}
/* open a socket for sending RS and receiving RA */
if ((s = sockopen()) < 0)
errx(1, "failed to open a socket");
/* setup for probing default routers */
if (probe_init())
errx(1, "failed to setup for probing routers");
@ -210,7 +221,6 @@ main(argc, argv)
FD_ZERO(&fdset);
FD_SET(s, &fdset);
while (1) { /* main loop */
extern int errno;
int e;
struct fd_set select_fd = fdset;
@ -269,11 +279,13 @@ ifconfig(char *ifname)
if (find_ifinfo(sdl->sdl_index)) {
warnmsg(LOG_ERR, __FUNCTION__,
"interface %s was already cofigured", ifname);
free(sdl);
return(-1);
}
if ((ifinfo = malloc(sizeof(*ifinfo))) == NULL) {
warnmsg(LOG_ERR, __FUNCTION__, "memory allocation failed");
free(sdl);
return(-1);
}
memset(ifinfo, 0, sizeof(*ifinfo));
@ -318,11 +330,38 @@ ifconfig(char *ifname)
return(0);
bad:
free(ifinfo);
free(ifinfo->sdl);
free(ifinfo);
return(-1);
}
#if 0
static int
ifreconfig(char *ifname)
{
struct ifinfo *ifi, *prev;
int rv;
prev = NULL;
for (ifi = iflist; ifi; ifi = ifi->next) {
if (strncmp(ifi->ifname, ifname, sizeof(ifi->ifname)) == 0)
break;
prev = ifi;
}
prev->next = ifi->next;
rv = ifconfig(ifname);
/* reclaim it after ifconfig() in case ifname is pointer inside ifi */
if (ifi->rs_data)
free(ifi->rs_data);
free(ifi->sdl);
free(ifi);
return rv;
}
#endif
struct ifinfo *
find_ifinfo(int ifindex)
{
@ -506,7 +545,11 @@ rtsol_timer_update(struct ifinfo *ifinfo)
ifinfo->timer = tm_max; /* stop timer(valid?) */
break;
case IFS_DELAY:
#ifndef HAVE_ARC4RANDOM
interval = random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
#else
interval = arc4random() % (MAX_RTR_SOLICITATION_DELAY * MILLION);
#endif
ifinfo->timer.tv_sec = interval / MILLION;
ifinfo->timer.tv_usec = interval % MILLION;
break;

View File

@ -33,7 +33,7 @@ struct ifinfo {
struct ifinfo *next; /* pointer to the next interface */
struct sockaddr_dl *sdl; /* link-layer address */
char ifname[16]; /* interface name */
char ifname[IF_NAMESIZE]; /* interface name */
int active; /* interface status */
int probeinterval; /* interval of probe timer(if necessary) */
int probetimer; /* rest of probe timer */
@ -43,6 +43,7 @@ struct ifinfo {
int dadcount;
struct timeval timer;
struct timeval expire;
int errors; /* # of errors we've got - detect wedge */
int racnt; /* total # of valid RAs it have got */