summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2011-06-16 12:41:37 +0000
committerhrs <hrs@FreeBSD.org>2011-06-16 12:41:37 +0000
commit941fea0834d05ab32f6422648f2ce94a76e13a48 (patch)
treed25763e4257e6353015b15e059406201097d086b /usr.sbin
parent7afd303ca9e45353e1af220a988ddac723fde355 (diff)
downloadFreeBSD-src-941fea0834d05ab32f6422648f2ce94a76e13a48.zip
FreeBSD-src-941fea0834d05ab32f6422648f2ce94a76e13a48.tar.gz
- Add ":origin" label to the interface id for resolvconf(8).
- Add -u option to enable adding :[RA-source-address] to the interface id. - s/INET6_ADDRSTRLEN/sizeof(ntopbuf)/ - Fix a bug that can prevent -D from being overridden by -d. - /-P pidfile/-p pidfile/ for consistency with rtadvd(8). - Fix WARNS. Discussed with: ume
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/rtsold/Makefile2
-rw-r--r--usr.sbin/rtsold/rtsol.c133
-rw-r--r--usr.sbin/rtsold/rtsold.828
-rw-r--r--usr.sbin/rtsold/rtsold.c25
-rw-r--r--usr.sbin/rtsold/rtsold.h6
5 files changed, 139 insertions, 55 deletions
diff --git a/usr.sbin/rtsold/Makefile b/usr.sbin/rtsold/Makefile
index 9e2b480..efc322c 100644
--- a/usr.sbin/rtsold/Makefile
+++ b/usr.sbin/rtsold/Makefile
@@ -19,7 +19,7 @@ MAN= rtsold.8
MLINKS= rtsold.8 rtsol.8
SRCS= rtsold.c rtsol.c if.c probe.c dump.c rtsock.c
-WARNS?= 6
+WARNS?= 3
CFLAGS+= -DHAVE_ARC4RANDOM -DHAVE_POLL_H
DPADD= ${LIBKVM}
LDADD= -lkvm
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index 13845f3..850e5d9 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -73,6 +73,7 @@ static struct sockaddr_in6 from;
static int rcvcmsglen;
int rssock;
+static char rsid[IFNAMSIZ + 1 + sizeof(DNSINFO_ORIGIN_LABEL) + 1 + NI_MAXHOST];
struct ifinfo_head_t ifinfo_head =
TAILQ_HEAD_INITIALIZER(ifinfo_head);
@@ -82,14 +83,18 @@ static const struct sockaddr_in6 sin6_allrouters = {
.sin6_addr = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT,
};
-static void call_script(const int, const char *const *, void *);
+static void call_script(const int, const char *const *,
+ struct script_msg_head_t *);
static size_t dname_labeldec(char *, size_t, const char *);
static int safefile(const char *);
static struct ra_opt *find_raopt(struct rainfo *, int, void *, size_t);
+static int ra_opt_rdnss_dispatch(struct ifinfo *, struct rainfo *,
+ struct script_msg_head_t *, struct script_msg_head_t *);
+static char *make_rsid(const char *, const char *, struct rainfo *);
#define _ARGS_OTHER otherconf_script, ifi->ifname
-#define _ARGS_RESADD resolvconf_script, "-a", ifi->ifname
-#define _ARGS_RESDEL resolvconf_script, "-d", ifi->ifname
+#define _ARGS_RESADD resolvconf_script, "-a", rsid
+#define _ARGS_RESDEL resolvconf_script, "-d", rsid
#define CALL_SCRIPT(name, sm_head) \
do { \
@@ -306,7 +311,7 @@ rtsol_input(int s)
warnmsg(LOG_ERR, __func__,
"invalid icmp type(%d) from %s on %s", icp->icmp6_type,
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
- INET6_ADDRSTRLEN),
+ sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
@@ -315,7 +320,7 @@ rtsol_input(int s)
warnmsg(LOG_INFO, __func__,
"invalid icmp code(%d) from %s on %s", icp->icmp6_code,
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
- INET6_ADDRSTRLEN),
+ sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
@@ -325,7 +330,7 @@ rtsol_input(int s)
"invalid RA with hop limit(%d) from %s on %s",
*hlimp,
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
- INET6_ADDRSTRLEN),
+ sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
@@ -334,7 +339,7 @@ rtsol_input(int s)
warnmsg(LOG_INFO, __func__,
"invalid RA with non link-local source from %s on %s",
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
- INET6_ADDRSTRLEN),
+ sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
@@ -345,14 +350,14 @@ rtsol_input(int s)
warnmsg(LOG_INFO, __func__,
"received RA from %s on an unexpected IF(%s)",
inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf,
- INET6_ADDRSTRLEN),
+ sizeof(ntopbuf)),
if_indextoname(pi->ipi6_ifindex, ifnamebuf));
return;
}
warnmsg(LOG_DEBUG, __func__,
"received RA from %s on %s, state is %d",
- inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, INET6_ADDRSTRLEN),
+ inet_ntop(AF_INET6, &from.sin6_addr, ntopbuf, sizeof(ntopbuf)),
ifi->ifname, ifi->state);
nd_ra = (struct nd_router_advert *)icp;
@@ -378,6 +383,8 @@ rtsol_input(int s)
ELM_MALLOC(rai, exit(1));
rai->rai_ifinfo = ifi;
TAILQ_INIT(&rai->rai_ra_opt);
+ rai->rai_saddr.sin6_family = AF_INET6;
+ rai->rai_saddr.sin6_len = sizeof(rai->rai_saddr);
memcpy(&rai->rai_saddr.sin6_addr, &from.sin6_addr,
sizeof(rai->rai_saddr.sin6_addr));
newent_rai = 1;
@@ -406,19 +413,19 @@ rtsol_input(int s)
"too short RDNSS option"
"in RA from %s was ignored.",
inet_ntop(AF_INET6, &from.sin6_addr,
- ntopbuf, INET6_ADDRSTRLEN));
+ ntopbuf, sizeof(ntopbuf)));
break;
}
addr = (struct in6_addr *)(raoptp + sizeof(*rdnss));
while ((char *)addr < (char *)RA_OPT_NEXT_HDR(raoptp)) {
if (inet_ntop(AF_INET6, addr, ntopbuf,
- INET6_ADDRSTRLEN) == NULL) {
+ sizeof(ntopbuf)) == NULL) {
warnmsg(LOG_INFO, __func__,
"an invalid address in RDNSS option"
" in RA from %s was ignored.",
inet_ntop(AF_INET6, &from.sin6_addr,
- ntopbuf, INET6_ADDRSTRLEN));
+ ntopbuf, sizeof(ntopbuf)));
addr++;
continue;
}
@@ -482,7 +489,7 @@ rtsol_input(int s)
"too short DNSSL option"
"in RA from %s was ignored.",
inet_ntop(AF_INET6, &from.sin6_addr,
- ntopbuf, INET6_ADDRSTRLEN));
+ ntopbuf, sizeof(ntopbuf)));
break;
}
@@ -568,10 +575,11 @@ ra_opt_handler(struct ifinfo *ifi)
struct rainfo *rai;
struct script_msg *smp1, *smp2, *smp3;
struct timeval now;
- TAILQ_HEAD(, script_msg) sm_rdnss_head =
- TAILQ_HEAD_INITIALIZER(sm_rdnss_head);
- TAILQ_HEAD(, script_msg) sm_dnssl_head =
- TAILQ_HEAD_INITIALIZER(sm_dnssl_head);
+ struct script_msg_head_t sm_rdnss_head =
+ TAILQ_HEAD_INITIALIZER(sm_rdnss_head);
+ struct script_msg_head_t sm_dnssl_head =
+ TAILQ_HEAD_INITIALIZER(sm_dnssl_head);
+
int dcount, dlen;
dcount = 0;
@@ -658,17 +666,69 @@ free2:
free1:
free(smp1);
}
- }
+ /* Call the script for each information source. */
+ if (uflag)
+ ra_opt_rdnss_dispatch(ifi, rai, &sm_rdnss_head,
+ &sm_dnssl_head);
+ }
+ /* Call the script for each interface. */
+ if (!uflag)
+ ra_opt_rdnss_dispatch(ifi, NULL, &sm_rdnss_head,
+ &sm_dnssl_head);
+ return (0);
+}
+
+char *
+make_rsid(const char *ifname, const char *origin, struct rainfo *rai)
+{
+ char hbuf[NI_MAXHOST];
+
+ if (rai == NULL)
+ sprintf(rsid, "%s:%s", ifname, origin);
+ else {
+ if (!IN6_IS_ADDR_LINKLOCAL(&rai->rai_saddr.sin6_addr))
+ return (NULL);
+ if (getnameinfo((struct sockaddr *)&rai->rai_saddr,
+ rai->rai_saddr.sin6_len, hbuf, sizeof(hbuf), NULL, 0,
+ NI_NUMERICHOST) != 0)
+ return (NULL);
+ sprintf(rsid, "%s:%s:[%s]", ifname, origin, hbuf);
+ }
+ warnmsg(LOG_DEBUG, __func__, "rsid = [%s]", rsid);
+ return (rsid);
+}
+
+int
+ra_opt_rdnss_dispatch(struct ifinfo *ifi,
+ struct rainfo *rai,
+ struct script_msg_head_t *sm_rdnss_head,
+ struct script_msg_head_t *sm_dnssl_head)
+{
+ const char *r;
+ struct script_msg *smp1;
+ int error;
+
+ error = 0;
/* Add \n for DNSSL list. */
- if (!TAILQ_EMPTY(&sm_dnssl_head)) {
- ELM_MALLOC(smp1, goto ra_opt_handler_freeit);
+ if (!TAILQ_EMPTY(sm_dnssl_head)) {
+ ELM_MALLOC(smp1, goto ra_opt_rdnss_freeit);
smp1->sm_msg = resstr_nl;
- TAILQ_INSERT_TAIL(&sm_dnssl_head, smp1, sm_next);
- }
- TAILQ_CONCAT(&sm_rdnss_head, &sm_dnssl_head, sm_next);
-
- if (!TAILQ_EMPTY(&sm_rdnss_head))
- CALL_SCRIPT(RESADD, &sm_rdnss_head);
+ TAILQ_INSERT_TAIL(sm_dnssl_head, smp1, sm_next);
+ }
+ TAILQ_CONCAT(sm_rdnss_head, sm_dnssl_head, sm_next);
+
+ if (rai != NULL && uflag)
+ r = make_rsid(ifi->ifname, DNSINFO_ORIGIN_LABEL, rai);
+ else
+ r = make_rsid(ifi->ifname, DNSINFO_ORIGIN_LABEL, NULL);
+ if (r == NULL) {
+ warnmsg(LOG_ERR, __func__, "make_rsid() failed. "
+ "Script was not invoked.");
+ error = 1;
+ goto ra_opt_rdnss_freeit;
+ }
+ if (!TAILQ_EMPTY(sm_rdnss_head))
+ CALL_SCRIPT(RESADD, sm_rdnss_head);
else if (ifi->ifi_rdnss == IFI_DNSOPT_STATE_RECEIVED ||
ifi->ifi_dnssl == IFI_DNSOPT_STATE_RECEIVED) {
CALL_SCRIPT(RESDEL, NULL);
@@ -676,21 +736,21 @@ free1:
ifi->ifi_dnssl = IFI_DNSOPT_STATE_NOINFO;
}
-ra_opt_handler_freeit:
+ra_opt_rdnss_freeit:
/* Clear script message queue. */
- if (!TAILQ_EMPTY(&sm_rdnss_head)) {
- while ((smp1 = TAILQ_FIRST(&sm_rdnss_head)) != NULL) {
- TAILQ_REMOVE(&sm_rdnss_head, smp1, sm_next);
+ if (!TAILQ_EMPTY(sm_rdnss_head)) {
+ while ((smp1 = TAILQ_FIRST(sm_rdnss_head)) != NULL) {
+ TAILQ_REMOVE(sm_rdnss_head, smp1, sm_next);
free(smp1);
}
}
- if (!TAILQ_EMPTY(&sm_dnssl_head)) {
- while ((smp1 = TAILQ_FIRST(&sm_dnssl_head)) != NULL) {
- TAILQ_REMOVE(&sm_dnssl_head, smp1, sm_next);
+ if (!TAILQ_EMPTY(sm_dnssl_head)) {
+ while ((smp1 = TAILQ_FIRST(sm_dnssl_head)) != NULL) {
+ TAILQ_REMOVE(sm_dnssl_head, smp1, sm_next);
free(smp1);
}
}
- return (0);
+ return (error);
}
static struct ra_opt *
@@ -709,19 +769,18 @@ find_raopt(struct rainfo *rai, int type, void *msg, size_t len)
}
static void
-call_script(const int argc, const char *const argv[], void *head)
+call_script(const int argc, const char *const argv[],
+ struct script_msg_head_t *sm_head)
{
const char *scriptpath;
int fd[2];
int error;
pid_t pid, wpid;
- TAILQ_HEAD(, script_msg) *sm_head;
if ((scriptpath = argv[0]) == NULL)
return;
fd[0] = fd[1] = -1;
- sm_head = head;
if (sm_head != NULL && !TAILQ_EMPTY(sm_head)) {
error = pipe(fd);
if (error) {
diff --git a/usr.sbin/rtsold/rtsold.8 b/usr.sbin/rtsold/rtsold.8
index 8eb2539..97b6000 100644
--- a/usr.sbin/rtsold/rtsold.8
+++ b/usr.sbin/rtsold/rtsold.8
@@ -29,7 +29,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd May 28, 2011
+.Dd June 14, 2011
.Dt RTSOLD 8
.Os
.\"
@@ -39,24 +39,24 @@
.\"
.Sh SYNOPSIS
.Nm
-.Op Fl dDfFm1
+.Op Fl dDfFmu1
.Op Fl O Ar script-name
-.Op Fl P Ar pidfile
+.Op Fl p Ar pidfile
.Op Fl R Ar script-name
.Ar interface ...
.Nm
-.Op Fl dDfFm1
+.Op Fl dDfFmu1
.Op Fl O Ar script-name
-.Op Fl P Ar pidfile
+.Op Fl p Ar pidfile
.Op Fl R Ar script-name
.Fl a
.Nm rtsol
-.Op Fl dD
+.Op Fl dDu
.Op Fl O Ar script-name
.Op Fl R Ar script-name
.Ar interface ...
.Nm rtsol
-.Op Fl dD
+.Op Fl dDu
.Op Fl O Ar script-name
.Op Fl R Ar script-name
.Fl a
@@ -227,7 +227,7 @@ configuration.
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 .
-.It Fl P Ar pidfile
+.It Fl p Ar pidfile
Writes the process ID of
.Nm
to
@@ -245,6 +245,18 @@ standard input of this script.
The
.Xr resolvconf 8
script is used by default.
+.It Fl u
+Specifies whether adding the source address of Router Advertisement
+messages to the interface name in an argument of the RDNSS and DNSSL
+script.
+.Pp
+If
+.Fl u
+is specified, the interface name in the script argument will be
+.Ql ifname:slaac:[RA-source-address] .
+.Pp
+If not, it will be
+.Ql ifname:slaac .
.El
.Sh FILES
.Bl -tag -width /var/run/rtsold.dump -compact
diff --git a/usr.sbin/rtsold/rtsold.c b/usr.sbin/rtsold/rtsold.c
index 73c027f..ee87753 100644
--- a/usr.sbin/rtsold/rtsold.c
+++ b/usr.sbin/rtsold/rtsold.c
@@ -75,6 +75,7 @@ static int fflag = 0;
int Fflag = 0; /* force setting sysctl parameters */
int aflag = 0;
int dflag = 0;
+int uflag = 0;
const char *otherconf_script;
const char *resolvconf_script = "/sbin/resolvconf";
@@ -129,10 +130,10 @@ main(int argc, char **argv)
#ifndef SMALL
/* rtsold */
- opts = "adDfFm1O:P:R:";
+ opts = "adDfFm1O:p:R:u";
#else
/* rtsol */
- opts = "adDFO:P:R:";
+ opts = "adDFO:R:u";
fflag = 1;
once = 1;
#endif
@@ -144,10 +145,10 @@ main(int argc, char **argv)
aflag = 1;
break;
case 'd':
- dflag = 1;
+ dflag += 1;
break;
case 'D':
- dflag = 2;
+ dflag += 2;
break;
case 'f':
fflag = 1;
@@ -164,12 +165,15 @@ main(int argc, char **argv)
case 'O':
otherconf_script = optarg;
break;
- case 'P':
+ case 'p':
pidfilename = optarg;
break;
case 'R':
resolvconf_script = optarg;
break;
+ case 'u':
+ uflag = 1;
+ break;
default:
usage();
exit(1);
@@ -184,14 +188,19 @@ main(int argc, char **argv)
}
/* set log level */
- if (dflag == 0)
+ if (dflag > 1)
+ log_upto = LOG_DEBUG;
+ else if (dflag > 0)
+ log_upto = LOG_INFO;
+ else
log_upto = LOG_NOTICE;
+
if (!fflag) {
char *ident;
- ident = strrchr(argv[0], '/');
+ ident = strrchr(argv0, '/');
if (!ident)
- ident = argv[0];
+ ident = argv0;
else
ident++;
openlog(ident, LOG_NDELAY|LOG_PID, LOG_DAEMON);
diff --git a/usr.sbin/rtsold/rtsold.h b/usr.sbin/rtsold/rtsold.h
index 0aa9b4f..3ab010f 100644
--- a/usr.sbin/rtsold/rtsold.h
+++ b/usr.sbin/rtsold/rtsold.h
@@ -37,6 +37,8 @@ struct script_msg {
char *sm_msg;
};
+TAILQ_HEAD(script_msg_head_t, script_msg);
+
struct ra_opt {
TAILQ_ENTRY(ra_opt) rao_next;
@@ -60,7 +62,7 @@ struct ifinfo {
TAILQ_ENTRY(ifinfo) ifi_next; /* pointer to the next interface */
struct sockaddr_dl *sdl; /* link-layer address */
- char ifname[IF_NAMESIZE]; /* interface name */
+ char ifname[IFNAMSIZ]; /* interface name */
u_int32_t linkid; /* link ID of this interface */
int active; /* interface status */
int probeinterval; /* interval of probe timer (if necessary) */
@@ -96,6 +98,7 @@ struct ifinfo {
/* Interface list */
extern TAILQ_HEAD(ifinfo_head_t, ifinfo) ifinfo_head;
+#define DNSINFO_ORIGIN_LABEL "slaac"
/*
* RFC 3542 API deprecates IPV6_PKTINFO in favor of
* IPV6_RECVPKTINFO
@@ -126,6 +129,7 @@ extern struct timeval tm_max;
extern int dflag;
extern int aflag;
extern int Fflag;
+extern int uflag;
extern const char *otherconf_script;
extern const char *resolvconf_script;
extern int ifconfig(char *);
OpenPOWER on IntegriCloud