bring in latest rtadvd source from kame.
authoritojun <itojun@openbsd.org>
Mon, 13 Mar 2000 06:16:11 +0000 (06:16 +0000)
committeritojun <itojun@openbsd.org>
Mon, 13 Mar 2000 06:16:11 +0000 (06:16 +0000)
this fixes unclosed file descriptor in router renumbering case.

usr.sbin/rtadvd/config.c
usr.sbin/rtadvd/if.c
usr.sbin/rtadvd/rrenum.c
usr.sbin/rtadvd/rtadvd.8
usr.sbin/rtadvd/rtadvd.c
usr.sbin/rtadvd/rtadvd.conf.5
usr.sbin/rtadvd/rtadvd.h

index 7fa3098..b304276 100644 (file)
@@ -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 <netinet/ip6.h>
 #include <netinet6/ip6_var.h>
 #include <netinet/icmp6.h>
+#ifdef MIP6
+#include <netinet6/mip6.h>
+#endif
 
 #include <arpa/inet.h>
 
@@ -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);
index 1485e3d..6740ea6 100644 (file)
@@ -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 */
index 38d5999..5c20c93 100644 (file)
@@ -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);
index b220bb9..1c86af4 100644 (file)
@@ -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
index e00eaa9..8238432 100644 (file)
@@ -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 <time.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <err.h>
 #include <errno.h>
 #include <string.h>
 #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;
 }
index 7768620..f176e33 100644 (file)
@@ -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
index 1a6d6b2..ae42759 100644 (file)
@@ -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.
 #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