Submit #2841 ยป rtadvd-rtadvctl.diff
sys/netinet/icmp6.h | ||
---|---|---|
#define ND_OPT_MTU 5
|
||
#define ND_OPT_ROUTE_INFO 200 /* draft-ietf-ipngwg-router-preference, not officially assigned yet */
|
||
#define ND_OPT_RDNSS 25 /* RFC 6106 */
|
||
#define ND_OPT_DNSSL 31 /* RFC 6106 */
|
||
#define ND_OPT_MAX 31
|
||
struct nd_opt_prefix_info { /* prefix information */
|
||
u_int8_t nd_opt_pi_type;
|
||
... | ... | |
/* prefix follows */
|
||
} __attribute__((__packed__));
|
||
struct nd_opt_rdnss { /* RDNSS option (RFC 6106) */
|
||
u_int8_t nd_opt_rdnss_type;
|
||
u_int8_t nd_opt_rdnss_len;
|
||
u_int16_t nd_opt_rdnss_reserved;
|
||
u_int32_t nd_opt_rdnss_lifetime;
|
||
/* followed by list of recursive DNS servers */
|
||
} __attribute__((__packed__));
|
||
struct nd_opt_dnssl { /* DNSSL option (RFC 6106) */
|
||
u_int8_t nd_opt_dnssl_type;
|
||
u_int8_t nd_opt_dnssl_len;
|
||
u_int16_t nd_opt_dnssl_reserved;
|
||
u_int32_t nd_opt_dnssl_lifetime;
|
||
/* followed by list of DNS search domains */
|
||
} __attribute__((__packed__));
|
||
/*
|
||
* icmp6 namelookup
|
||
*/
|
usr.sbin/Makefile | ||
---|---|---|
rpcbind \
|
||
rrenumd \
|
||
rtadvd \
|
||
rtadvctl \
|
||
rtprio \
|
||
rtsold \
|
||
rwhod \
|
usr.sbin/rtadvctl/Makefile | ||
---|---|---|
# $FreeBSD: stable/10/usr.sbin/rtadvctl/Makefile 224144 2011-07-17 19:24:54Z hrs $
|
||
#
|
||
.PATH: ${.CURDIR}/../rtadvd
|
||
PROG= rtadvctl
|
||
MAN= rtadvctl.8
|
||
SRCS= rtadvctl.c control.c control_client.c if.c timer_subr.c
|
||
CFLAGS+= -I${.CURDIR} -I${.CURDIR}/../rtadvd
|
||
WARNS?= 1
|
||
.include <bsd.prog.mk>
|
usr.sbin/rtadvctl/rtadvctl.8 | ||
---|---|---|
.\" Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>.
|
||
.\" All rights reserved.
|
||
.\"
|
||
.\" Redistribution and use in source and binary forms, with or without
|
||
.\" modification, are permitted provided that the following conditions
|
||
.\" are met:
|
||
.\" 1. Redistributions of source code must retain the above copyright
|
||
.\" notice, this list of conditions and the following disclaimer.
|
||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||
.\" notice, this list of conditions and the following disclaimer in the
|
||
.\" documentation and/or other materials provided with the distribution.
|
||
.\"
|
||
.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS
|
||
.\" IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||
.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||
.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||
.\" PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||
.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||
.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||
.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
.\"
|
||
.\" $FreeBSD: stable/10/usr.sbin/rtadvctl/rtadvctl.8 235873 2012-05-24 02:24:03Z wblock $
|
||
.\"
|
||
.Dd July 16, 2011
|
||
.Dt RTADVCTL 8
|
||
.Os
|
||
.Sh NAME
|
||
.Nm rtadvctl
|
||
.Nd control program for
|
||
.Xr rtadvd 8
|
||
daemon
|
||
.Sh SYNOPSIS
|
||
.Nm
|
||
.Op Fl v
|
||
.Ar subcommand
|
||
.Op Ar interface ...
|
||
.Sh DESCRIPTION
|
||
.Nm
|
||
is a utility that communicates with
|
||
.Xr rtadvd 8
|
||
daemon and displays information about Router Advertisement messages being
|
||
sent on each interface.
|
||
.Pp
|
||
This utility provides several options and subcommands.
|
||
The options are as follows:
|
||
.Bl -tag -width indent
|
||
.\"
|
||
.It Fl v
|
||
Increase verbosity level.
|
||
When specified once, the
|
||
.Nm
|
||
utility shows additional information about prefixes, RDNSS, and DNSSL
|
||
options.
|
||
When given twice, it additionally shows information about
|
||
inactive interfaces and some statistics.
|
||
.El
|
||
.Pp
|
||
The subcommands are as follows:
|
||
.Bl -tag -width indent
|
||
.\"
|
||
.It reload Op interfaces...
|
||
Specifies to reload the configuration file. If one or more
|
||
.Ar interface
|
||
is specified, configuration entries for the interfaces will be reloaded
|
||
selectively.
|
||
.It enable interfaces...
|
||
Specifies to mark the interface as enable and to try to reload the
|
||
configuration entry.
|
||
This subcommand is useful for dynamically-added interfaces.
|
||
.Pp
|
||
The
|
||
.Xr rtadvd 8
|
||
daemon marks an interface as enable if the interface exists and the
|
||
configuration file has a valid entry for that when it is invoked.
|
||
.It disable interfaces...
|
||
Specifies to mark the interface as disable.
|
||
.It shutdown
|
||
Makes the
|
||
.Xr rtadvd 8
|
||
daemon shut down.
|
||
Note that the
|
||
.Xr rtadvd 8
|
||
daemon will send several RAs with zero lifetime to invalidate the old
|
||
information on each interface.
|
||
It will take at most nine seconds.
|
||
.It show Op interfaces...
|
||
Displays information on Router Advertisement messages being sent
|
||
on each interface.
|
||
.El
|
||
.Sh SEE ALSO
|
||
.Xr rtadvd 8 ,
|
||
.Xr rtadvd.conf 5
|
||
.Sh HISTORY
|
||
The
|
||
.Nm
|
||
command first appeared in
|
||
.Fx 9.0 .
|
||
.Sh AUTHORS
|
||
.Nm
|
||
was written by
|
||
.An "Hiroki Sato" Aq hrs@FreeBSD.org .
|
usr.sbin/rtadvctl/rtadvctl.c | ||
---|---|---|
/*-
|
||
* Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
|
||
* All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
* 1. Redistributions of source code must retain the above copyright
|
||
* notice, this list of conditions and the following disclaimer.
|
||
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
|
||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
*
|
||
* $FreeBSD: stable/10/usr.sbin/rtadvctl/rtadvctl.c 253970 2013-08-05 20:13:02Z hrs $
|
||
*
|
||
*/
|
||
#include <sys/queue.h>
|
||
#include <sys/types.h>
|
||
#include <sys/socket.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/un.h>
|
||
#include <sys/uio.h>
|
||
#include <net/if.h>
|
||
#include <net/if_dl.h>
|
||
#include <net/if_types.h>
|
||
#include <net/if_var.h>
|
||
#include <net/ethernet.h>
|
||
#include <netinet/in.h>
|
||
#include <netinet/ip6.h>
|
||
#include <netinet/icmp6.h>
|
||
#include <netinet6/in6_var.h>
|
||
#include <netinet6/nd6.h>
|
||
#include <arpa/inet.h>
|
||
#include <fcntl.h>
|
||
#include <errno.h>
|
||
#include <inttypes.h>
|
||
#include <netdb.h>
|
||
#include <unistd.h>
|
||
#include <string.h>
|
||
#include <stdarg.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <stdarg.h>
|
||
#include <syslog.h>
|
||
#include <time.h>
|
||
#include <err.h>
|
||
#include "pathnames.h"
|
||
#include "rtadvd.h"
|
||
#include "if.h"
|
||
#include "timer_subr.h"
|
||
#include "timer.h"
|
||
#include "control.h"
|
||
#include "control_client.h"
|
||
#define RA_IFSTATUS_INACTIVE 0
|
||
#define RA_IFSTATUS_RA_RECV 1
|
||
#define RA_IFSTATUS_RA_SEND 2
|
||
static int vflag = LOG_ERR;
|
||
static void usage(void);
|
||
static int action_propset(char *);
|
||
static int action_propget(char *, struct ctrl_msg_pl *);
|
||
static int action_plgeneric(int, char *, char *);
|
||
static int action_enable(int, char **);
|
||
static int action_disable(int, char **);
|
||
static int action_reload(int, char **);
|
||
static int action_echo(int, char **);
|
||
static int action_version(int, char **);
|
||
static int action_shutdown(int, char **);
|
||
static int action_show(int, char **);
|
||
static int action_show_prefix(struct prefix *);
|
||
static int action_show_rtinfo(struct rtinfo *);
|
||
static int action_show_rdnss(void *);
|
||
static int action_show_dnssl(void *);
|
||
static int csock_client_open(struct sockinfo *);
|
||
static size_t dname_labeldec(char *, size_t, const char *);
|
||
static void mysyslog(int, const char *, ...);
|
||
static const char *rtpref_str[] = {
|
||
"medium", /* 00 */
|
||
"high", /* 01 */
|
||
"rsv", /* 10 */
|
||
"low" /* 11 */
|
||
};
|
||
static struct dispatch_table {
|
||
const char *dt_comm;
|
||
int (*dt_act)(int, char **);
|
||
} dtable[] = {
|
||
{ "show", action_show },
|
||
{ "reload", action_reload },
|
||
{ "shutdown", action_shutdown },
|
||
{ "enable", action_enable },
|
||
{ "disable", action_disable },
|
||
{ NULL, NULL },
|
||
{ "echo", action_echo },
|
||
{ "version", action_version },
|
||
{ NULL, NULL },
|
||
};
|
||
static char errmsgbuf[1024];
|
||
static char *errmsg = NULL;
|
||
static void
|
||
mysyslog(int priority, const char * restrict fmt, ...)
|
||
{
|
||
va_list ap;
|
||
if (vflag >= priority) {
|
||
va_start(ap, fmt);
|
||
vfprintf(stderr, fmt, ap);
|
||
fprintf(stderr, "\n");
|
||
va_end(ap);
|
||
}
|
||
}
|
||
static void
|
||
usage(void)
|
||
{
|
||
int i;
|
||
for (i = 0; (size_t)i < sizeof(dtable)/sizeof(dtable[0]); i++) {
|
||
if (dtable[i].dt_comm == NULL)
|
||
break;
|
||
printf("%s\n", dtable[i].dt_comm);
|
||
}
|
||
exit(1);
|
||
}
|
||
int
|
||
main(int argc, char *argv[])
|
||
{
|
||
int i;
|
||
int ch;
|
||
int (*action)(int, char **) = NULL;
|
||
int error;
|
||
while ((ch = getopt(argc, argv, "Dv")) != -1) {
|
||
switch (ch) {
|
||
case 'D':
|
||
vflag = LOG_DEBUG;
|
||
break;
|
||
case 'v':
|
||
vflag++;
|
||
break;
|
||
default:
|
||
usage();
|
||
}
|
||
}
|
||
argc -= optind;
|
||
argv += optind;
|
||
if (argc == 0)
|
||
usage();
|
||
for (i = 0; (size_t)i < sizeof(dtable)/sizeof(dtable[0]); i++) {
|
||
if (dtable[i].dt_comm == NULL ||
|
||
strcmp(dtable[i].dt_comm, argv[0]) == 0) {
|
||
action = dtable[i].dt_act;
|
||
break;
|
||
}
|
||
}
|
||
if (action == NULL)
|
||
usage();
|
||
error = (dtable[i].dt_act)(--argc, ++argv);
|
||
if (error) {
|
||
fprintf(stderr, "%s failed", dtable[i].dt_comm);
|
||
if (errmsg != NULL)
|
||
fprintf(stderr, ": %s", errmsg);
|
||
fprintf(stderr, ".\n");
|
||
}
|
||
return (error);
|
||
}
|
||
static int
|
||
csock_client_open(struct sockinfo *s)
|
||
{
|
||
struct sockaddr_un sun;
|
||
if ((s->si_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
|
||
err(1, "cannot open control socket.");
|
||
memset(&sun, 0, sizeof(sun));
|
||
sun.sun_family = AF_UNIX;
|
||
sun.sun_len = sizeof(sun);
|
||
strlcpy(sun.sun_path, s->si_name, sizeof(sun.sun_path));
|
||
if (connect(s->si_fd, (struct sockaddr *)&sun, sizeof(sun)) == -1)
|
||
err(1, "connect: %s", s->si_name);
|
||
mysyslog(LOG_DEBUG,
|
||
"<%s> connected to %s", __func__, sun.sun_path);
|
||
return (0);
|
||
}
|
||
static int
|
||
action_plgeneric(int action, char *plstr, char *buf)
|
||
{
|
||
struct ctrl_msg_hdr *cm;
|
||
struct ctrl_msg_pl cp;
|
||
struct sockinfo *s;
|
||
char *msg;
|
||
char *p;
|
||
char *q;
|
||
s = &ctrlsock;
|
||
csock_client_open(s);
|
||
cm = (struct ctrl_msg_hdr *)buf;
|
||
msg = (char *)buf + sizeof(*cm);
|
||
cm->cm_version = CM_VERSION;
|
||
cm->cm_type = action;
|
||
cm->cm_len = sizeof(*cm);
|
||
if (plstr != NULL) {
|
||
memset(&cp, 0, sizeof(cp));
|
||
p = strchr(plstr, ':');
|
||
q = strchr(plstr, '=');
|
||
if (p != NULL && q != NULL && p > q)
|
||
return (1);
|
||
if (p == NULL) { /* No : */
|
||
cp.cp_ifname = NULL;
|
||
cp.cp_key = plstr;
|
||
} else if (p == plstr) { /* empty */
|
||
cp.cp_ifname = NULL;
|
||
cp.cp_key = plstr + 1;
|
||
} else {
|
||
*p++ = '\0';
|
||
cp.cp_ifname = plstr;
|
||
cp.cp_key = p;
|
||
}
|
||
if (q == NULL)
|
||
cp.cp_val = NULL;
|
||
else {
|
||
*q++ = '\0';
|
||
cp.cp_val = q;
|
||
}
|
||
cm->cm_len += cm_pl2bin(msg, &cp);
|
||
mysyslog(LOG_DEBUG, "<%s> key=%s, val_len=%d, ifname=%s",
|
||
__func__,cp.cp_key, cp.cp_val_len, cp.cp_ifname);
|
||
}
|
||
return (cm_handler_client(s->si_fd, CM_STATE_MSG_DISPATCH, buf));
|
||
}
|
||
static int
|
||
action_propget(char *argv, struct ctrl_msg_pl *cp)
|
||
{
|
||
int error;
|
||
struct ctrl_msg_hdr *cm;
|
||
char buf[CM_MSG_MAXLEN];
|
||
char *msg;
|
||
memset(cp, 0, sizeof(*cp));
|
||
cm = (struct ctrl_msg_hdr *)buf;
|
||
msg = (char *)buf + sizeof(*cm);
|
||
error = action_plgeneric(CM_TYPE_REQ_GET_PROP, argv, buf);
|
||
if (error || cm->cm_len <= sizeof(*cm))
|
||
return (1);
|
||
cm_bin2pl(msg, cp);
|
||
mysyslog(LOG_DEBUG, "<%s> type=%d, len=%d",
|
||
__func__, cm->cm_type, cm->cm_len);
|
||
mysyslog(LOG_DEBUG, "<%s> key=%s, val_len=%d, ifname=%s",
|
||
__func__,cp->cp_key, cp->cp_val_len, cp->cp_ifname);
|
||
return (0);
|
||
}
|
||
static int
|
||
action_propset(char *argv)
|
||
{
|
||
char buf[CM_MSG_MAXLEN];
|
||
return (action_plgeneric(CM_TYPE_REQ_SET_PROP, argv, buf));
|
||
}
|
||
static int
|
||
action_disable(int argc, char **argv)
|
||
{
|
||
char *action_argv;
|
||
char argv_disable[IFNAMSIZ + sizeof(":disable=")];
|
||
int i;
|
||
int error;
|
||
if (argc < 1)
|
||
return (1);
|
||
error = 0;
|
||
for (i = 0; i < argc; i++) {
|
||
sprintf(argv_disable, "%s:disable=", argv[i]);
|
||
action_argv = argv_disable;
|
||
error += action_propset(action_argv);
|
||
}
|
||
return (error);
|
||
}
|
||
static int
|
||
action_enable(int argc, char **argv)
|
||
{
|
||
char *action_argv;
|
||
char argv_enable[IFNAMSIZ + sizeof(":enable=")];
|
||
int i;
|
||
int error;
|
||
if (argc < 1)
|
||
return (1);
|
||
error = 0;
|
||
for (i = 0; i < argc; i++) {
|
||
sprintf(argv_enable, "%s:enable=", argv[i]);
|
||
action_argv = argv_enable;
|
||
error += action_propset(action_argv);
|
||
}
|
||
return (error);
|
||
}
|
||
static int
|
||
action_reload(int argc, char **argv)
|
||
{
|
||
char *action_argv;
|
||
char argv_reload[IFNAMSIZ + sizeof(":reload=")];
|
||
int i;
|
||
int error;
|
||
if (argc == 0) {
|
||
action_argv = strdup(":reload=");
|
||
return (action_propset(action_argv));
|
||
}
|
||
error = 0;
|
||
for (i = 0; i < argc; i++) {
|
||
sprintf(argv_reload, "%s:reload=", argv[i]);
|
||
action_argv = argv_reload;
|
||
error += action_propset(action_argv);
|
||
}
|
||
return (error);
|
||
}
|
||
static int
|
||
action_echo(int argc __unused, char **argv __unused)
|
||
{
|
||
char *action_argv;
|
||
action_argv = strdup("echo");
|
||
return (action_propset(action_argv));
|
||
}
|
||
static int
|
||
action_shutdown(int argc __unused, char **argv __unused)
|
||
{
|
||
char *action_argv;
|
||
action_argv = strdup("shutdown");
|
||
return (action_propset(action_argv));
|
||
}
|
||
/* XXX */
|
||
static int
|
||
action_version(int argc __unused, char **argv __unused)
|
||
{
|
||
char *action_argv;
|
||
struct ctrl_msg_pl cp;
|
||
int error;
|
||
action_argv = strdup(":version=");
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
return (error);
|
||
printf("version=%s\n", cp.cp_val);
|
||
return (0);
|
||
}
|
||
static int
|
||
action_show(int argc, char **argv)
|
||
{
|
||
char *action_argv;
|
||
char argv_ifilist[sizeof(":ifilist=")] = ":ifilist=";
|
||
char argv_ifi[IFNAMSIZ + sizeof(":ifi=")];
|
||
char argv_rai[IFNAMSIZ + sizeof(":rai=")];
|
||
char argv_rti[IFNAMSIZ + sizeof(":rti=")];
|
||
char argv_pfx[IFNAMSIZ + sizeof(":pfx=")];
|
||
char argv_ifi_ra_timer[IFNAMSIZ + sizeof(":ifi_ra_timer=")];
|
||
char argv_rdnss[IFNAMSIZ + sizeof(":rdnss=")];
|
||
char argv_dnssl[IFNAMSIZ + sizeof(":dnssl=")];
|
||
char ssbuf[SSBUFLEN];
|
||
struct timespec now, ts0, ts;
|
||
struct ctrl_msg_pl cp;
|
||
struct ifinfo *ifi;
|
||
TAILQ_HEAD(, ifinfo) ifl = TAILQ_HEAD_INITIALIZER(ifl);
|
||
char *endp;
|
||
char *p;
|
||
int error;
|
||
int i;
|
||
int len;
|
||
if (argc == 0) {
|
||
action_argv = argv_ifilist;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
return (error);
|
||
p = cp.cp_val;
|
||
endp = p + cp.cp_val_len;
|
||
while (p < endp) {
|
||
ifi = malloc(sizeof(*ifi));
|
||
if (ifi == NULL)
|
||
return (1);
|
||
memset(ifi, 0, sizeof(*ifi));
|
||
strcpy(ifi->ifi_ifname, p);
|
||
ifi->ifi_ifindex = if_nametoindex(ifi->ifi_ifname);
|
||
TAILQ_INSERT_TAIL(&ifl, ifi, ifi_next);
|
||
p += strlen(ifi->ifi_ifname) + 1;
|
||
}
|
||
} else {
|
||
for (i = 0; i < argc; i++) {
|
||
ifi = malloc(sizeof(*ifi));
|
||
if (ifi == NULL)
|
||
return (1);
|
||
memset(ifi, 0, sizeof(*ifi));
|
||
strcpy(ifi->ifi_ifname, argv[i]);
|
||
ifi->ifi_ifindex = if_nametoindex(ifi->ifi_ifname);
|
||
if (ifi->ifi_ifindex == 0) {
|
||
sprintf(errmsgbuf, "invalid interface %s",
|
||
ifi->ifi_ifname);
|
||
errmsg = errmsgbuf;
|
||
return (1);
|
||
}
|
||
TAILQ_INSERT_TAIL(&ifl, ifi, ifi_next);
|
||
}
|
||
}
|
||
clock_gettime(CLOCK_REALTIME_FAST, &now);
|
||
clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
|
||
TS_SUB(&now, &ts, &ts0);
|
||
TAILQ_FOREACH(ifi, &ifl, ifi_next) {
|
||
struct ifinfo *ifi_s;
|
||
struct rtadvd_timer *rat;
|
||
struct rainfo *rai;
|
||
struct rtinfo *rti;
|
||
struct prefix *pfx;
|
||
int c;
|
||
int ra_ifstatus;
|
||
sprintf(argv_ifi, "%s:ifi=", ifi->ifi_ifname);
|
||
action_argv = argv_ifi;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
return (error);
|
||
ifi_s = (struct ifinfo *)cp.cp_val;
|
||
if (!(ifi_s->ifi_persist) && vflag < LOG_NOTICE)
|
||
continue;
|
||
printf("%s: flags=<", ifi->ifi_ifname);
|
||
c = 0;
|
||
if (ifi_s->ifi_ifindex == 0)
|
||
c += printf("NONEXISTENT");
|
||
else
|
||
c += printf("%s", (ifi_s->ifi_flags & IFF_UP) ?
|
||
"UP" : "DOWN");
|
||
switch (ifi_s->ifi_state) {
|
||
case IFI_STATE_CONFIGURED:
|
||
c += printf("%s%s", (c) ? "," : "", "CONFIGURED");
|
||
break;
|
||
case IFI_STATE_TRANSITIVE:
|
||
c += printf("%s%s", (c) ? "," : "", "TRANSITIVE");
|
||
break;
|
||
}
|
||
if (ifi_s->ifi_persist)
|
||
c += printf("%s%s", (c) ? "," : "", "PERSIST");
|
||
printf(">");
|
||
ra_ifstatus = RA_IFSTATUS_INACTIVE;
|
||
if ((ifi_s->ifi_flags & IFF_UP) &&
|
||
((ifi_s->ifi_state == IFI_STATE_CONFIGURED) ||
|
||
(ifi_s->ifi_state == IFI_STATE_TRANSITIVE))) {
|
||
#if (__FreeBSD_version < 900000)
|
||
/*
|
||
* RA_RECV: !ip6.forwarding && ip6.accept_rtadv
|
||
* RA_SEND: ip6.forwarding
|
||
*/
|
||
if (getinet6sysctl(IPV6CTL_FORWARDING) == 0) {
|
||
if (getinet6sysctl(IPV6CTL_ACCEPT_RTADV))
|
||
ra_ifstatus = RA_IFSTATUS_RA_RECV;
|
||
else
|
||
ra_ifstatus = RA_IFSTATUS_INACTIVE;
|
||
} else
|
||
ra_ifstatus = RA_IFSTATUS_RA_SEND;
|
||
#else
|
||
/*
|
||
* RA_RECV: ND6_IFF_ACCEPT_RTADV
|
||
* RA_SEND: ip6.forwarding
|
||
*/
|
||
if (ifi_s->ifi_nd_flags & ND6_IFF_ACCEPT_RTADV)
|
||
ra_ifstatus = RA_IFSTATUS_RA_RECV;
|
||
else if (getinet6sysctl(IPV6CTL_FORWARDING))
|
||
ra_ifstatus = RA_IFSTATUS_RA_SEND;
|
||
else
|
||
ra_ifstatus = RA_IFSTATUS_INACTIVE;
|
||
#endif
|
||
}
|
||
c = 0;
|
||
printf(" status=<");
|
||
if (ra_ifstatus == RA_IFSTATUS_INACTIVE)
|
||
printf("%s%s", (c) ? "," : "", "INACTIVE");
|
||
else if (ra_ifstatus == RA_IFSTATUS_RA_RECV)
|
||
printf("%s%s", (c) ? "," : "", "RA_RECV");
|
||
else if (ra_ifstatus == RA_IFSTATUS_RA_SEND)
|
||
printf("%s%s", (c) ? "," : "", "RA_SEND");
|
||
printf("> ");
|
||
switch (ifi_s->ifi_state) {
|
||
case IFI_STATE_CONFIGURED:
|
||
case IFI_STATE_TRANSITIVE:
|
||
break;
|
||
default:
|
||
printf("\n");
|
||
continue;
|
||
}
|
||
printf("mtu %d\n", ifi_s->ifi_phymtu);
|
||
sprintf(argv_rai, "%s:rai=", ifi->ifi_ifname);
|
||
action_argv = argv_rai;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
continue;
|
||
rai = (struct rainfo *)cp.cp_val;
|
||
printf("\tDefaultLifetime: %s",
|
||
sec2str(rai->rai_lifetime, ssbuf));
|
||
if (ra_ifstatus != RA_IFSTATUS_RA_SEND &&
|
||
rai->rai_lifetime == 0)
|
||
printf(" (RAs will be sent with zero lifetime)");
|
||
printf("\n");
|
||
printf("\tMinAdvInterval/MaxAdvInterval: ");
|
||
printf("%s/", sec2str(rai->rai_mininterval, ssbuf));
|
||
printf("%s\n", sec2str(rai->rai_maxinterval, ssbuf));
|
||
if (rai->rai_linkmtu)
|
||
printf("\tAdvLinkMTU: %d", rai->rai_linkmtu);
|
||
else
|
||
printf("\tAdvLinkMTU: <none>");
|
||
printf(", ");
|
||
printf("Flags: ");
|
||
if (rai->rai_managedflg || rai->rai_otherflg) {
|
||
printf("%s", rai->rai_managedflg ? "M" : "");
|
||
printf("%s", rai->rai_otherflg ? "O" : "");
|
||
} else
|
||
printf("<none>");
|
||
printf(", ");
|
||
printf("Preference: %s\n",
|
||
rtpref_str[(rai->rai_rtpref >> 3) & 0xff]);
|
||
printf("\tReachableTime: %s, ",
|
||
sec2str(rai->rai_reachabletime, ssbuf));
|
||
printf("RetransTimer: %s, "
|
||
"CurHopLimit: %d\n",
|
||
sec2str(rai->rai_retranstimer, ssbuf),
|
||
rai->rai_hoplimit);
|
||
printf("\tAdvIfPrefixes: %s\n",
|
||
rai->rai_advifprefix ? "yes" : "no");
|
||
/* RA timer */
|
||
rat = NULL;
|
||
if (ifi_s->ifi_ra_timer != NULL) {
|
||
sprintf(argv_ifi_ra_timer, "%s:ifi_ra_timer=",
|
||
ifi->ifi_ifname);
|
||
action_argv = argv_ifi_ra_timer;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
return (error);
|
||
rat = (struct rtadvd_timer *)cp.cp_val;
|
||
}
|
||
printf("\tNext RA send: ");
|
||
if (rat == NULL)
|
||
printf("never\n");
|
||
else {
|
||
ts.tv_sec = rat->rat_tm.tv_sec + ts0.tv_sec;
|
||
printf("%s", ctime(&ts.tv_sec));
|
||
}
|
||
printf("\tLast RA send: ");
|
||
if (ifi_s->ifi_ra_lastsent.tv_sec == 0)
|
||
printf("never\n");
|
||
else {
|
||
ts.tv_sec = ifi_s->ifi_ra_lastsent.tv_sec + ts0.tv_sec;
|
||
printf("%s", ctime(&ts.tv_sec));
|
||
}
|
||
if (rai->rai_clockskew)
|
||
printf("\tClock skew: %" PRIu16 "sec\n",
|
||
rai->rai_clockskew);
|
||
if (vflag < LOG_WARNING)
|
||
continue;
|
||
/* route information */
|
||
sprintf(argv_rti, "%s:rti=", ifi->ifi_ifname);
|
||
action_argv = argv_rti;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
return (error);
|
||
rti = (struct rtinfo *)cp.cp_val;
|
||
len = cp.cp_val_len / sizeof(*rti);
|
||
if (len > 0) {
|
||
printf("\tRoute Info:\n");
|
||
for (i = 0; i < len; i++)
|
||
action_show_rtinfo(&rti[i]);
|
||
}
|
||
/* prefix information */
|
||
sprintf(argv_pfx, "%s:pfx=", ifi->ifi_ifname);
|
||
action_argv = argv_pfx;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
continue;
|
||
pfx = (struct prefix *)cp.cp_val;
|
||
len = cp.cp_val_len / sizeof(*pfx);
|
||
if (len > 0) {
|
||
printf("\tPrefixes (%d):\n", len);
|
||
for (i = 0; i < len; i++)
|
||
action_show_prefix(&pfx[i]);
|
||
}
|
||
/* RDNSS information */
|
||
sprintf(argv_rdnss, "%s:rdnss=", ifi->ifi_ifname);
|
||
action_argv = argv_rdnss;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
continue;
|
||
len = *((uint16_t *)cp.cp_val);
|
||
if (len > 0) {
|
||
printf("\tRDNSS entries:\n");
|
||
action_show_rdnss(cp.cp_val);
|
||
}
|
||
/* DNSSL information */
|
||
sprintf(argv_dnssl, "%s:dnssl=", ifi->ifi_ifname);
|
||
action_argv = argv_dnssl;
|
||
error = action_propget(action_argv, &cp);
|
||
if (error)
|
||
continue;
|
||
len = *((uint16_t *)cp.cp_val);
|
||
if (len > 0) {
|
||
printf("\tDNSSL entries:\n");
|
||
action_show_dnssl(cp.cp_val);
|
||
}
|
||
if (vflag < LOG_NOTICE)
|
||
continue;
|
||
printf("\n");
|
||
printf("\tCounters\n"
|
||
"\t RA burst counts: %" PRIu16 " (interval: %s)\n"
|
||
"\t RS wait counts: %" PRIu16 "\n",
|
||
ifi_s->ifi_burstcount,
|
||
sec2str(ifi_s->ifi_burstinterval, ssbuf),
|
||
ifi_s->ifi_rs_waitcount);
|
||
printf("\tOutputs\n"
|
||
"\t RA: %" PRIu64 "\n", ifi_s->ifi_raoutput);
|
||
printf("\tInputs\n"
|
||
"\t RA: %" PRIu64 " (normal)\n"
|
||
"\t RA: %" PRIu64 " (inconsistent)\n"
|
||
"\t RS: %" PRIu64 "\n",
|
||
ifi_s->ifi_rainput,
|
||
ifi_s->ifi_rainconsistent,
|
||
ifi_s->ifi_rsinput);
|
||
printf("\n");
|
||
#if 0 /* Not implemented yet */
|
||
printf("\tReceived RAs:\n");
|
||
#endif
|
||
}
|
||
return (0);
|
||
}
|
||
static int
|
||
action_show_rtinfo(struct rtinfo *rti)
|
||
{
|
||
char ntopbuf[INET6_ADDRSTRLEN];
|
||
char ssbuf[SSBUFLEN];
|
||
printf("\t %s/%d (pref: %s, ltime: %s)\n",
|
||
inet_ntop(AF_INET6, &rti->rti_prefix,
|
||
ntopbuf, sizeof(ntopbuf)),
|
||
rti->rti_prefixlen,
|
||
rtpref_str[0xff & (rti->rti_rtpref >> 3)],
|
||
(rti->rti_ltime == ND6_INFINITE_LIFETIME) ?
|
||
"infinity" : sec2str(rti->rti_ltime, ssbuf));
|
||
return (0);
|
||
}
|
||
static int
|
||
action_show_prefix(struct prefix *pfx)
|
||
{
|
||
char ntopbuf[INET6_ADDRSTRLEN];
|
||
char ssbuf[SSBUFLEN];
|
||
struct timespec now;
|
||
clock_gettime(CLOCK_MONOTONIC_FAST, &now);
|
||
printf("\t %s/%d", inet_ntop(AF_INET6, &pfx->pfx_prefix,
|
||
ntopbuf, sizeof(ntopbuf)), pfx->pfx_prefixlen);
|
||
printf(" (");
|
||
switch (pfx->pfx_origin) {
|
||
case PREFIX_FROM_KERNEL:
|
||
printf("KERNEL");
|
||
break;
|
||
case PREFIX_FROM_CONFIG:
|
||
printf("CONFIG");
|
||
break;
|
||
case PREFIX_FROM_DYNAMIC:
|
||
printf("DYNAMIC");
|
||
break;
|
||
}
|
||
printf(",");
|
||
printf(" vltime=%s",
|
||
(pfx->pfx_validlifetime == ND6_INFINITE_LIFETIME) ?
|
||
"infinity" : sec2str(pfx->pfx_validlifetime, ssbuf));
|
||
if (pfx->pfx_vltimeexpire > 0)
|
||
printf("(expire: %s)",
|
||
((long)pfx->pfx_vltimeexpire > now.tv_sec) ?
|
||
sec2str(pfx->pfx_vltimeexpire - now.tv_sec, ssbuf) :
|
||
"0");
|
||
printf(",");
|
||
printf(" pltime=%s",
|
||
(pfx->pfx_preflifetime == ND6_INFINITE_LIFETIME) ?
|
||
"infinity" : sec2str(pfx->pfx_preflifetime, ssbuf));
|
||
if (pfx->pfx_pltimeexpire > 0)
|
||
printf("(expire %s)",
|
||
((long)pfx->pfx_pltimeexpire > now.tv_sec) ?
|
||
sec2str(pfx->pfx_pltimeexpire - now.tv_sec, ssbuf) :
|
||
"0");
|
||
printf(",");
|
||
printf(" flags=");
|
||
if (pfx->pfx_onlinkflg || pfx->pfx_autoconfflg) {
|
||
printf("%s", pfx->pfx_onlinkflg ? "L" : "");
|
||
printf("%s", pfx->pfx_autoconfflg ? "A" : "");
|
||
} else
|
||
printf("<none>");
|
||
if (pfx->pfx_timer) {
|
||
struct timespec *rest;
|
||
rest = rtadvd_timer_rest(pfx->pfx_timer);
|
||
if (rest) { /* XXX: what if not? */
|
||
printf(" expire=%s", sec2str(rest->tv_sec, ssbuf));
|
||
}
|
||
}
|
||
printf(")\n");
|
||
return (0);
|
||
}
|
||
static int
|
||
action_show_rdnss(void *msg)
|
||
{
|
||
struct rdnss *rdn;
|
||
struct rdnss_addr *rda;
|
||
uint16_t *rdn_cnt;
|
||
uint16_t *rda_cnt;
|
||
int i;
|
||
int j;
|
||
char *p;
|
||
uint32_t ltime;
|
||
char ntopbuf[INET6_ADDRSTRLEN];
|
||
char ssbuf[SSBUFLEN];
|
||
p = msg;
|
||
rdn_cnt = (uint16_t *)p;
|
||
p += sizeof(*rdn_cnt);
|
||
if (*rdn_cnt > 0) {
|
||
for (i = 0; i < *rdn_cnt; i++) {
|
||
rdn = (struct rdnss *)p;
|
||
ltime = rdn->rd_ltime;
|
||
p += sizeof(*rdn);
|
||
rda_cnt = (uint16_t *)p;
|
||
p += sizeof(*rda_cnt);
|
||
if (*rda_cnt > 0)
|
||
for (j = 0; j < *rda_cnt; j++) {
|
||
rda = (struct rdnss_addr *)p;
|
||
printf("\t %s (ltime=%s)\n",
|
||
inet_ntop(AF_INET6,
|
||
&rda->ra_dns,
|
||
ntopbuf,
|
||
sizeof(ntopbuf)),
|
||
sec2str(ltime, ssbuf));
|
||
p += sizeof(*rda);
|
||
}
|
||
}
|
||
}
|
||
return (0);
|
||
}
|
||
static int
|
||
action_show_dnssl(void *msg)
|
||
{
|
||
struct dnssl *dns;
|
||
struct dnssl_addr *dna;
|
||
uint16_t *dns_cnt;
|
||
uint16_t *dna_cnt;
|
||
int i;
|
||
int j;
|
||
char *p;
|
||
uint32_t ltime;
|
||
char hbuf[NI_MAXHOST];
|
||
char ssbuf[SSBUFLEN];
|
||
p = msg;
|
||
dns_cnt = (uint16_t *)p;
|
||
p += sizeof(*dns_cnt);
|
||
if (*dns_cnt > 0) {
|
||
for (i = 0; i < *dns_cnt; i++) {
|
||
dns = (struct dnssl *)p;
|
||
ltime = dns->dn_ltime;
|
||
p += sizeof(*dns);
|
||
dna_cnt = (uint16_t *)p;
|
||
p += sizeof(*dna_cnt);
|
||
if (*dna_cnt > 0)
|
||
for (j = 0; j < *dna_cnt; j++) {
|
||
dna = (struct dnssl_addr *)p;
|
||
dname_labeldec(hbuf, sizeof(hbuf),
|
||
dna->da_dom);
|
||
printf("\t %s (ltime=%s)\n",
|
||
hbuf, sec2str(ltime, ssbuf));
|
||
p += sizeof(*dna);
|
||
}
|
||
}
|
||
}
|
||
return (0);
|
||
}
|
||
/* Decode domain name label encoding in RFC 1035 Section 3.1 */
|
||
static size_t
|
||
dname_labeldec(char *dst, size_t dlen, const char *src)
|
||
{
|
||
size_t len;
|
||
const char *src_origin;
|
||
const char *src_last;
|
||
const char *dst_origin;
|
||
src_origin = src;
|
||
src_last = strchr(src, '\0');
|
||
dst_origin = dst;
|
||
memset(dst, '\0', dlen);
|
||
while (src && (len = (uint8_t)(*src++) & 0x3f) &&
|
||
(src + len) <= src_last) {
|
||
if (dst != dst_origin)
|
||
*dst++ = '.';
|
||
mysyslog(LOG_DEBUG, "<%s> labellen = %zd", __func__, len);
|
||
memcpy(dst, src, len);
|
||
src += len;
|
||
dst += len;
|
||
}
|
||
*dst = '\0';
|
||
return (src - src_origin);
|
||
}
|
usr.sbin/rtadvd/Makefile | ||
---|---|---|
# AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
|
||
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||
# A PARTICULAR PURPOSE.
|
||
# $FreeBSD: src/usr.sbin/rtadvd/Makefile,v 1.1.2.2 2001/04/25 12:10:48 ru Exp $
|
||
#
|
||
# $FreeBSD: stable/10/usr.sbin/rtadvd/Makefile 224144 2011-07-17 19:24:54Z hrs $
|
||
PROG= rtadvd
|
||
SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
|
||
WARNS?= 2
|
||
MAN= rtadvd.conf.5 rtadvd.8
|
||
SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c timer_subr.c \
|
||
control.c control_server.c
|
||
CFLAGS+=-DINET6
|
||
DPADD= ${LIBUTIL}
|
||
LDADD= -lutil
|
||
MAN= rtadvd.conf.5 rtadvd.8
|
||
CFLAGS+= -DHAVE_ARC4RANDOM
|
||
WARNS?= 1
|
||
.include <bsd.prog.mk>
|
usr.sbin/rtadvd/advcap.c | ||
---|---|---|
/* $KAME: advcap.c,v 1.5 2001/02/01 09:12:08 jinmei Exp $ */
|
||
/* $FreeBSD: stable/10/usr.sbin/rtadvd/advcap.c 222824 2011-06-07 15:40:17Z hrs $ */
|
||
/* $KAME: advcap.c,v 1.11 2003/05/19 09:46:50 keiichi Exp $ */
|
||
/*
|
||
* Copyright (c) 1983 The Regents of the University of California.
|
||
... | ... | |
* 2. Redistributions in binary form must reproduce the above copyright
|
||
* notice, this list of conditions and the following disclaimer in the
|
||
* documentation and/or other materials provided with the distribution.
|
||
* 3. Neither the name of the University nor the names of its contributors
|
||
* 4. Neither the name of the University nor the names of its contributors
|
||
* may be used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
... | ... | |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
* SUCH DAMAGE.
|
||
*
|
||
* $FreeBSD: src/usr.sbin/rtadvd/advcap.c,v 1.1.2.2 2001/07/03 11:02:13 ume Exp $
|
||
* $DragonFly: src/usr.sbin/rtadvd/advcap.c,v 1.5 2005/02/17 14:00:10 joerg Exp $
|
||
*/
|
||
/*
|
||
... | ... | |
#define V_TERM "HOST"
|
||
#endif
|
||
char *RM;
|
||
/*
|
||
* termcap - routines for dealing with the terminal capability data base
|
||
*
|
||
... | ... | |
static char *tbuf;
|
||
static int hopcount; /* detect infinite loops in termcap, init 0 */
|
||
static char *remotefile;
|
||
extern char *conffile;
|
||
extern const char *conffile;
|
||
int tgetent(char *, char *);
|
||
int getent(char *, char *, char *);
|
||
int getent(char *, char *, const char *);
|
||
int tnchktc(void);
|
||
int tnamatch(char *);
|
||
static char *tskip(char *);
|
||
long long tgetnum(char *);
|
||
int64_t tgetnum(char *);
|
||
int tgetflag(char *);
|
||
char *tgetstr(char *, char **);
|
||
static char *tdecode(char *, char **);
|
||
... | ... | |
int
|
||
tgetent(char *bp, char *name)
|
||
{
|
||
char *cp;
|
||
remotefile = cp = conffile ? conffile : _PATH_RTADVDCONF;
|
||
return (getent(bp, name, cp));
|
||
return (getent(bp, name, conffile));
|
||
}
|
||
int
|
||
getent(char *bp, char *name, char *cp)
|
||
getent(char *bp, char *name, const char *cfile)
|
||
{
|
||
int c;
|
||
int i = 0, cnt = 0;
|
||
char ibuf[BUFSIZ];
|
||
char *cp;
|
||
int tf;
|
||
tbuf = bp;
|
||
... | ... | |
* use so we don't have to read the file. In this case it
|
||
* has to already have the newlines crunched out.
|
||
*/
|
||
if (cp && *cp) {
|
||
tf = open(RM = cp, O_RDONLY);
|
||
}
|
||
if (cfile && *cfile)
|
||
tf = open(cfile, O_RDONLY);
|
||
if (tf < 0) {
|
||
syslog(LOG_INFO,
|
||
"<%s> open: %s", __func__, strerror(errno));
|
||
... | ... | |
}
|
||
break;
|
||
}
|
||
if (cp >= bp+BUFSIZ) {
|
||
write(2,"Remcap entry too long\n", 23);
|
||
if (cp >= bp + BUFSIZ) {
|
||
write(STDERR_FILENO, "Remcap entry too long\n",
|
||
23);
|
||
break;
|
||
} else
|
||
*cp++ = c;
|
||
... | ... | |
p = tbuf + strlen(tbuf) - 2; /* before the last colon */
|
||
while (*--p != ':')
|
||
if (p<tbuf) {
|
||
write(2, "Bad remcap entry\n", 18);
|
||
if (p < tbuf) {
|
||
write(STDERR_FILENO, "Bad remcap entry\n", 18);
|
||
return (0);
|
||
}
|
||
p++;
|
||
/* p now points to beginning of last field */
|
||
if (p[0] != 't' || p[1] != 'c')
|
||
return (1);
|
||
strcpy(tcname, p+3);
|
||
strlcpy(tcname, p + 3, sizeof tcname);
|
||
q = tcname;
|
||
while (*q && *q != ':')
|
||
q++;
|
||
*q = 0;
|
||
if (++hopcount > MAXHOP) {
|
||
write(2, "Infinite tc= loop\n", 18);
|
||
write(STDERR_FILENO, "Infinite tc= loop\n", 18);
|
||
return (0);
|
||
}
|
||
if (getent(tcbuf, tcname, remotefile) != 1) {
|
||
if (getent(tcbuf, tcname, conffile) != 1) {
|
||
return (0);
|
||
}
|
||
for (q = tcbuf; *q++ != ':'; )
|
||
;
|
||
l = p - holdtbuf + strlen(q);
|
||
if (l > BUFSIZ) {
|
||
write(2, "Remcap entry too long\n", 23);
|
||
write(STDERR_FILENO, "Remcap entry too long\n", 23);
|
||
q[BUFSIZ - (p-holdtbuf)] = 0;
|
||
}
|
||
strcpy(p, q);
|
||
... | ... | |
* a # character. If the option is not found we return -1.
|
||
* Note that we handle octal numbers beginning with 0.
|
||
*/
|
||
long long
|
||
int64_t
|
||
tgetnum(char *id)
|
||
{
|
||
long long i;
|
||
int64_t i;
|
||
int base;
|
||
char *bp = tbuf;
|
||
... | ... | |
}
|
||
/*
|
||
* Tdecode does the grunt work to decode the
|
||
* Tdecode does the grung work to decode the
|
||
* string capability escapes.
|
||
*/
|
||
static char *
|
||
... | ... | |
{
|
||
char *cp;
|
||
int c;
|
||
char *dp;
|
||
const char *dp;
|
||
int i;
|
||
char term;
|
||
usr.sbin/rtadvd/advcap.h | ||
---|---|---|
/* $KAME: advcap.h,v 1.3 2001/02/01 09:12:08 jinmei Exp $ */
|
||
/* $FreeBSD: stable/10/usr.sbin/rtadvd/advcap.h 173412 2007-11-07 10:53:41Z kevlo $ */
|
||
/* $KAME: advcap.h,v 1.5 2003/06/09 05:40:54 t-momose Exp $ */
|
||
/*
|
||
* Copyright (C) 1994,1995 by Andrey A. Chernov, Moscow, Russia.
|
||
... | ... | |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
* SUCH DAMAGE.
|
||
*
|
||
* $FreeBSD: src/usr.sbin/rtadvd/advcap.h,v 1.1.2.2 2001/07/03 11:02:14 ume Exp $
|
||
* $DragonFly: src/usr.sbin/rtadvd/advcap.h,v 1.3 2003/11/03 19:31:42 eirikn Exp $
|
||
*/
|
||
/* Based on Id: termcap.h,v 1.8 1996/09/10 12:42:10 peter Exp */
|
||
... | ... | |
extern int agetent(char *, const char *);
|
||
extern int agetflag(const char *);
|
||
extern long long agetnum(const char *);
|
||
extern int64_t agetnum(const char *);
|
||
extern char *agetstr(const char *, char **);
|
||
__END_DECLS
|
usr.sbin/rtadvd/config.c | ||
---|---|---|
/* $KAME: config.c,v 1.37 2001/05/25 07:34:00 itojun Exp $ */
|
||
/* $FreeBSD: stable/10/usr.sbin/rtadvd/config.c 254955 2013-08-27 11:50:33Z hrs $ */
|
||
/* $KAME: config.c,v 1.84 2003/08/05 12:34:23 itojun Exp $ */
|
||
/*
|
||
* Copyright (C) 1998 WIDE Project.
|
||
* Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
|
||
* All rights reserved.
|
||
*
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without
|
||
* modification, are permitted provided that the following conditions
|
||
* are met:
|
||
... | ... | |
* 3. Neither the name of the project nor the names of its contributors
|
||
* may be used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
... | ... | |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
* SUCH DAMAGE.
|
||
*
|
||
* $FreeBSD: src/usr.sbin/rtadvd/config.c,v 1.3.2.5 2003/04/22 09:40:57 suz Exp $
|
||
*/
|
||
#include <sys/param.h>
|
||
#include <sys/ioctl.h>
|
||
#include <sys/socket.h>
|
||
#include <sys/time.h>
|
||
#include <sys/sysctl.h>
|
||
#include <net/if.h>
|
||
#if defined(__DragonFly__)
|
||
#include <net/if_var.h>
|
||
#endif /* __DragonFly__ */
|
||
#include <net/route.h>
|
||
#include <net/if_dl.h>
|
||
... | ... | |
#include <netinet/ip6.h>
|
||
#include <netinet6/ip6_var.h>
|
||
#include <netinet/icmp6.h>
|
||
#ifdef MIP6
|
||
#include <netinet6/mip6.h>
|
||
#endif
|
||
#include <netinet6/nd6.h>
|
||
#include <arpa/inet.h>
|
||
#include <stdio.h>
|
||
#include <syslog.h>
|
||
#include <errno.h>
|
||
#include <inttypes.h>
|
||
#include <netdb.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <search.h>
|
||
#include <stdlib.h>
|
||
#include <time.h>
|
||
#include <unistd.h>
|
||
#include <ifaddrs.h>
|
||
... | ... | |
#include "if.h"
|
||
#include "config.h"
|
||
/* label of tcapcode + number + domain name + zero octet */
|
||
static char entbuf[10 + 3 + NI_MAXHOST + 1];
|
||
static char oentbuf[10 + 3 + NI_MAXHOST + 1];
|
||
static char abuf[DNAME_LABELENC_MAXLEN];
|
||
static time_t prefix_timo = (60 * 120); /* 2 hours.
|
||
* XXX: should be configurable. */
|
||
extern struct rainfo *ralist;
|
||
static struct rtadvd_timer *prefix_timeout(void *);
|
||
static void makeentry(char *, size_t, int, char *, int);
|
||
static void get_prefix(struct rainfo *);
|
||
static int getinet6sysctl(int);
|
||
static void makeentry(char *, size_t, int, const char *);
|
||
static size_t dname_labelenc(char *, const char *);
|
||
void
|
||
getconfig(char *intface)
|
||
/* Encode domain name label encoding in RFC 1035 Section 3.1 */
|
||
static size_t
|
||
dname_labelenc(char *dst, const char *src)
|
||
{
|
||
int stat, pfxs, i;
|
||
char tbuf[BUFSIZ];
|
||
struct rainfo *tmp;
|
||
long val;
|
||
long long val64;
|
||
char buf[BUFSIZ];
|
||
char *bp = buf;
|
||
char *addr;
|
||
static int forwarding = -1;
|
||
char *dst_origin;
|
||
char *p;
|
||
size_t len;
|
||
dst_origin = dst;
|
||
len = strlen(src);
|
||
/* Length fields per 63 octets + '\0' (<= DNAME_LABELENC_MAXLEN) */
|
||
memset(dst, 0, len + len / 64 + 1 + 1);
|
||
syslog(LOG_DEBUG, "<%s> labelenc = %s", __func__, src);
|
||
while (src && (len = strlen(src)) != 0) {
|
||
/* Put a length field with 63 octet limitation first. */
|
||
p = strchr(src, '.');
|
||
if (p == NULL)
|
||
*dst++ = len = MIN(63, len);
|
||
else
|
||
*dst++ = len = MIN(63, p - src);
|
||
/* Copy 63 octets at most. */
|
||
memcpy(dst, src, len);
|
||
dst += len;
|
||
if (p == NULL) /* the last label */
|
||
break;
|
||
src = p + 1;
|
||
}
|
||
/* Always need a 0-length label at the tail. */
|
||
*dst++ = '\0';
|
||
syslog(LOG_DEBUG, "<%s> labellen = %td", __func__, dst - dst_origin);
|
||
return (dst - dst_origin);
|
||
}
|
||
#define MUSTHAVE(var, cap) \
|
||
#define MUSTHAVE(var, cap) \
|
||
do { \
|