From 514e9d866304587061951dc0480b88ea46ec2ee1 Mon Sep 17 00:00:00 2001 From: itojun Date: Mon, 13 Mar 2000 06:16:11 +0000 Subject: [PATCH] bring in latest rtadvd source from kame. this fixes unclosed file descriptor in router renumbering case. --- usr.sbin/rtadvd/config.c | 116 +++++++++++++++++++++++++++++++--- usr.sbin/rtadvd/if.c | 11 ++-- usr.sbin/rtadvd/rrenum.c | 6 +- usr.sbin/rtadvd/rtadvd.8 | 14 ++-- usr.sbin/rtadvd/rtadvd.c | 55 +++++++++++++--- usr.sbin/rtadvd/rtadvd.conf.5 | 4 +- usr.sbin/rtadvd/rtadvd.h | 30 ++++++++- 7 files changed, 199 insertions(+), 37 deletions(-) diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index 7fa309813e7..b3042761c4f 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.4 2000/02/08 05:34:45 itojun Exp $ */ +/* $OpenBSD: config.c,v 1.5 2000/03/13 06:16:11 itojun Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -46,6 +46,9 @@ #include #include #include +#ifdef MIP6 +#include +#endif #include @@ -83,7 +86,7 @@ getconfig(intface) char *addr; #define MUSTHAVE(var, cap) \ - { \ + do { \ int t; \ if ((t = agetnum(cap)) < 0) { \ fprintf(stderr, "rtadvd: need %s for interface %s\n", \ @@ -91,12 +94,12 @@ getconfig(intface) exit(1); \ } \ var = t; \ - } + } while (0) #define MAYHAVE(var, cap, def) \ - { \ + do { \ if ((var = agetnum(cap)) < 0) \ var = def; \ - } + } while (0) if ((stat = agetent(tbuf, intface)) <= 0) { memset(tbuf, 0, sizeof(tbuf)); @@ -140,7 +143,7 @@ getconfig(intface) MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL); if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) { syslog(LOG_ERR, - "<%s> maxinterval must be between %d and %d", + "<%s> maxinterval must be between %e and %u", __FUNCTION__, MIN_MAXINTERVAL, MAX_MAXINTERVAL); exit(1); } @@ -148,7 +151,7 @@ getconfig(intface) MAYHAVE(val, "mininterval", tmp->maxinterval/3); if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) { syslog(LOG_ERR, - "<%s> mininterval must be between %d and %d", + "<%s> mininterval must be between %e and %d", __FUNCTION__, MIN_MININTERVAL, (tmp->maxinterval * 3) / 4); @@ -162,6 +165,10 @@ getconfig(intface) MAYHAVE(val, "raflags", 0); tmp->managedflg= val & ND_RA_FLAG_MANAGED; tmp->otherflg = val & ND_RA_FLAG_OTHER; +#ifdef MIP6 + if (mobileip6) + tmp->haflg = val & ND_RA_FLAG_HA; +#endif MAYHAVE(val, "rltime", tmp->maxinterval * 3); if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) { @@ -191,6 +198,39 @@ getconfig(intface) } tmp->retranstimer = (u_int32_t)val; +#ifdef MIP6 + if (!mobileip6) +#else + if (1) +#endif + { + if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) { + syslog(LOG_ERR, + "<%s> mobile-ip6 configuration without " + "proper command line option", + __FUNCTION__); + exit(1); + } + } +#ifdef MIP6 + else { + tmp->hapref = 0; + if ((val = agetnum("hapref")) >= 0) + tmp->hapref = (int16_t)val; + if (tmp->hapref != 0) { + tmp->hatime = 0; + MUSTHAVE(val, "hatime"); + tmp->hatime = (u_int16_t)val; + if (tmp->hatime <= 0) { + syslog(LOG_ERR, + "<%s> home agent lifetime must be greater than 0", + __FUNCTION__); + exit(1); + } + } + } +#endif + /* prefix information */ if ((pfxs = agetnum("addrs")) < 0) { /* auto configure prefix information */ @@ -231,10 +271,24 @@ getconfig(intface) pfx->prefixlen = (int)val; makeentry(entbuf, i, "pinfoflags", added); - MAYHAVE(val, entbuf, - (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO)); +#ifdef MIP6 + if (mobileip6) + { + MAYHAVE(val, entbuf, + (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO| + ND_OPT_PI_FLAG_RTADDR)); + } else +#endif + { + MAYHAVE(val, entbuf, + (ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO)); + } pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK; pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO; +#ifdef MIP6 + if (mobileip6) + pfx->routeraddr = val & ND_OPT_PI_FLAG_RTADDR; +#endif makeentry(entbuf, i, "vltime", added); MAYHAVE(val, entbuf, DEF_ADVVALIDLIFETIME); @@ -517,6 +571,7 @@ init_prefix(struct in6_prefixreq *ipr) "This should not happen if I am router", __FUNCTION__, inet_ntop(AF_INET6, &ipr->ipr_prefix.sin6_addr, ntopbuf, sizeof(ntopbuf)), ipr->ipr_origin); + close(s); return 1; } @@ -554,6 +609,10 @@ make_packet(struct rainfo *rainfo) struct nd_router_advert *ra; struct nd_opt_prefix_info *ndopt_pi; struct nd_opt_mtu *ndopt_mtu; +#ifdef MIP6 + struct nd_opt_advint *ndopt_advint; + struct nd_opt_hai *ndopt_hai; +#endif struct prefix *pfx; /* calculate total length */ @@ -573,6 +632,12 @@ make_packet(struct rainfo *rainfo) packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs; if (rainfo->linkmtu) packlen += sizeof(struct nd_opt_mtu); +#ifdef MIP6 + if (mobileip6 && rainfo->maxinterval) + packlen += sizeof(struct nd_opt_advint); + if (mobileip6 && rainfo->hatime) + packlen += sizeof(struct nd_opt_hai); +#endif /* allocate memory for the packet */ if ((buf = malloc(packlen)) == NULL) { @@ -598,6 +663,10 @@ make_packet(struct rainfo *rainfo) rainfo->managedflg ? ND_RA_FLAG_MANAGED : 0; ra->nd_ra_flags_reserved |= rainfo->otherflg ? ND_RA_FLAG_OTHER : 0; +#ifdef MIP6 + ra->nd_ra_flags_reserved |= + rainfo->haflg ? ND_RA_FLAG_HA : 0; +#endif ra->nd_ra_router_lifetime = htons(rainfo->lifetime); ra->nd_ra_reachable = htonl(rainfo->reachabletime); ra->nd_ra_retransmit = htonl(rainfo->retranstimer); @@ -617,6 +686,30 @@ make_packet(struct rainfo *rainfo) buf += sizeof(struct nd_opt_mtu); } +#ifdef MIP6 + if (mobileip6 && rainfo->maxinterval) { + ndopt_advint = (struct nd_opt_advint *)buf; + ndopt_advint->nd_opt_int_type = ND_OPT_ADV_INTERVAL; + ndopt_advint->nd_opt_int_len = 1; + ndopt_advint->nd_opt_int_reserved = 0; + ndopt_advint->nd_opt_int_interval = ntohl(rainfo->maxinterval * + 1000); + buf += sizeof(struct nd_opt_advint); + } +#endif + +#ifdef MIP6 + if (rainfo->hatime) { + ndopt_hai = (struct nd_opt_hai *)buf; + ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION; + ndopt_hai->nd_opt_hai_len = 1; + ndopt_hai->nd_opt_hai_reserved = 0; + ndopt_hai->nd_opt_hai_pref = ntohs(rainfo->hapref); + ndopt_hai->nd_opt_hai_lifetime = ntohs(rainfo->hatime); + buf += sizeof(struct nd_opt_hai); + } +#endif + for (pfx = rainfo->prefix.next; pfx != &rainfo->prefix; pfx = pfx->next) { ndopt_pi = (struct nd_opt_prefix_info *)buf; @@ -630,6 +723,11 @@ make_packet(struct rainfo *rainfo) if (pfx->autoconfflg) ndopt_pi->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; +#ifdef MIP6 + if (pfx->routeraddr) + ndopt_pi->nd_opt_pi_flags_reserved |= + ND_OPT_PI_FLAG_RTADDR; +#endif ndopt_pi->nd_opt_pi_valid_time = ntohl(pfx->validlifetime); ndopt_pi->nd_opt_pi_preferred_time = ntohl(pfx->preflifetime); diff --git a/usr.sbin/rtadvd/if.c b/usr.sbin/rtadvd/if.c index 1485e3d5b27..6740ea68787 100644 --- a/usr.sbin/rtadvd/if.c +++ b/usr.sbin/rtadvd/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.2 1999/12/11 10:33:28 itojun Exp $ */ +/* $OpenBSD: if.c,v 1.3 2000/03/13 06:16:11 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -167,21 +167,22 @@ if_getmtu(char *name) return(ifr.ifr_mtu); #endif #ifdef __bsdi__ - struct ifaddrs *ifa; + struct ifaddrs *ifap, *ifa; struct if_data *ifd; - if (getifaddrs(&ifa) < 0) + if (getifaddrs(&ifap) < 0) return(0); - while (ifa) { + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { if (strcmp(ifa->ifa_name, name) == 0) { ifd = ifa->ifa_data; + freeifaddrs(ifap); if (ifd) return ifd->ifi_mtu; else return 0; } - ifa = ifa->ifa_next; } + freeifaddrs(ifap); return 0; #endif /* last resort */ diff --git a/usr.sbin/rtadvd/rrenum.c b/usr.sbin/rtadvd/rrenum.c index 38d59992c53..5c20c934f04 100644 --- a/usr.sbin/rtadvd/rrenum.c +++ b/usr.sbin/rtadvd/rrenum.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rrenum.c,v 1.2 1999/12/11 10:33:28 itojun Exp $ */ +/* $OpenBSD: rrenum.c,v 1.3 2000/03/13 06:16:11 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -69,7 +69,7 @@ static int rrcmd2pco[RPM_PCO_MAX] = {0, SIOCCIFPREFIX_IN6, SIOCSGIFPREFIX_IN6 }; -static int s; +static int s = -1; /* * Check validity of a Prefix Control Operation(PCO). @@ -202,7 +202,7 @@ do_pco(struct icmp6_router_renum *rr, int len, struct rr_pco_match *rpm) if ((rr_pco_check(len, rpm) != NULL)) return 1; - if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { + if (s == -1 && (s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, strerror(errno)); exit(1); diff --git a/usr.sbin/rtadvd/rtadvd.8 b/usr.sbin/rtadvd/rtadvd.8 index b220bb92f10..1c86af430c9 100644 --- a/usr.sbin/rtadvd/rtadvd.8 +++ b/usr.sbin/rtadvd/rtadvd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rtadvd.8,v 1.7 2000/02/02 04:10:37 itojun Exp $ +.\" $OpenBSD: rtadvd.8,v 1.8 2000/03/13 06:16:11 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" KAME Id: rtadvd.8,v 1.4 2000/02/02 03:55:44 itojun Exp +.\" KAME Id: rtadvd.8,v 1.5 2000/02/08 05:19:36 itojun Exp .\" .Dd May 17, 1998 .Dt RTADVD 8 @@ -38,7 +38,7 @@ .Sh SYNOPSIS .Nm .Op Fl c Ar configfile -.Op Fl dDfsR +.Op Fl dDfRs .Ar interface ... .Sh DESCRIPTION .Nm Rtadvd @@ -89,11 +89,15 @@ Print debugging information. Even more debugging information is printed. .It Fl f Foreground mode (useful when debugging). -.It Fl s -Do not monitor routing table changes (static prefix). +.\".It Fl m +.\"Enables mobile IPv6 support. +.\"This changes the content of router advertisement option, as well as +.\"permitted configuration directives. .It Fl R 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). .El .Pp Use diff --git a/usr.sbin/rtadvd/rtadvd.c b/usr.sbin/rtadvd/rtadvd.c index e00eaa98947..82384327e10 100644 --- a/usr.sbin/rtadvd/rtadvd.c +++ b/usr.sbin/rtadvd/rtadvd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtadvd.c,v 1.3 2000/02/02 04:10:37 itojun Exp $ */ +/* $OpenBSD: rtadvd.c,v 1.4 2000/03/13 06:16:11 itojun Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -60,14 +61,19 @@ #include "config.h" struct msghdr rcvmhdr; -static u_char rcvcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; +static u_char *rcvcmsgbuf; +static size_t rcvcmsgbuflen; +static u_char *sndcmsgbuf = NULL; +static size_t sndcmsgbuflen; struct msghdr sndmhdr; struct iovec rcviov[2]; struct iovec sndiov[2]; struct sockaddr_in6 from; struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; int sock, rtsock; +#ifdef MIP6 +int mobileip6 = 0; +#endif int accept_rr = 0; int dflag = 0, sflag = 0; @@ -142,7 +148,13 @@ main(argc, argv) openlog(*argv, LOG_NDELAY|LOG_PID, LOG_DAEMON); /* get command line options and arguments */ - while ((ch = getopt(argc, argv, "c:dDfRs")) != -1) { +#ifdef MIP6 +#define OPTIONS "c:dDfmRs" +#else +#define OPTIONS "c:dDfRs" +#endif + while ((ch = getopt(argc, argv, OPTIONS)) != -1) { +#undef OPTIONS switch(ch) { case 'c': conffile = optarg; @@ -156,6 +168,11 @@ main(argc, argv) case 'f': fflag = 1; break; +#ifdef MIP6 + case 'm': + mobileip6 = 1; + break; +#endif case 'R': accept_rr = 1; break; @@ -168,7 +185,11 @@ main(argc, argv) argv += optind; if (argc == 0) { fprintf(stderr, - "usage: rtadvd [-dDfsR] [-c conffile] " +#ifdef MIP6 + "usage: rtadvd [-dDfmRs] [-c conffile] " +#else + "usage: rtadvd [-dDfRs] [-c conffile] " +#endif "interfaces...\n"); exit(1); } @@ -463,7 +484,7 @@ rtadvd_input() * be modified if we had received a message before setting * receive options. */ - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); + rcvmhdr.msg_controllen = rcvcmsgbuflen; if ((i = recvmsg(sock, &rcvmhdr, 0)) < 0) return; @@ -1076,8 +1097,22 @@ sock_open() int on; /* XXX: should be max MTU attached to the node */ static u_char answer[1500]; - static u_char sndcmsgbuf[CMSG_SPACE(sizeof(struct in6_pktinfo)) + - CMSG_SPACE(sizeof(int))]; + + rcvcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + rcvcmsgbuf = (u_char *)malloc(rcvcmsgbuflen); + if (rcvcmsgbuf == NULL) { + syslog(LOG_ERR, "<%s> not enough core", __FUNCTION__); + exit(1); + } + + sndcmsgbuflen = CMSG_SPACE(sizeof(struct in6_pktinfo)) + + CMSG_SPACE(sizeof(int)); + sndcmsgbuf = (u_char *)malloc(sndcmsgbuflen); + if (sndcmsgbuf == NULL) { + syslog(LOG_ERR, "<%s> not enough core", __FUNCTION__); + exit(1); + } if ((sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) { syslog(LOG_ERR, "<%s> socket: %s", __FUNCTION__, @@ -1162,14 +1197,14 @@ sock_open() rcvmhdr.msg_iov = rcviov; rcvmhdr.msg_iovlen = 1; rcvmhdr.msg_control = (caddr_t) rcvcmsgbuf; - rcvmhdr.msg_controllen = sizeof(rcvcmsgbuf); + rcvmhdr.msg_controllen = rcvcmsgbuflen; /* 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 = sndcmsgbuflen; return; } diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index 7768620cf25..f176e33f980 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rtadvd.conf.5,v 1.2 1999/12/11 10:33:29 itojun Exp $ +.\" $OpenBSD: rtadvd.conf.5,v 1.3 2000/03/13 06:16:11 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. .\" All rights reserved. @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" KAME Id: rtadvd.conf.5,v 1.1.1.1 1999/08/08 23:31:42 itojun Exp +.\" KAME Id: rtadvd.conf.5,v 1.2 2000/02/08 05:19:36 itojun Exp .\" .Dd May 17, 1998 .Dt RTADVD.CONF 5 diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h index 1a6d6b2e0ae..ae427599129 100644 --- a/usr.sbin/rtadvd/rtadvd.h +++ b/usr.sbin/rtadvd/rtadvd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtadvd.h,v 1.2 1999/12/11 10:33:29 itojun Exp $ */ +/* $OpenBSD: rtadvd.h,v 1.3 2000/03/13 06:16:11 itojun Exp $ */ /* * Copyright (C) 1998 WIDE Project. @@ -43,12 +43,21 @@ #define DEF_ADVVALIDLIFETIME 2592000 #define DEF_ADVPREFERREDLIFETIME 604800 +/*XXX int-to-double comparison for INTERVAL items */ +#ifndef MIP6 +#define mobileip6 0 +#endif + #define MAXROUTERLIFETIME 9000 -#define MIN_MAXINTERVAL 4 +#define MIN_MAXINTERVAL (mobileip6 ? 1.5 : 4.0) #define MAX_MAXINTERVAL 1800 -#define MIN_MININTERVAL 3 +#define MIN_MININTERVAL (mobileip6 ? 0.5 : 3) #define MAXREACHABLETIME 3600000 +#ifndef MIP6 +#undef miobileip6 +#endif + #define MAX_INITIAL_RTR_ADVERT_INTERVAL 16 #define MAX_INITIAL_RTR_ADVERTISEMENTS 3 #define MAX_FINAL_RTR_ADVERTISEMENTS 3 @@ -63,6 +72,9 @@ struct prefix { u_int32_t preflifetime; /* AdvPreferredLifetime */ u_int onlinkflg; /* bool: AdvOnLinkFlag */ u_int autoconfflg; /* bool: AdvAutonomousFlag */ +#ifdef MIP6 + u_int routeraddr; /* bool: RouterAddress */ +#endif int prefixlen; struct in6_addr prefix; }; @@ -90,6 +102,9 @@ struct rainfo { u_int mininterval; /* MinRtrAdvInterval */ int managedflg; /* AdvManagedFlag */ int otherflg; /* AdvOtherConfigFlag */ +#ifdef MIP6 + int haflg; /* HAFlag */ +#endif u_int32_t linkmtu; /* AdvLinkMTU */ u_int32_t reachabletime; /* AdvReachableTime */ u_int32_t retranstimer; /* AdvRetransTimer */ @@ -97,6 +112,11 @@ struct rainfo { struct prefix prefix; /* AdvPrefixList(link head) */ int pfxs; /* number of prefixes */ +#ifdef MIP6 + u_short hapref; /* Home Agent Preference */ + u_short hatime; /* Home Agent Lifetime */ +#endif + /* actual RA packet data and its length */ size_t ra_datalen; u_char *ra_data; @@ -104,3 +124,7 @@ struct rainfo { void ra_timeout __P((void *)); void ra_timer_update __P((void *, struct timeval *)); + +#ifdef MIP6 +extern int mobileip6; +#endif -- 2.20.1