summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtsold
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-08-08 16:42:37 +0000
committerume <ume@FreeBSD.org>2003-08-08 16:42:37 +0000
commit02ba92cc973152efd707c7e8e1c3b17091ddb26e (patch)
tree099a5ddb0139b1572c5cc2a9d1f4dc52af700a65 /usr.sbin/rtsold
parent52b4a696e076a7e2fb7dd05bd2f6feec997189cd (diff)
downloadFreeBSD-src-02ba92cc973152efd707c7e8e1c3b17091ddb26e.zip
FreeBSD-src-02ba92cc973152efd707c7e8e1c3b17091ddb26e.tar.gz
Process the "O bit."
If the value of OtherConfigFlag changes from FALSE to TRUE, the host should invoke the stateful autoconfiguration protocol, requesting information. [RFC 2462 Section 5.5.3] Obtained from: KAME MFC after: 1 week
Diffstat (limited to 'usr.sbin/rtsold')
-rw-r--r--usr.sbin/rtsold/dump.c2
-rw-r--r--usr.sbin/rtsold/rtsol.c127
-rw-r--r--usr.sbin/rtsold/rtsold.833
-rw-r--r--usr.sbin/rtsold/rtsold.c20
-rw-r--r--usr.sbin/rtsold/rtsold.h3
5 files changed, 183 insertions, 2 deletions
diff --git a/usr.sbin/rtsold/dump.c b/usr.sbin/rtsold/dump.c
index 7915d92..56f8afc 100644
--- a/usr.sbin/rtsold/dump.c
+++ b/usr.sbin/rtsold/dump.c
@@ -76,6 +76,8 @@ dump_interface_status()
}
fprintf(fp, " interface status: %s\n",
ifinfo->active > 0 ? "active" : "inactive");
+ fprintf(fp, " other config: %s\n",
+ ifinfo->otherconfig ? "on" : "off");
fprintf(fp, " rtsold status: %s\n", ifstatstr[ifinfo->state]);
fprintf(fp, " carrier detection: %s\n",
ifinfo->mediareqok ? "available" : "unavailable");
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index 0543bca..923628d 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -35,7 +35,10 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/time.h>
+#include <fcntl.h>
#include <sys/queue.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
#include <net/if.h>
#include <net/route.h>
@@ -70,6 +73,9 @@ int rssock;
static struct sockaddr_in6 sin6_allrouters = {sizeof(sin6_allrouters), AF_INET6};
+static void call_script __P((char *, char *));
+static int safefile __P((const char *));
+
int
sockopen()
{
@@ -233,6 +239,7 @@ rtsol_input(int s)
struct cmsghdr *cm;
struct in6_pktinfo *pi = NULL;
struct ifinfo *ifi = NULL;
+ struct nd_router_advert *nd_ra;
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
/* get message */
@@ -330,6 +337,23 @@ rtsol_input(int s)
INET6_ADDRSTRLEN),
ifi->ifname, ifi->state);
+ nd_ra = (struct nd_router_advert *)icp;
+
+ /*
+ * Process the "O bit."
+ * If the value of OtherConfigFlag changes from FALSE to TRUE, the
+ * host should invoke the stateful autoconfiguration protocol,
+ * requesting information.
+ * [RFC 2462 Section 5.5.3]
+ */
+ if (((nd_ra->nd_ra_flags_reserved) & ND_RA_FLAG_OTHER) &&
+ !ifi->otherconfig) {
+ warnmsg(LOG_DEBUG, __func__,
+ "OtherConfigFlag on %s is turned on", ifi->ifname);
+ ifi->otherconfig = 1;
+ call_script(otherconf_script, ifi->ifname);
+ }
+
ifi->racnt++;
switch(ifi->state) {
@@ -343,3 +367,106 @@ rtsol_input(int s)
break;
}
}
+
+static void
+call_script(scriptpath, ifname)
+ char *scriptpath, *ifname;
+{
+ pid_t pid, wpid;
+
+ if (scriptpath == NULL)
+ return;
+
+ /* launch the script */
+ pid = fork();
+ if (pid < 0) {
+ warnmsg(LOG_ERR, __func__,
+ "failed to fork: %s", strerror(errno));
+ return;
+ } else if (pid) {
+ int wstatus;
+
+ do {
+ wpid = wait(&wstatus);
+ } while (wpid != pid && wpid > 0);
+
+ if (wpid < 0)
+ warnmsg(LOG_ERR, __func__,
+ "wait: %s", strerror(errno));
+ else {
+ warnmsg(LOG_DEBUG, __func__,
+ "script \"%s\" terminated", scriptpath);
+ }
+ } else {
+ char *argv[3];
+ int fd;
+
+ argv[0] = scriptpath;
+ argv[1] = ifname;
+ argv[2] = NULL;
+
+ if (safefile(scriptpath)) {
+ warnmsg(LOG_ERR, __func__,
+ "script \"%s\" cannot be executed safely",
+ scriptpath);
+ exit(1);
+ }
+
+ if ((fd = open("/dev/null", O_RDWR)) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ close(fd);
+ }
+
+ execv(scriptpath, argv);
+
+ warnmsg(LOG_ERR, __func__, "child: exec failed: %s",
+ strerror(errno));
+ exit(0);
+ }
+
+ return;
+}
+
+static int
+safefile(path)
+ const char *path;
+{
+ struct stat s;
+ uid_t myuid;
+
+ /* no setuid */
+ if (getuid() != geteuid()) {
+ warnmsg(LOG_NOTICE, __func__,
+ "setuid'ed execution not allowed\n");
+ return (-1);
+ }
+
+ if (lstat(path, &s) != 0) {
+ warnmsg(LOG_NOTICE, __func__, "lstat failed: %s",
+ strerror(errno));
+ return (-1);
+ }
+
+ /* the file must be owned by the running uid */
+ myuid = getuid();
+ if (s.st_uid != myuid) {
+ warnmsg(LOG_NOTICE, __func__,
+ "%s has invalid owner uid\n", path);
+ return (-1);
+ }
+
+ switch (s.st_mode & S_IFMT) {
+ case S_IFREG:
+ break;
+ default:
+ warnmsg(LOG_NOTICE, __func__,
+ "%s is an invalid file type 0x%o\n",
+ path, (s.st_mode & S_IFMT));
+ return (-1);
+ }
+
+ return (0);
+}
diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index e72bb6a..a365637 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -40,15 +40,19 @@
.Sh SYNOPSIS
.Nm
.Op Fl dDfm1
+.Op Fl O Ar script-name
.Ar interface ...
.Nm
.Op Fl dDfm1
+.Op Fl O Ar script-name
.Fl a
.Nm rtsol
.Op Fl dD
+.Op Fl O Ar script-name
.Ar interface ...
.Nm rtsol
.Op Fl dD
+.Op Fl O Ar script-name
.Fl a
.\"
.Sh DESCRIPTION
@@ -128,6 +132,21 @@ When sending a Router Solicitation on an interface,
.Nm
includes a Source Link-layer address option if the interface
has a link-layer address.
+.Lp
+.Nm
+manages a per-interface parameter to detect if a separate protocol is
+needed for configuration parameters other than host's addresses.
+At the invocation time, the flag is FALSE, and becomes TRUE when
+the daemon receives a router advertisement with the OtherConfig flag
+being set.
+A script file can be specified to deal with the case
+.Pq see below .
+When
+.Nm
+start resending router solicitation messages by one of the conditions
+events,
+the daemon resets the parameter because the event may indicate a
+change on the attached link.
.Pp
Upon receipt of signal
.Dv SIGUSR1 ,
@@ -178,6 +197,20 @@ Transmit Router Solicitation packets until at least one valid Router
Advertisement packet has arrived on each
.Ar interface ,
then exit.
+.It Fl O Ar script-name
+Specifies a supplement script file to handle the Other Configuration
+flag of the router advertisement.
+When the flag changes from FALSE to TRUE,
+.Nm
+will invoke
+.Ar script-name
+with a single argument of the receiving interface name,
+expecting the script will then start a protocol for the other
+configuration.
+.Ar script-name
+must be the absolute path from root to the script file, be a regular
+file, and be created by the same owner who runs
+.Nm .
.El
.Sh DIAGNOSTICS
.Ex -std rtsold rtsol
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index e3b9a61..55b1942 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -57,6 +57,7 @@ struct ifinfo *iflist;
struct timeval tm_max = {0x7fffffff, 0x7fffffff};
int aflag = 0;
int dflag = 0;
+char *otherconf_script;
static int log_upto = 999;
static int fflag = 0;
@@ -126,9 +127,9 @@ main(argc, argv)
if (argv0 && argv0[strlen(argv0) - 1] != 'd') {
fflag = 1;
once = 1;
- opts = "adD";
+ opts = "adDO:";
} else
- opts = "adDfm1";
+ opts = "adDfm1O:";
while ((ch = getopt(argc, argv, opts)) != -1) {
switch (ch) {
@@ -150,6 +151,9 @@ main(argc, argv)
case '1':
once = 1;
break;
+ case 'O':
+ otherconf_script = optarg;
+ break;
default:
usage(argv0);
/*NOTREACHED*/
@@ -196,6 +200,11 @@ main(argc, argv)
setlogmask(LOG_UPTO(log_upto));
}
+ if (otherconf_script && *otherconf_script != '/') {
+ errx(1, "configuration script (%s) must be an absolute path",
+ otherconf_script);
+ }
+
#ifndef HAVE_ARC4RANDOM
/* random value initilization */
srandom((u_long)time(NULL));
@@ -524,6 +533,13 @@ rtsol_check_timer()
ifinfo->state = IFS_PROBE;
}
+ /*
+ * If we need a probe, clear the previous
+ * status wrt the "other" configuration.
+ */
+ if (probe)
+ ifinfo->otherconfig = 0;
+
if (probe && mobile_node)
defrouter_probe(ifinfo->sdl->sdl_index);
break;
diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h
index 52175fa..c309b68 100644
--- a/usr.sbin/rtsold/rtsold.h
+++ b/usr.sbin/rtsold/rtsold.h
@@ -40,6 +40,8 @@ struct ifinfo {
int probeinterval; /* interval of probe timer(if necessary) */
int probetimer; /* rest of probe timer */
int mediareqok; /* wheter the IF supports SIOCGIFMEDIA */
+ int otherconfig; /* need a separate protocol for the "other"
+ * configuration */
int state;
int probes;
int dadcount;
@@ -63,6 +65,7 @@ struct ifinfo {
/* rtsold.c */
extern struct timeval tm_max;
extern int dflag;
+extern char *otherconf_script;
struct ifinfo *find_ifinfo __P((int ifindex));
void rtsol_timer_update __P((struct ifinfo *ifinfo));
extern void warnmsg __P((int, const char *, const char *, ...))
OpenPOWER on IntegriCloud