sync with sys/netinet/icmp6.h change (no bitfield for router renumber).

more logging.  improve error handling/garbage collection.  sync with kame.
This commit is contained in:
itojun 2000-07-06 12:37:56 +00:00
parent 0a1e211454
commit 19a4d0910c
10 changed files with 210 additions and 77 deletions

View File

@ -1,5 +1,5 @@
/* $NetBSD: dump.c,v 1.1 2000/05/23 11:37:58 itojun Exp $ */
/* $KAME: dump.c,v 1.10 2000/05/23 11:31:25 itojun Exp $ */
/* $NetBSD: dump.c,v 1.2 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: dump.c,v 1.11 2000/05/27 11:30:43 jinmei Exp $ */
/*
* Copyright (C) 2000 WIDE Project.
@ -55,6 +55,7 @@
#include "rtadvd.h"
#include "timer.h"
#include "if.h"
#include "dump.h"
static FILE *fp;
@ -100,6 +101,10 @@ if_dump()
for (rai = ralist; rai; rai = rai->next) {
fprintf(fp, "%s:\n", rai->ifname);
fprintf(fp, " Status: %s\n",
(iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" :
"DOWN");
/* control information */
if (rai->lastsent.tv_sec) {
/* note that ctime() appends CR by itself */
@ -110,6 +115,8 @@ if_dump()
fprintf(fp, " Next RA will be sent: %s",
ctime((time_t *)&rai->timer->tm.tv_sec));
}
else
fprintf(fp, " RA timer is stopped");
fprintf(fp, " waits: %d, initcount: %d\n",
rai->waiting, rai->initcounter);

View File

@ -1,5 +1,5 @@
/* $NetBSD: if.c,v 1.5 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: if.c,v 1.8 2000/05/22 22:04:37 itojun Exp $ */
/* $NetBSD: if.c,v 1.6 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: if.c,v 1.11 2000/07/06 08:20:04 jinmei Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -39,9 +39,7 @@
#ifdef __FreeBSD__
# include <net/ethernet.h>
#endif
#ifdef __bsdi__
#include <ifaddrs.h>
#endif
#ifdef __NetBSD__
#include <net/if_ether.h>
#endif
@ -149,7 +147,7 @@ if_nametosdl(char *name)
int
if_getmtu(char *name)
{
#ifndef __bsdi__
#if 0
struct ifreq ifr;
int s;
@ -207,6 +205,7 @@ if_getflags(int ifindex, int oifflags)
close(s);
return (oifflags & ~IFF_UP);
}
close(s);
return (ifr.ifr_flags);
}
@ -589,5 +588,4 @@ init_iflist()
/* make list of pointers to each if_msghdr */
parse_iflist(&iflist, ifblock, ifblock_size);
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: if.h,v 1.3 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: if.h,v 1.2 2000/05/16 13:34:13 itojun Exp $ */
/* $NetBSD: if.h,v 1.4 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: if.h,v 1.3 2000/05/27 11:47:09 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -36,6 +36,7 @@ extern struct if_msghdr **iflist;
extern size_t ifblock_size;
extern char *ifblock;
struct nd_opt_hdr;
struct sockaddr_dl *if_nametosdl __P((char *name));
int if_getmtu __P((char *name));
int if_getflags __P((int ifindex, int oifflags));

View File

@ -1,5 +1,5 @@
/* $NetBSD: rrenum.c,v 1.4 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: rrenum.c,v 1.3 2000/05/16 13:34:14 itojun Exp $ */
/* $NetBSD: rrenum.c,v 1.5 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: rrenum.c,v 1.4 2000/07/03 02:51:08 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -65,7 +65,8 @@ struct rr_operation {
static struct rr_operation rro;
static int rr_rcvifindex;
static int rrcmd2pco[RPM_PCO_MAX] = {0,
static int rrcmd2pco[RPM_PCO_MAX] = {
0,
SIOCAIFPREFIX_IN6,
SIOCCIFPREFIX_IN6,
SIOCSGIFPREFIX_IN6
@ -171,14 +172,20 @@ do_use_prefix(int len, struct rr_pco_match *rpm, struct in6_rrenumreq *irr) {
/* init in6_rrenumreq fields */
irr->irr_u_uselen = rpu->rpu_uselen;
irr->irr_u_keeplen = rpu->rpu_keeplen;
irr->irr_raf_mask_onlink = rpu->rpu_mask_onlink;
irr->irr_raf_mask_auto = rpu->rpu_mask_autonomous;
irr->irr_raf_mask_onlink =
(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
irr->irr_raf_mask_auto =
(rpu->rpu_ramask & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
irr->irr_vltime = rpu->rpu_vltime;
irr->irr_pltime = rpu->rpu_pltime;
irr->irr_raf_onlink = rpu->rpu_onlink;
irr->irr_raf_auto = rpu->rpu_autonomous;
irr->irr_rrf_decrvalid = rpu->rpu_decr_vltime;
irr->irr_rrf_decrprefd = rpu->rpu_decr_pltime;
irr->irr_raf_onlink =
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_ONLINK);
irr->irr_raf_auto =
(rpu->rpu_raflags & ICMP6_RR_PCOUSE_RAFLAGS_AUTO);
irr->irr_rrf_decrvalid =
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME);
irr->irr_rrf_decrprefd =
(rpu->rpu_flags & ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME);
irr->irr_useprefix.sin6_len = sizeof(irr->irr_useprefix);
irr->irr_useprefix.sin6_family = AF_INET6;
irr->irr_useprefix.sin6_addr = rpu->rpu_prefix;
@ -220,10 +227,10 @@ do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm)
while (if_indextoname(++ifindex, irr.irr_name)) {
/*
* if rr_forceapply(A flag) is 0 and IFF_UP is off,
* if ICMP6_RR_FLAGS_FORCEAPPLY(A flag) is 0 and IFF_UP is off,
* the interface is not applied
*/
if (!rr->rr_forceapply &&
if ((rr->rr_flags & ICMP6_RR_FLAGS_FORCEAPPLY) == 0 &&
(iflist[ifindex]->ifm_flags & IFF_UP) == 0)
continue;
/* TODO: interface scope check */
@ -321,9 +328,9 @@ rr_command_check(int len, struct icmp6_router_renum *rr, struct in6_addr *from,
return 1;
}
if (rro.rro_seqnum == rr->rr_seqnum &&
rr->rr_test == 0 &&
(rr->rr_flags & ICMP6_RR_FLAGS_TEST) == 0 &&
RR_ISSET_SEGNUM(rro.rro_segnum_bits, rr->rr_segnum)) {
if (rr->rr_reqresult)
if ((rr->rr_flags & ICMP6_RR_FLAGS_REQRESULT) != 0)
syslog(LOG_WARNING,
"<%s> rcvd duped segnum %d from %s",
__FUNCTION__, rr->rr_segnum,
@ -352,7 +359,8 @@ rr_command_input(int len, struct icmp6_router_renum *rr,
/* rr_command validity check */
if (rr_command_check(len, rr, from, dst))
goto failed;
if (rr->rr_test && !rr->rr_reqresult)
if ((rr->rr_flags & (ICMP6_RR_FLAGS_TEST|ICMP6_RR_FLAGS_REQRESULT)) ==
ICMP6_RR_FLAGS_TEST)
return;
/* do router renumbering */

View File

@ -1,5 +1,5 @@
.\" $NetBSD: rtadvd.8,v 1.8 2000/05/23 11:37:59 itojun Exp $
.\" $KAME: rtadvd.8,v 1.8 2000/05/22 22:12:11 itojun Exp $
.\" $NetBSD: rtadvd.8,v 1.9 2000/07/06 12:37:56 itojun Exp $
.\" $KAME: rtadvd.8,v 1.9 2000/05/27 13:37:01 jinmei Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -64,13 +64,18 @@ them as on-link prefixes.
.Nm
also watches the routing table.
By default, if an interface direct route is
added/deleted on an advertising interface,
added/deleted on an advertising interface and no static prefixes are
specified by the configuration file,
.Nm
adds/deletes the corresponding prefix to/from its advertising list,
respectively.
The
.Ic Fl s
command line option may be used to disable this behavior.
may be used to disable this behavior.
Moreover, if the status of an advertising interface changes,
.Nm
will start or stop sending router advertisements according
to the latest status.
.Pp
The command line options are:
.Bl -tag -width indent
@ -96,7 +101,8 @@ Foreground mode (useful when debugging).
Accept router renumbering requests.
If you enable it, certain IPsec setup is suggested for security reasons.
.It Fl s
Do not monitor routing table changes (static prefix).
Do not add or delete prefixes dynamically.
Only statically configured prefixes, if any, will be advertised.
.El
.Pp
Upon receipt of signal

View File

@ -1,5 +1,5 @@
/* $NetBSD: rtadvd.c,v 1.9 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: rtadvd.c,v 1.26 2000/05/23 11:31:26 itojun Exp $ */
/* $NetBSD: rtadvd.c,v 1.10 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: rtadvd.c,v 1.31 2000/06/23 06:34:51 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -243,12 +243,10 @@ main(argc, argv)
FD_ZERO(&fdset);
FD_SET(sock, &fdset);
maxfd = sock;
if (sflag == 0) {
rtsock_open();
FD_SET(rtsock, &fdset);
if (rtsock > sock)
maxfd = rtsock;
}
signal(SIGTERM, (void *)die);
signal(SIGUSR1, (void *)rtadvd_set_dump_file);
@ -264,11 +262,18 @@ main(argc, argv)
/* timer expiration check and reset the timer */
timeout = rtadvd_check_timer();
if (timeout != NULL) {
syslog(LOG_DEBUG,
"<%s> set timer to %ld:%ld. waiting for inputs "
"or timeout",
"<%s> set timer to %ld:%ld. waiting for "
"inputs or timeout",
__FUNCTION__,
(long int)timeout->tv_sec, (long int)timeout->tv_usec);
(long int)timeout->tv_sec,
(long int)timeout->tv_usec);
} else {
syslog(LOG_DEBUG,
"<%s> there's no timer. waiting for inputs",
__FUNCTION__);
}
if ((i = select(maxfd + 1, &select_fd,
NULL, NULL, timeout)) < 0) {
@ -343,7 +348,7 @@ rtmsg_input()
if (n > rtmsg_len(msg)) {
/*
* This usually won't happen for messages received on
* an routing socket.
* a routing socket.
*/
if (dflag > 1)
syslog(LOG_DEBUG,
@ -359,6 +364,8 @@ rtmsg_input()
lim = msg + n;
for (next = msg; next < lim; next += len) {
int oldifflags;
next = get_next_msg(next, lim, 0, &len,
RTADV_TYPE2BITMASK(RTM_ADD) |
RTADV_TYPE2BITMASK(RTM_DELETE) |
@ -388,7 +395,7 @@ rtmsg_input()
__FUNCTION__, __LINE__, type,
if_indextoname(ifindex, ifname));
}
return;
continue;
}
if ((rai = if_indextorainfo(ifindex)) == NULL) {
@ -399,16 +406,20 @@ rtmsg_input()
__FUNCTION__,
if_indextoname(ifindex, ifname));
}
return;
continue;
}
oldifflags = iflist[ifindex]->ifm_flags;
switch(type) {
case RTM_ADD:
/* init iffalgs because it may have changed */
/* init ifflags because it may have changed */
iflist[ifindex]->ifm_flags =
if_getflags(ifindex,
iflist[ifindex]->ifm_flags);
if (sflag)
break; /* we aren't interested in prefixes */
addr = get_addr(msg);
plen = get_prefixlen(msg);
/* sanity check for plen */
@ -417,7 +428,7 @@ rtmsg_input()
syslog(LOG_INFO, "<%s> new interface route's"
"plen %d is invalid for a prefix",
__FUNCTION__, plen);
return;
break;
}
prefix = find_prefix(rai, addr, plen);
if (prefix) {
@ -433,7 +444,7 @@ rtmsg_input()
plen,
rai->ifname);
}
return;
break;
}
make_prefix(rai, ifindex, addr, plen);
break;
@ -443,6 +454,9 @@ rtmsg_input()
if_getflags(ifindex,
iflist[ifindex]->ifm_flags);
if (sflag)
break;
addr = get_addr(msg);
plen = get_prefixlen(msg);
/* sanity check for plen */
@ -452,7 +466,7 @@ rtmsg_input()
"route's"
"plen %d is invalid for a prefix",
__FUNCTION__, plen);
return;
break;
}
prefix = find_prefix(rai, addr, plen);
if (prefix == NULL) {
@ -468,7 +482,7 @@ rtmsg_input()
plen,
rai->ifname);
}
return;
break;
}
delete_prefix(rai, prefix);
break;
@ -492,6 +506,29 @@ rtmsg_input()
}
return;
}
/* check if an interface flag is changed */
if ((oldifflags & IFF_UP) != 0 && /* UP to DOWN */
(iflist[ifindex]->ifm_flags & IFF_UP) == 0) {
syslog(LOG_INFO,
"<%s> interface %s becomes down. stop timer.",
__FUNCTION__, rai->ifname);
rtadvd_remove_timer(&rai->timer);
}
else if ((oldifflags & IFF_UP) == 0 && /* DOWN to UP */
(iflist[ifindex]->ifm_flags & IFF_UP) != 0) {
syslog(LOG_INFO,
"<%s> interface %s becomes up. restart timer.",
__FUNCTION__, rai->ifname);
rai->initcounter = 0; /* reset the counter */
rai->waiting = 0; /* XXX */
rai->timer = rtadvd_add_timer(ra_timeout,
ra_timer_update,
rai, rai);
ra_timer_update((void *)rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
}
}
return;
@ -550,6 +587,18 @@ rtadvd_input()
return;
}
/*
* If we happen to receive data on an interface which is now down,
* just discard the data.
*/
if ((iflist[pi->ipi6_ifindex]->ifm_flags & IFF_UP) == 0) {
syslog(LOG_INFO,
"<%s> received data on a disabled interface (%s)",
__FUNCTION__,
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
#ifdef OLDRAWSOCKET
if (i < sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr)) {
syslog(LOG_ERR,
@ -741,6 +790,19 @@ rs_input(int len, struct nd_router_solicit *rs,
{
long delay; /* must not be greater than 1000000 */
struct timeval interval, now, min_delay, tm_tmp, *rest;
struct soliciter *sol;
/*
* record sockaddr waiting for RA, if possible
*/
sol = (struct soliciter *)malloc(sizeof(*sol));
if (sol) {
sol->addr = *from;
/*XXX RFC2553 need clarification on flowinfo */
sol->addr.sin6_flowinfo = 0;
sol->next = ra->soliciter;
ra->soliciter = sol->next;
}
/*
* If there is already a waiting RS packet, don't
@ -1298,9 +1360,15 @@ ra_output(rainfo)
struct rainfo *rainfo;
{
int i;
struct cmsghdr *cm;
struct in6_pktinfo *pi;
struct soliciter *sol, *nextsol;
if ((iflist[rainfo->ifindex]->ifm_flags & IFF_UP) == 0) {
syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA",
__FUNCTION__, rainfo->ifname);
return;
}
sndmhdr.msg_name = (caddr_t)&sin6_allnodes;
sndmhdr.msg_iov[0].iov_base = (caddr_t)rainfo->ra_data;
@ -1340,6 +1408,32 @@ struct rainfo *rainfo;
}
}
/*
* unicast advertisements
* XXX commented out. reason: though spec does not forbit it, unicast
* advert does not really help
*/
for (sol = rainfo->soliciter; sol; sol = nextsol) {
nextsol = sol->next;
#if 0
sndmhdr.msg_name = (caddr_t)&sol->addr;
i = sendmsg(sock, &sndmhdr, 0);
if (i < 0 || i != rainfo->ra_datalen) {
if (i < 0) {
syslog(LOG_ERR,
"<%s> unicast sendmsg on %s: %s",
__FUNCTION__, rainfo->ifname,
strerror(errno));
}
}
#endif
sol->next = NULL;
free(sol);
}
rainfo->soliciter = NULL;
/* update counter */
if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS)
rainfo->initcounter++;
@ -1366,11 +1460,7 @@ ra_timeout(void *data)
"<%s> RA timer on %s is expired",
__FUNCTION__, rai->ifname);
if (iflist[rai->ifindex]->ifm_flags & IFF_UP)
ra_output(rai);
else
syslog(LOG_DEBUG, "<%s> %s is not up, skip sending RA",
__FUNCTION__, rai->ifname);
}
/* update RA timer */

View File

@ -1,5 +1,5 @@
.\" $NetBSD: rtadvd.conf.5,v 1.3 2000/05/23 11:37:59 itojun Exp $
.\" $KAME: rtadvd.conf.5,v 1.5 2000/05/22 22:22:56 itojun Exp $
.\" $NetBSD: rtadvd.conf.5,v 1.4 2000/07/06 12:37:56 itojun Exp $
.\" $KAME: rtadvd.conf.5,v 1.6 2000/05/26 10:54:58 jinmei Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -134,7 +134,7 @@ for each item below.
Indices vary from 0 to N-1, where N is the
value of
.Ic addrs .
Each index shall follows the name of each item, e.g.,
Each index shall follow the name of each item, e.g.,
.Dq prefixlen2 .
.It Cm \&prefixlen
(num) Prefix length field.

View File

@ -1,5 +1,5 @@
/* $NetBSD: rtadvd.h,v 1.4 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: rtadvd.h,v 1.8 2000/05/16 13:34:14 itojun Exp $ */
/* $NetBSD: rtadvd.h,v 1.5 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: rtadvd.h,v 1.9 2000/06/22 20:16:13 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -85,6 +85,11 @@ struct prefix {
struct in6_addr prefix;
};
struct soliciter {
struct soliciter *next;
struct sockaddr_in6 addr;
};
struct rainfo {
/* pointer for list */
struct rainfo *next;
@ -132,6 +137,9 @@ struct rainfo {
u_quad_t rainput; /* number of RAs received */
u_quad_t rainconsistent; /* number of RAs inconsistent with ours */
u_quad_t rsinput; /* number of RSs received */
/* info about soliciter */
struct soliciter *soliciter; /* recent solication source */
};
void ra_timeout __P((void *));

View File

@ -1,5 +1,5 @@
/* $NetBSD: timer.c,v 1.3 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: timer.c,v 1.3 2000/05/22 22:23:07 itojun Exp $ */
/* $NetBSD: timer.c,v 1.4 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: timer.c,v 1.4 2000/05/27 11:30:43 jinmei Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -44,6 +44,8 @@
static struct rtadvd_timer timer_head;
#define MILLION 1000000
#define TIMEVAL_EQUAL(t1,t2) ((t1)->tv_sec == (t2)->tv_sec &&\
(t1)->tv_usec == (t2)->tv_usec)
static struct timeval tm_max = {0x7fffffff, 0x7fffffff};
@ -93,6 +95,14 @@ rtadvd_add_timer(void (*timeout) __P((void *)),
return(newtimer);
}
void
rtadvd_remove_timer(struct rtadvd_timer **timer)
{
remque(*timer);
free(*timer);
*timer = NULL;
}
void
rtadvd_set_timer(struct timeval *tm, struct rtadvd_timer *timer)
{
@ -139,7 +149,11 @@ rtadvd_check_timer()
tm = tm->next;
}
if (TIMEVAL_LT(timer_head.tm, now)) {
if (TIMEVAL_EQUAL(&tm_max, &timer_head.tm)) {
/* no need to timeout */
return(NULL);
}
else if (TIMEVAL_LT(timer_head.tm, now)) {
/* this may occur when the interval is too small */
returnval.tv_sec = returnval.tv_usec = 0;
}

View File

@ -1,5 +1,5 @@
/* $NetBSD: timer.h,v 1.3 2000/05/23 11:37:59 itojun Exp $ */
/* $KAME: timer.h,v 1.2 2000/05/16 13:34:14 itojun Exp $ */
/* $NetBSD: timer.h,v 1.4 2000/07/06 12:37:56 itojun Exp $ */
/* $KAME: timer.h,v 1.3 2000/05/27 11:30:43 jinmei Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -56,6 +56,7 @@ void rtadvd_timer_init __P((void));
struct rtadvd_timer *rtadvd_add_timer __P((void (*) __P((void *)),
void (*) __P((void *, struct timeval *)), void *, void *));
void rtadvd_set_timer __P((struct timeval *, struct rtadvd_timer *));
void rtadvd_remove_timer __P((struct rtadvd_timer **));
struct timeval * rtadvd_check_timer __P((void));
struct timeval * rtadvd_timer_rest __P((struct rtadvd_timer *));
void TIMEVAL_ADD __P((struct timeval *, struct timeval *,