aboutsummaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorGarrett Wollman <wollman@FreeBSD.org>1996-12-11 21:04:17 +0000
committerGarrett Wollman <wollman@FreeBSD.org>1996-12-11 21:04:17 +0000
commita30febec0e1b05d4c0a1c9329cb2bd3467888172 (patch)
treeb5e9cc3ba80d427ad183fadbc654c5039be6a551 /sbin
parentfda109d2ad660dbffe58bdd26c3dc69a35cfdd3d (diff)
downloadsrc-a30febec0e1b05d4c0a1c9329cb2bd3467888172.tar.gz
src-a30febec0e1b05d4c0a1c9329cb2bd3467888172.zip
Merge from vendor branch.
Notes
Notes: svn path=/head/; revision=20342
Diffstat (limited to 'sbin')
-rw-r--r--sbin/routed/defs.h47
-rw-r--r--sbin/routed/main.c88
-rw-r--r--sbin/routed/routed.826
-rw-r--r--sbin/routed/rtquery/rtquery.c1
-rw-r--r--sbin/routed/table.c46
5 files changed, 132 insertions, 76 deletions
diff --git a/sbin/routed/defs.h b/sbin/routed/defs.h
index d87029d14560..1f8ec00d100b 100644
--- a/sbin/routed/defs.h
+++ b/sbin/routed/defs.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)defs.h 8.1 (Berkeley) 6/5/93
- * $Id: defs.h,v 1.3 1996/11/19 20:42:11 wollman Exp $
+ * $Id: defs.h,v 1.4 1996/12/10 17:07:36 wollman Exp $
*/
/* Definitions for RIPv2 routing process.
@@ -119,7 +119,8 @@
*/
/* #define MCAST_PPP_BUG */
-#define NEVER (24*60*60) /* a long time */
+#define DAY (24*60*60)
+#define NEVER DAY /* a long time */
#define EPOCH NEVER /* bias time by this to avoid <0 */
/* Scan the kernel regularly to see if any interfaces have appeared or been
@@ -288,15 +289,13 @@ struct interface {
#endif
time_t ts; /* timestamp on network stats */
} int_data;
+# define MAX_AUTH_KEYS 5
struct auth { /* authentication info */
u_char type;
-# define MAX_AUTH_KEYS 3
- struct auth_key {
- u_char key[RIP_AUTH_PW_LEN];
- u_char keyid;
- time_t start, end;
- } keys[MAX_AUTH_KEYS];
- } int_auth;
+ u_char key[RIP_AUTH_PW_LEN];
+ u_char keyid;
+ time_t start, end;
+ } int_auth[MAX_AUTH_KEYS];
int int_rdisc_pref; /* advertised rdisc preference */
int int_rdisc_int; /* MaxAdvertiseInterval */
int int_rdisc_cnt;
@@ -313,10 +312,10 @@ struct interface {
#define IS_ALL_HOSTS 0x0000040 /* in INADDR_ALLHOSTS_GROUP */
#define IS_ALL_ROUTERS 0x0000080 /* in INADDR_ALLROUTERS_GROUP */
#define IS_DISTRUST 0x0000100 /* ignore untrusted routers */
-#define IS_BROKE 0x0000200 /* seems to be broken */
-#define IS_SICK 0x0000400 /* seems to be broken */
-#define IS_DUP 0x0000800 /* has a duplicate address */
-/* 0x0001000 spare */
+#define IS_REDIRECT_OK 0x0000200 /* accept ICMP redirects */
+#define IS_BROKE 0x0000400 /* seems to be broken */
+#define IS_SICK 0x0000800 /* seems to be broken */
+#define IS_DUP 0x0001000 /* has a duplicate address */
#define IS_NEED_NET_SYN 0x0002000 /* need RS_NET_SYN route */
#define IS_NO_AG 0x0004000 /* do not aggregate subnets */
#define IS_NO_SUPER_AG 0x0008000 /* do not aggregate networks */
@@ -395,7 +394,7 @@ extern struct parm {
u_int parm_int_state;
int parm_rdisc_pref;
int parm_rdisc_int;
- struct auth parm_auth;
+ struct auth parm_auth[MAX_AUTH_KEYS];
} *parms;
/* authority for internal networks */
@@ -471,13 +470,14 @@ extern int need_flash; /* flash update needed */
extern struct timeval need_kern; /* need to update kernel table */
extern int update_seqno; /* a route has changed */
-extern u_int tracelevel, new_tracelevel;
+extern int tracelevel, new_tracelevel;
#define MAX_TRACELEVEL 4
#define TRACEKERNEL (tracelevel >= 4) /* log kernel changes */
#define TRACECONTENTS (tracelevel >= 3) /* display packet contents */
#define TRACEPACKETS (tracelevel >= 2) /* note packets */
#define TRACEACTIONS (tracelevel != 0)
extern FILE *ftrace; /* output trace file */
+extern char inittracename[MAXPATHLEN+1];
extern struct radix_node_head *rhead;
@@ -495,7 +495,7 @@ extern void rip_on(struct interface *);
extern void bufinit(void);
extern int output(enum output_type, struct sockaddr_in *,
struct interface *, struct rip *, int);
-extern void clr_ws_buf(struct ws_buf *, struct auth_key *, struct interface *);
+extern void clr_ws_buf(struct ws_buf *, struct auth *);
extern void rip_query(void);
extern void rip_bcast(int);
extern void supply(struct sockaddr_in *, struct interface *,
@@ -503,8 +503,12 @@ extern void supply(struct sockaddr_in *, struct interface *,
extern void msglog(char *, ...);
struct msg_limit {
+ time_t reuse;
+ struct msg_sub {
naddr addr;
time_t until;
+# define MSG_SUBJECT_N 8
+ } subs[MSG_SUBJECT_N];
};
extern void msglim(struct msg_limit *, naddr, char *, ...);
#define LOGERR(msg) msglog(msg ": %s", strerror(errno))
@@ -524,15 +528,16 @@ extern void intvl_random(struct timeval *, u_long, u_long);
extern int getnet(char *, naddr *, naddr *);
extern int gethost(char *, naddr *);
extern void gwkludge(void);
-extern char *parse_parms(char *);
+extern char *parse_parms(char *, int);
extern char *check_parms(struct parm *);
extern void get_parms(struct interface *);
extern void lastlog(void);
-extern void trace_on(char *, int);
+extern void set_tracefile(char *, char *, int);
+extern void tracelevel_msg(char *, int);
extern void trace_off(char*, ...);
+extern void set_tracelevel(void);
extern void trace_flush(void);
-extern void set_tracelevel(int);
extern void trace_kernel(char *, ...);
extern void trace_act(char *, ...);
extern void trace_pkt(char *, ...);
@@ -615,7 +620,7 @@ extern struct interface *ifwithname(char *, naddr);
extern struct interface *ifwithindex(u_short);
extern struct interface *iflookup(naddr);
-extern struct auth_key *find_auth(struct interface *);
-extern void end_md5_auth(struct ws_buf *, struct auth_key *);
+extern struct auth *find_auth(struct interface *);
+extern void end_md5_auth(struct ws_buf *, struct auth *);
#include <md5.h>
diff --git a/sbin/routed/main.c b/sbin/routed/main.c
index dc0b1d88ab63..36399e999a70 100644
--- a/sbin/routed/main.c
+++ b/sbin/routed/main.c
@@ -39,7 +39,6 @@ static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.18 $"
#include "defs.h"
#include "pathnames.h"
@@ -201,10 +200,13 @@ main(int argc,
/* handle arbirary, (usually) per-interface
* parameters.
*/
- p = parse_parms(optarg);
- if (p != 0)
- msglog("bad \"%s\" in \"%s\"",
- p, optarg);
+ p = parse_parms(optarg, 0);
+ if (p != 0) {
+ if (strcasecmp(p,optarg))
+ msglog("%s in \"%s\"", p, optarg);
+ else
+ msglog("bad \"-P %s\"", optarg);
+ }
break;
default:
@@ -218,9 +220,11 @@ main(int argc,
tracename = *argv++;
argc--;
}
+ if (tracename != 0 && tracename[0] == '\0')
+ goto usage;
if (argc != 0) {
usage:
- logbad(0, "usage: routed [-sqdghmpAt] [-T /tracefile]"
+ logbad(0, "usage: routed [-sqdghmpAt] [-T tracefile]"
" [-F net[,metric]] [-P parms]");
}
if (geteuid() != 0)
@@ -263,18 +267,16 @@ usage:
signal(SIGUSR2, sigtrace_off);
/* get into the background */
- if (background) {
#ifdef sgi
- if (0 > _daemonize(_DF_NOCHDIR,
- new_tracelevel == 0 ? -1 : STDOUT_FILENO,
- new_tracelevel == 0 ? -1 : STDERR_FILENO,
- -1))
- BADERR(0, "_daemonize()");
+ if (0 > _daemonize(background ? 0 : (_DF_NOCHDIR|_DF_NOFORK),
+ new_tracelevel == 0 ? -1 : STDOUT_FILENO,
+ new_tracelevel == 0 ? -1 : STDERR_FILENO,
+ -1))
+ BADERR(0, "_daemonize()");
#else
- if (daemon(1, 1) < 0)
- BADERR(0,"daemon()");
+ if (background && daemon(0, new_tracelevel) < 0)
+ BADERR(0,"daemon()");
#endif
- }
mypid = getpid();
srandom((int)(clk.tv_sec ^ clk.tv_usec ^ mypid));
@@ -297,11 +299,11 @@ usage:
if (background && new_tracelevel == 0)
ftrace = 0;
if (tracename != 0) {
- trace_on(tracename, 1);
- if (new_tracelevel == 0) /* use stdout if file is bad */
- new_tracelevel = 1;
+ strncpy(inittracename, tracename, sizeof(inittracename)-1);
+ set_tracefile(inittracename, "%s\n", -1);
+ } else {
+ tracelevel_msg("%s\n", -1); /* turn on tracing to stdio */
}
- set_tracelevel(1);
bufinit();
@@ -354,8 +356,8 @@ usage:
now_expire = now.tv_sec - EXPIRE_TIME;
now_garbage = now.tv_sec - GARBAGE_TIME;
- /* deal with interrupts that should affect tracing */
- set_tracelevel(0);
+ /* deal with signals that should affect tracing */
+ set_tracelevel();
if (stopint != 0) {
rip_bcast(0);
@@ -491,7 +493,7 @@ usage:
/* ARGSUSED */
void
-sigalrm(int sig)
+sigalrm(int s)
{
/* Historically, SIGALRM would cause the daemon to check for
* new and broken interfaces.
@@ -816,20 +818,53 @@ msglog(char *p, ...)
}
-/* Put a message about a bad router into the system log if
+/* Put a message about a bad system into the system log if
* we have not complained about it recently.
+ *
+ * It is desirable to complain about all bad systems, but not too often.
+ * In the worst case, it is not practical to keep track of all bad systems.
+ * For example, there can be many systems with the wrong password.
*/
void
msglim(struct msg_limit *lim, naddr addr, char *p, ...)
{
va_list args;
+ int i;
+ struct msg_sub *ms1, *ms;
char *p1;
va_start(args, p);
- if ( lim->addr != addr || lim->until <= now.tv_sec) {
- lim->addr = addr;
- lim->until = now.tv_sec + 60*60;
+ /* look for the oldest slot in the table
+ * or the slot for the bad router.
+ */
+ ms = ms1 = lim->subs;
+ for (i = MSG_SUBJECT_N; ; i--, ms1++) {
+ if (i == 0) {
+ /* Reuse a slot at most once every 10 minutes.
+ */
+ if (lim->reuse > now.tv_sec) {
+ ms = 0;
+ } else {
+ ms = ms1;
+ lim->reuse = now.tv_sec + 10*60;
+ }
+ break;
+ }
+ if (ms->addr == addr) {
+ /* Repeat a complaint about a given system at
+ * most once an hour.
+ */
+ if (ms->until > now.tv_sec)
+ ms = 0;
+ break;
+ }
+ if (ms->until < ms1->until)
+ ms = ms1;
+ }
+ if (ms != 0) {
+ ms->addr = addr;
+ ms->until = now.tv_sec + 60*60; /* 60 minutes */
trace_flush();
for (p1 = p; *p1 == ' '; p1++)
@@ -837,6 +872,7 @@ msglim(struct msg_limit *lim, naddr addr, char *p, ...)
vsyslog(LOG_ERR, p1, args);
}
+ /* always display the message if tracing */
if (ftrace != 0) {
(void)vfprintf(ftrace, p, args);
(void)fputc('\n', ftrace);
diff --git a/sbin/routed/routed.8 b/sbin/routed/routed.8
index 5eaaff2be96f..8771654dfb0b 100644
--- a/sbin/routed/routed.8
+++ b/sbin/routed/routed.8
@@ -514,11 +514,13 @@ specifies a RIPv2 password that will be included on all RIPv2
responses sent and checked on all RIPv2 responses received.
The password must not contain any blanks, tab characters, commas
or '#' characters.
-.It Cm passwd Ns \&= Ns Ar XXX1[|KeyID[start|stop]][XXX2...]
-specifies one or more RIPv2 cleartext passwords that will be included on
+.It Cm passwd Ns \&= Ns Ar XXX1[|KeyID[start|stop]]
+specifies a RIPv2 cleartext password that will be included on
all RIPv2 responses sent, and checked on all RIPv2 responses received.
-Any blanks, tab characters, commas, or '#' or '|' characters in the
+Any blanks, tab characters, commas, or '#', '|', or NULL characters in the
password must be escaped with a backslash (\\).
+The common escape sequences \\n, \\r, \\t, \\b, and \\xxx have their
+usual meanings.
The
.Cm KeyID
must be unique but is ignored for cleartext passwords.
@@ -528,15 +530,21 @@ and
.Cm stop
are timestamps in the form year/month/day@hour:minute.
They specify when the password is valid.
-The first valid password is used on output packets.
+The valid password with the most future is used on output packets, unless
+all passwords have expired, in which case the password that expired most
+recently is used, or unless no passwords are valid yet, in which case
+no password is output.
Incoming packets can carry any password that is valid, will
be valid within 24 hours, or that was valid within 24 hours.
-.It Cm md5_passwd Ns \&= Ns Ar XXX1|KeyID[start|stop][XXX2...]
-specifes one or more RIPv2 MD5 passwords.
+.It Cm md5_passwd Ns \&= Ns Ar XXX1|KeyID[start|stop]
+specifes a RIPv2 MD5 password.
Except that a
.Cm KeyID
-is required, this keyword is the similar to
+is required, this keyword is similar to
.Cm passwd .
+To protect the secrets, this parameter setting is valid only in the
+.Em /etc/gateways
+file and only when that file is readable only by UID 0.
.It Cm no_ag
turns off aggregation of subnets in RIPv1 and RIPv2 responses.
.It Cm no_super_ag
@@ -612,6 +620,10 @@ causes RIP packets from that router and other routers named in
other
.Cm trust_gateway
keywords to be accept, and packets from other routers to be ignored.
+.It Cm redirect_ok
+causes RIP to allow ICMP Redirect messages when the system is acting
+as a router and forwarding packets.
+Otherwise, ICMP Redirect messages are are overridden.
.El
.Pp
.Sh FILES
diff --git a/sbin/routed/rtquery/rtquery.c b/sbin/routed/rtquery/rtquery.c
index 42d4d6ee2099..f5421471e6ed 100644
--- a/sbin/routed/rtquery/rtquery.c
+++ b/sbin/routed/rtquery/rtquery.c
@@ -40,7 +40,6 @@ static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93";
#elif defined(__NetBSD__)
static char rcsid[] = "$NetBSD$";
#endif
-#ident "$Revision: 1.1.1.2 $"
#include <sys/param.h>
#include <sys/protosw.h>
diff --git a/sbin/routed/table.c b/sbin/routed/table.c
index dda559a295fe..a7c230339e8a 100644
--- a/sbin/routed/table.c
+++ b/sbin/routed/table.c
@@ -745,7 +745,7 @@ static struct khash {
#define KS_DELETED 0x100 /* already deleted */
time_t k_keep;
#define K_KEEP_LIM 30
- time_t k_redirect_time;
+ time_t k_redirect_time; /* when redirected route 1st seen */
} *khash_bins[KHASH_SIZE];
@@ -831,8 +831,7 @@ rtm_add(struct rt_msghdr *rtm,
} else if (INFO_MASK(info) != 0) {
mask = ntohl(S_ADDR(INFO_MASK(info)));
} else {
- msglog("ignore %s without mask",
- rtm_type_name(rtm->rtm_type));
+ msglog("ignore %s without mask", rtm_type_name(rtm->rtm_type));
return;
}
@@ -859,20 +858,32 @@ rtm_add(struct rt_msghdr *rtm,
k->k_state |= KS_STATIC;
if (0 != (rtm->rtm_flags & (RTF_DYNAMIC | RTF_MODIFIED))) {
- if (supplier) {
+ if (INFO_AUTHOR(info) != 0
+ && INFO_AUTHOR(info)->sa_family == AF_INET)
+ ifp = iflookup(S_ADDR(INFO_AUTHOR(info)));
+ else
+ ifp = 0;
+ if (supplier
+ && (ifp == 0 || !(ifp->int_state & IS_REDIRECT_OK))) {
/* Routers are not supposed to listen to redirects,
- * so delete it.
+ * so delete it if it came via an unknown interface
+ * or the interface does not have special permission.
*/
k->k_state &= ~KS_DYNAMIC;
k->k_state |= KS_DELETE;
LIM_SEC(need_kern, 0);
- trace_act("mark redirected %s --> %s for deletion"
- " since this is a router",
+ trace_act("mark for deletion redirected %s --> %s"
+ " via %s",
addrname(k->k_dst, k->k_mask, 0),
- naddr_ntoa(k->k_gate));
+ naddr_ntoa(k->k_gate),
+ ifp ? ifp->int_name : "unknown interface");
} else {
k->k_state |= KS_DYNAMIC;
k->k_redirect_time = now.tv_sec;
+ trace_act("accept redirected %s --> %s via %s",
+ addrname(k->k_dst, k->k_mask, 0),
+ naddr_ntoa(k->k_gate),
+ ifp ? ifp->int_name : "unknown interface");
}
return;
}
@@ -892,17 +903,10 @@ rtm_add(struct rt_msghdr *rtm,
* Find the interface toward the gateway.
*/
ifp = iflookup(k->k_gate);
- if (ifp == 0) {
- /* if there is no known interface,
- * maybe there is a new interface
- */
- ifinit();
- ifp = iflookup(k->k_gate);
- if (ifp == 0)
- msglog("static route %s --> %s impossibly lacks ifp",
- addrname(S_ADDR(INFO_DST(info)), mask, 0),
- naddr_ntoa(k->k_gate));
- }
+ if (ifp == 0)
+ msglog("static route %s --> %s impossibly lacks ifp",
+ addrname(S_ADDR(INFO_DST(info)), mask, 0),
+ naddr_ntoa(k->k_gate));
kern_check_static(k, ifp);
}
@@ -916,8 +920,8 @@ rtm_lose(struct rt_msghdr *rtm,
{
if (INFO_GATE(info) == 0
|| INFO_GATE(info)->sa_family != AF_INET) {
- msglog("ignore %s without gateway",
- rtm_type_name(rtm->rtm_type));
+ trace_act("ignore %s without gateway",
+ rtm_type_name(rtm->rtm_type));
return;
}