Index: ChangeLog
===================================================================
--- ChangeLog (nonexistent)
+++ ChangeLog (revision 5)
@@ -0,0 +1,87 @@
+25-Dec-2000:
+ Bug fix - on newer kernels, don't attempt to add direct
+ interface-routes to KRT - assume they're always present.
+ Bug fix - corrected handling of direct interface-routes
+ in rtioctl(): use rt.rt_dev entry instead of rt.rt_gateway
+ for these (was old BSDism).
+ Bug fix - do not add routes to remote subnets with netmask
+ set to 255.255.255.255, when pointopoint interfaces whose
+ IP belongs to the same network class as IP of another
+ non-pointopoint interface, are in use.
+ Feature change - do not "timeout" interface-routes even if we
+ act as route supplier.
+ Feature change - removed arbitrary limit on number of interfaces
+ that routed can look up in rtinit().
+ New feature - introduced "announced" type of distant gateways
+ for use in "gateways" file.
+ New feature - introduced command-line flag "-p" to ignore
+ all interfaces with IFF_POINTOPOINT set.
+ New feature - introduced command-line flag "-i <dev>" to ignore
+ given network interface <dev>.
+ Routed manpage upgraded accordingly. (Jan Rafaj, rafaj@vabo.cz)
+
+22-Jul-2000:
+ Allow appending to an existing log file, as long as it's in
+ the log directory. Also some cosmetic fixes. (Dennis Reichel,
+ dennis@reichel.net)
+
+ Also a bit of other cleanup and sanity checking.
+
+5-Jan-2000:
+ Bug fix (mishandling of fork return codes). (Bill Nottingham,
+ notting@redhat.com)
+ Also correct getopt handling. (Noticed by Dirk von Suchodoletz,
+ dirk@goe.net)
+
+14-Dec-1999:
+ netkit-routed-0.16 is released.
+
+12-Dec-1999:
+ Apply backlogged 64-bit bug fix. (Dr. Graeme Wilford,
+ G.Wilford@ee.surrey.ac.uk)
+ Old doc fixes from Debian. (Peter Tobias, tobias@et-inf.fho-emden.de)
+
+1-Aug-1999:
+ Complete y2k and y2038 audit.
+
+1-Aug-1999:
+ Code cleanup.
+
+31-Jul-1999:
+ Redid makefiles/config stuff for new confgen version.
+
+19-May-1998:
+ Rearranged security fix; basically you can only log to
+ /var/log/routed/*. Make this directory if you want it to log
+ anything.
+
+8-May-1998:
+ Added a security 'feature' to routed that prevents it writing any
+ file as root and instead uses user nobody instead (defined in
+ defs.h) routed will write to syslog to tell you what fun files
+ it's trying to create.
+
+22-Sep-1997:
+ Reorganized dirs so ripquery isn't hiding under routed.
+
+12-Jun-1997:
+ netkit-routed-0.10 released.
+
+19-May-1997:
+ glibc fixes from Red Hat.
+
+05-Apr-1997:
+ Added configure script to generate MCONFIG.
+ glibc fixes from HJ Lu.
+ makefile and ripquery fixes. (Peter Tobias, tobias@et-inf.fho-emden.de)
+
+08-Mar-1997:
+ Split from full NetKit package.
+ Generated this change log from NetKit's.
+
+29-Dec-1996
+ NetKit-0.09 released.
+ Hardened programs against DNS h_length spoofing attacks.
+ Use inet_aton() everywhere instead of inet_addr().
+ Added this routed to NetKit package.
+
Index: README
===================================================================
--- README (nonexistent)
+++ README (revision 5)
@@ -0,0 +1,95 @@
+This is netkit-routed-0.18 for Linux.
+
+This package updates netkit-routed-0.17.
+
+If you're reading this off a CD, go right away and check the net
+archives for later versions and security fixes. As of this writing the
+home site for NetKit is
+ ftp://ftp.uk.linux.org/pub/linux/Networking/netkit
+
+Contents:
+ routed RIP-based routing daemon
+ ripquery Query program for routed
+
+Requires:
+ Working compiler, libc, and kernel.
+
+Security:
+ This release contains no security fixes relative to
+ netkit-routed-0.17. However, netkit-routed-0.10 and older are
+ insecure and should not be used.
+
+Installation:
+ Do "./configure --help" and decide what options you want. The
+ defaults should be suitable for most Linux systems. Then run
+ the configure script.
+
+ Do "make" to compile.
+ Then (as root) do "make install".
+
+ Save a backup copy of any mission-critical program in case the
+ new one doesn't work, and so forth. We warned you.
+
+ If you get gcc warnings from files in /usr/include, they are
+ due to problems in your libc, not netkit. (You may only see
+ them when compiling netkit because netkit turns on a lot of
+ compiler warnings.)
+
+DEC CC:
+ The DEC compiler for the Alpha is now freely available. This
+ is a much better compiler with gcc, that is, it generates much
+ better code. If you have the DEC compiler, you can explicitly
+ use the DEC compiler instead of gcc by configuring like this:
+
+ ./configure --with-c-compiler=ccc
+
+ It is known to generate spurious warnings on some files. Also,
+ some headers from some versions of glibc confuse it; that may
+ prevent netkit from working. Other problems should be reported
+ as bugs.
+
+Bugs:
+ Please make sure the header files in /usr/include match the
+ libc version installed in /lib and /usr/lib. If you have weird
+ problems this is the most likely culprit.
+
+ Also, before reporting a bug, be sure you're working with the
+ latest version.
+
+ If something doesn't compile for you, fix it and send diffs.
+ If you can't, send the compiler's error output.
+
+ If it compiles but doesn't work, send as complete a bug report as
+ you can. Patches and fixes are welcome, as long as you describe
+ adequately what they're supposed to fix. Please, one patch per
+ distinct fix. Please do NOT send the whole archive back or
+ reindent the source.
+
+ Be sure to send all correspondence in e-mail to the netkit address.
+ Postings to netnews or mailing lists will not be seen due to the
+ enormous volume. Also, anything that doesn't get filed in the bug
+ database is quite likely to end up forgotten.
+
+ Please don't report known bugs (see the BUGS file(s)) unless you
+ are including fixes. :-)
+
+ Mail should be sent to: netbug@ftp.uk.linux.org
+
+
+Early in April 2000, a hacker broke into the machine that was hosting
+the netkit bug database for me and trashed it. Unfortunately, it seems
+backups hadn't gotten done for a while, so three months of mail (since
+mid-January) was lost. So, if you sent something and didn't hear back,
+or you sent something, heard back, but the changes failed to appear in
+this release (unlikely but possible) - please resend.
+
+Please see http://www.hcs.harvard.edu/~dholland/computers/netkit.html
+if you are curious why it was so long between the 0.10 and 0.16 releases.
+
+Future plans for netkit maintenance are still up in the air, but in the
+meantime new releases will still appear from time to time. I don't have
+a whole lot of cycles to spare to work on netkit, so things are likely
+to continue to be fairly slow.
+
+David A. Holland
+23 July 2000
Index: configure
===================================================================
--- configure (nonexistent)
+++ configure (revision 5)
@@ -0,0 +1,261 @@
+#!/bin/sh
+#
+# This file was generated by confgen version 2.
+# Do not edit.
+#
+
+PREFIX='/usr'
+#EXECPREFIX='$PREFIX'
+INSTALLROOT=''
+BINMODE='755'
+#DAEMONMODE='$BINMODE'
+MANMODE='644'
+
+while [ x$1 != x ]; do case $1 in
+
+ --help)
+ cat <<EOF
+Usage: configure [options]
+ --help Show this message
+ --with-debug Enable debugging
+ --prefix=path Prefix for location of files [/usr]
+ --exec-prefix=path Location for arch-depedent files [prefix]
+ --installroot=root Top of filesystem tree to install in [/]
+ --binmode=mode Mode for binaries [755]
+ --daemonmode=mode Mode for daemon binaries [same as binmode]
+ --manmode=mode Mode for manual pages [644]
+ --with-c-compiler=cc Program for compiling C source [guessed]
+EOF
+ exit 0;;
+ --verbose) ;;
+ --quiet) ;;
+
+ --subdir) . ../configure.defs;;
+
+ --with-debug|--debug) DEBUG=1;;
+ --prefix=*) PREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --exec-prefix=*) EXECPREFIX=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --installroot=*) INSTALLROOT=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --binmode=*) BINMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --daemonmode=*) DAEMONMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --manmode=*) MANMODE=`echo $1 | sed 's/^[^=]*=//'` ;;
+ --with-c-compiler=*) CC=`echo $1 | sed 's/^[^=]*=//'` ;;
+ *) echo "Unrecognized option: $1"; exit 1;;
+esac
+shift
+done
+
+if [ x$EXECPREFIX = x ]; then
+ EXECPREFIX="$PREFIX"
+fi
+
+if [ x$DAEMONMODE = x ]; then
+ DAEMONMODE="$BINMODE"
+fi
+
+SBINDIR="$EXECPREFIX/sbin"
+MANDIR="$PREFIX/share/man"
+
+echo "Directories: $SBINDIR $MANDIR "
+
+if [ x$INSTALLROOT != x ]; then
+ echo "Installing in chroot tree rooted at $INSTALLROOT"
+fi
+
+##################################################
+
+WARNINGS='-Wall -W -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline '
+
+cat << EOF > __conftest.c
+ int main() { int class=0; return class; }
+EOF
+
+if [ x"$CC" = x ]; then
+ echo -n 'Looking for a C compiler... '
+ for TRY in egcs gcc g++ CC c++ cc; do
+ (
+ $TRY __conftest.c -o __conftest || exit 1;
+# ./__conftest || exit 1;
+ ) >/dev/null 2>&1 || continue;
+ CC=$TRY
+ break;
+ done
+ if [ x"$CC" = x ]; then
+ echo 'failed.'
+ echo 'Cannot find a C compiler. Run configure with --with-c-compiler.'
+ rm -f __conftest*
+ exit
+ fi
+ echo "$CC"
+else
+ echo -n 'Checking if C compiler works... '
+ if (
+ $CC __conftest.c -o __conftest || exit 1
+# ./__conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+ else
+ echo 'no'
+ echo 'Compiler '"$CC"' does not exist or cannot compile C; try another.'
+ rm -f __conftest*
+ exit
+ fi
+fi
+
+echo -n "Checking if $CC accepts gcc warnings... "
+if (
+ $CC $WARNINGS __conftest.c -o __conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+ CC_WARNINGS=1
+else
+ echo 'no'
+fi
+
+if [ x$DEBUG = x ]; then
+ echo -n "Checking if $CC accepts -O2... "
+ if (
+ $CC -O2 __conftest.c -o __conftest
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+ CFLAGS="$CFLAGS -O2"
+ else
+ echo 'no'
+ echo -n "Checking if $CC accepts -O... "
+ if (
+ $CC -O __conftest.c -o __conftest
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+ CFLAGS="$CFLAGS -O"
+ else
+ echo 'no'
+ fi
+ fi
+
+else
+ echo -n "Checking if $CC accepts -g... "
+ if (
+ $CC -g __conftest.c -o __conftest
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+ CFLAGS="$CFLAGS -g"
+ else
+ echo 'no'
+ fi
+
+fi
+
+LDFLAGS=$LDFLAGS
+LIBS=$LIBS
+
+rm -f __conftest*
+
+##################################################
+
+echo -n 'Checking for BSD signal semantics... '
+cat <<EOF >__conftest.c
+#include <unistd.h>
+#include <signal.h>
+int count=0;
+void handle(int foo) { count++; }
+int main() {
+ int pid=getpid();
+ signal(SIGINT, handle);
+ kill(pid,SIGINT);
+ kill(pid,SIGINT);
+ kill(pid,SIGINT);
+ if (count!=3) return 1;
+ return 0;
+}
+
+EOF
+if (
+ $CC $CFLAGS __conftest.c -o __conftest || exit 1
+# ./__conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+else
+ if (
+ $CC $CFLAGS -D__USE_BSD_SIGNAL __conftest.c -o __conftest || exit 1
+# ./__conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo '-D__USE_BSD_SIGNAL'
+ CFLAGS="$CFLAGS -D__USE_BSD_SIGNAL"
+ else
+ echo 'no'
+ echo 'This package needs BSD signal semantics to run.'
+ rm -f __conftest*
+ exit
+ fi
+fi
+rm -f __conftest*
+
+##################################################
+
+echo -n 'Checking for socklen_t... '
+cat <<EOF >__conftest.c
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+int main() {
+ struct sockaddr_in sn;
+ socklen_t len = sizeof(sn);
+ getpeername(0, (struct sockaddr *)&sn, &len);
+ return 0;
+}
+
+EOF
+if (
+ $CC $CFLAGS __conftest.c -o __conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'yes'
+else
+ if (
+ $CC $CFLAGS -Dsocklen_t=int __conftest.c -o __conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'int'
+ CFLAGS="$CFLAGS -Dsocklen_t=int"
+ else
+ if (
+ $CC $CFLAGS -Dsocklen_t=size_t __conftest.c -o __conftest || exit 1
+ ) >/dev/null 2>&1; then
+ echo 'size_t'
+ CFLAGS="$CFLAGS -Dsocklen_t=size_t"
+ else
+ echo 'no'
+ echo 'Cannot work out what to use for socklen_t. Help...'
+ rm -f __conftest*
+ exit
+ fi
+ fi
+fi
+rm -f __conftest*
+
+##################################################
+
+echo 'Generating MCONFIG...'
+(
+ echo -n '# Generated by configure (confgen version 2) on '
+ date
+ echo '#'
+ echo
+
+ echo "SBINDIR=$SBINDIR"
+ echo "MANDIR=$MANDIR"
+ echo "BINMODE=$BINMODE"
+ echo "DAEMONMODE=$DAEMONMODE"
+ echo "MANMODE=$MANMODE"
+ echo "PREFIX=$PREFIX"
+ echo "EXECPREFIX=$EXECPREFIX"
+ echo "INSTALLROOT=$INSTALLROOT"
+ echo "CC=$CC"
+ if [ x$CC_WARNINGS != x ]; then
+ CFLAGS="$CFLAGS $WARNINGS"
+ fi
+
+ echo "CFLAGS=$CFLAGS" | sed 's/= */=/'
+ echo "LDFLAGS=$LDFLAGS" | sed 's/= */=/'
+ echo "LIBS=$LIBS" | sed 's/= */=/'
+
+) > MCONFIG
+
Property changes on: configure
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: ripquery/ripquery.8
===================================================================
--- ripquery/ripquery.8 (nonexistent)
+++ ripquery/ripquery.8 (revision 5)
@@ -0,0 +1,22 @@
+.Dd March 27, 1999
+.Dt RIPQUERY 8
+.Os "Linux NetKit (0.17)"
+.Sh NAME
+.Nm ripquery
+.Nd send a RIP request to a remote host
+.Sh SYNOPSIS
+.Nm ripquery
+.Op Fl n
+host
+.Sh DESCRIPTION
+The
+.Nm ripquery
+command can be used to send a RIP request to a remote host.
+If the remote host runs a RIP server it will reply to the
+RIP request and sends its current routing table entries.
+.Nm ripquery
+will then print these entries. The option
+.Fl n
+can be used to suppress the IP number to name conversion.
+.Sh SEE ALSO
+.Xr routed 8
Index: ripquery
===================================================================
--- ripquery (nonexistent)
+++ ripquery (revision 5)
Property changes on: ripquery
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: routed/defs.h
===================================================================
--- routed/defs.h (nonexistent)
+++ routed/defs.h (revision 5)
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * from: @(#)defs.h 5.10 (Berkeley) 2/28/91
+ * from: @(#)defs.h 8.1 (Berkeley) 6/5/93
+ * $Id: defs.h,v 1.10 2000/12/25 14:56:55 jr Exp $
+ */
+
+/*
+ * Internal data structure definitions for
+ * user routing process. Based on Xerox NS
+ * protocol specs with mods relevant to more
+ * general addressing scheme.
+ */
+
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <protocols/routed.h>
+#include <arpa/inet.h>
+
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "trace.h"
+#include "interface.h"
+#include "table.h"
+#include "af.h"
+
+/*
+ * When we find any interfaces marked down we rescan the
+ * kernel every CHECK_INTERVAL seconds to see if they've
+ * come up.
+ */
+#define CHECK_INTERVAL (1*60)
+
+#define equal(a1, a2) \
+ (memcmp((a1), (a2), sizeof (struct sockaddr)) == 0)
+
+extern struct sockaddr_in addr; /* address of daemon's socket */
+
+extern int sock; /* source and sink of all data */
+extern int supplier; /* process should supply updates */
+extern int ignoreptp; /* whether to ignore PTP devices */
+extern int lookforinterfaces; /* if 1 probe kernel for new up interfaces */
+extern struct iflist igniflist; /* holds info about ignored devices */
+extern struct timeval now; /* current idea of time */
+extern struct timeval lastbcast; /* last time all/changes broadcast */
+extern struct timeval lastfullupdate; /* last time full table broadcast */
+extern struct timeval nextbcast; /* time to wait before changes broadcast */
+extern int needupdate; /* true if we need update at nextbcast */
+extern struct sockaddr_in inet_default; /* default inet addr */
+extern int kernel_version; /* kernel we are running under */
+
+extern char packet[MAXPACKETSIZE+1];
+extern struct rip *msg;
+
+extern int rip_port; /* port number we use (network byte order) */
+
+void supply(struct sockaddr *, int, struct interface *, int);
+
+void addrouteforif __P((struct interface *));
+void bumploglevel(void);
+void dumppacket(FILE *, char *, struct sockaddr *, char *,int, struct timeval *);
+void gwkludge(void);
+void hup(int);
+void ifinit(void);
+int inet_maskof(u_long);
+u_long inet_netof_subnet(struct in_addr);
+int inet_rtflags(struct sockaddr *);
+int inet_sendroute(struct rt_entry *, struct sockaddr *);
+void quit(char *);
+int is_ignored(char *);
+void rip_input(struct sockaddr *, struct rip *, int);
+void rtadd(struct sockaddr *, struct sockaddr *, int, int);
+void rtchange(struct rt_entry *, struct sockaddr *, short);
+void rtdefault(void);
+void rtdelete(struct rt_entry *);
+void rtdeleteall(int);
+void rtinit(void);
+int rtioctl(int, struct rtuentry *);
+void sigtrace(int);
+void sndmsg(struct sockaddr *, int, struct interface *, int);
+void timer(int);
+void timevaladd(struct timeval *t1, struct timeval *t2);
+void timevalsub(struct timeval *t1, struct timeval *t2);
+void toall(void (*)(struct sockaddr *, int, struct interface *, int),
+ int, struct interface *);
+void traceoff(void);
+void traceon(char *);
+void trace(struct ifdebug *, struct sockaddr *, char *, int, int);
+void traceaction(FILE *, char *, struct rt_entry *);
+void traceinit(struct interface *);
+void tracenewmetric(FILE *, struct rt_entry *, int);
+
+#define ADD 1
+#define DELETE 2
+#define CHANGE 3
+#define ROOT "root"
+#define NOBODY "nobody"
Index: routed/inet.c
===================================================================
--- routed/inet.c (nonexistent)
+++ routed/inet.c (revision 5)
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * From: @(#)inet.c 5.8 (Berkeley) 6/1/90
+ * From: @(#)inet.c 8.2 (Berkeley) 8/14/93
+ */
+char inet_rcsid[] =
+ "$Id: inet.c,v 1.6 2000/12/25 14:01:30 jr Exp $";
+
+
+/*
+ * Temporarily, copy these routines from the kernel,
+ * as we need to know about subnets.
+ */
+#include "defs.h"
+
+extern struct interface *ifnet;
+
+#if !defined(__GLIBC__) || (__GLIBC__ < 2)
+/*
+ * Formulate an Internet address from network + host.
+ */
+struct in_addr inet_makeaddr(u_long net, u_long host)
+{
+ struct interface *ifp;
+ u_long mask;
+ u_long addr;
+
+ if (IN_CLASSA(net))
+ mask = IN_CLASSA_HOST;
+ else if (IN_CLASSB(net))
+ mask = IN_CLASSB_HOST;
+ else
+ mask = IN_CLASSC_HOST;
+ for (ifp = ifnet; ifp; ifp = ifp->int_next)
+ if ((ifp->int_netmask & net) == ifp->int_net) {
+ mask = ~ifp->int_subnetmask;
+ break;
+ }
+ addr = net | (host & mask);
+ addr = htonl(addr);
+ return (*(struct in_addr *)&addr);
+}
+#endif /* not glibc */
+
+/*
+ * Return the network number from an internet address.
+ */
+u_long inet_netof_subnet(struct in_addr in)
+{
+ u_long i = ntohl(in.s_addr);
+ u_long net;
+ struct interface *ifp;
+
+ if (IN_CLASSA(i))
+ net = i & IN_CLASSA_NET;
+ else if (IN_CLASSB(i))
+ net = i & IN_CLASSB_NET;
+ else
+ net = i & IN_CLASSC_NET;
+
+ /*
+ * Check whether network is a subnet;
+ * if so, return subnet number.
+ */
+ for (ifp = ifnet; ifp; ifp = ifp->int_next)
+ if ((ifp->int_netmask & net) == ifp->int_net)
+ return (i & ifp->int_subnetmask);
+ return (net);
+}
+
+/*
+ * Return the netmask pertaining to an internet address.
+ */
+
+int inet_maskof(u_long inaddr)
+{
+ u_long i = ntohl(inaddr);
+ u_long mask;
+ struct interface *ifp;
+
+ if (i == 0) {
+ mask = 0;
+ } else if (IN_CLASSA(i)) {
+ mask = IN_CLASSA_NET;
+ } else if (IN_CLASSB(i)) {
+ mask = IN_CLASSB_NET;
+ } else
+ mask = IN_CLASSC_NET;
+
+ /*
+ * Check whether network is a subnet;
+ * if so, use the modified interpretation of `host'.
+ */
+ for (ifp = ifnet; ifp; ifp = ifp->int_next) {
+ if (ifp->int_flags & IFF_POINTOPOINT)
+ continue;
+ if ((ifp->int_netmask & i) == ifp->int_net)
+ mask = ifp->int_subnetmask;
+ }
+ return (htonl(mask));
+}
+
+/*
+ * Return RTF_HOST if the address is
+ * for an Internet host, RTF_SUBNET for a subnet,
+ * 0 for a network.
+ */
+
+int inet_rtflags(struct sockaddr *sa)
+{
+ struct sockaddr_in *sin=(struct sockaddr_in *)sa;
+ u_long i = ntohl(sin->sin_addr.s_addr);
+ u_long net, host;
+ struct interface *ifp;
+
+ if (IN_CLASSA(i)) {
+ net = i & IN_CLASSA_NET;
+ host = i & IN_CLASSA_HOST;
+ } else if (IN_CLASSB(i)) {
+ net = i & IN_CLASSB_NET;
+ host = i & IN_CLASSB_HOST;
+ } else {
+ net = i & IN_CLASSC_NET;
+ host = i & IN_CLASSC_HOST;
+ }
+
+ /*
+ * Check whether this network is subnetted;
+ * if so, check whether this is a subnet or a host.
+ */
+ for (ifp = ifnet; ifp; ifp = ifp->int_next)
+ if (net == ifp->int_net) {
+ if (host &~ ifp->int_subnetmask)
+ return (RTF_HOST);
+ else if (ifp->int_subnetmask != ifp->int_netmask)
+ return (RTF_SUBNET);
+ else
+ return (0); /* network */
+ }
+ if (host == 0)
+ return (0); /* network */
+ else
+ return (RTF_HOST);
+}
+
+/*
+ * Return true if a route to subnet/host of route rt should be sent to dst.
+ * Send it only if dst is on the same logical network if not "internal",
+ * otherwise only if the route is the "internal" route for the logical net.
+ */
+
+int inet_sendroute(struct rt_entry *rt, struct sockaddr *sa)
+{
+ struct sockaddr_in *dst=(struct sockaddr_in *)sa;
+ u_long r =
+ ntohl(((struct sockaddr_in *)&rt->rt_dst)->sin_addr.s_addr);
+ u_long d = ntohl(dst->sin_addr.s_addr);
+
+ if (IN_CLASSA(r)) {
+ if ((r & IN_CLASSA_NET) == (d & IN_CLASSA_NET)) {
+ if ((r & IN_CLASSA_HOST) == 0)
+ return ((rt->rt_state & RTS_INTERNAL) == 0);
+ return (1);
+ }
+ if (r & IN_CLASSA_HOST)
+ return (0);
+ return ((rt->rt_state & RTS_INTERNAL) != 0);
+ } else if (IN_CLASSB(r)) {
+ if ((r & IN_CLASSB_NET) == (d & IN_CLASSB_NET)) {
+ if ((r & IN_CLASSB_HOST) == 0)
+ return ((rt->rt_state & RTS_INTERNAL) == 0);
+ return (1);
+ }
+ if (r & IN_CLASSB_HOST)
+ return (0);
+ return ((rt->rt_state & RTS_INTERNAL) != 0);
+ } else {
+ if ((r & IN_CLASSC_NET) == (d & IN_CLASSC_NET)) {
+ if ((r & IN_CLASSC_HOST) == 0)
+ return ((rt->rt_state & RTS_INTERNAL) == 0);
+ return (1);
+ }
+ if (r & IN_CLASSC_HOST)
+ return (0);
+ return ((rt->rt_state & RTS_INTERNAL) != 0);
+ }
+}
Index: routed/interface.h
===================================================================
--- routed/interface.h (nonexistent)
+++ routed/interface.h (revision 5)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * From: @(#)interface.h 5.6 (Berkeley) 6/1/90
+ * From: @(#)interface.h 8.1 (Berkeley) 6/5/93
+ * $Id: interface.h,v 1.8 2000/12/22 19:43:08 jr Exp $
+ */
+
+/*
+ * Routing table management daemon.
+ */
+
+/*
+ * iflist describes array of ignored interface names
+ */
+struct iflist {
+ u_long length;
+ char *array;
+};
+
+/*
+ * An ``interface'' is similar to an ifnet structure,
+ * except it doesn't contain q'ing info, and it also
+ * handles ``logical'' interfaces (remote gateways
+ * that we want to keep polling even if they go down).
+ * The list of interfaces which we maintain is used
+ * in supplying the gratuitous routing table updates.
+ */
+struct interface {
+ struct interface *int_next;
+ struct sockaddr int_addr; /* address on this host */
+ union {
+ struct sockaddr intu_broadaddr;
+ struct sockaddr intu_dstaddr;
+ } int_intu;
+#define int_broadaddr int_intu.intu_broadaddr /* broadcast address */
+#define int_dstaddr int_intu.intu_dstaddr /* other end of p-to-p link */
+ int int_metric; /* init's routing entry */
+ int int_flags; /* see below */
+ /* START INTERNET SPECIFIC */
+ u_long int_net; /* network # */
+ u_long int_netmask; /* net mask for addr */
+ u_long int_subnet; /* subnet # */
+ u_long int_subnetmask; /* subnet mask for addr */
+ /* END INTERNET SPECIFIC */
+ struct ifdebug int_input, int_output; /* packet tracing stuff */
+ int int_ipackets; /* input packets received */
+ int int_opackets; /* output packets sent */
+ char *int_name; /* from kernel if structure */
+ u_short int_transitions; /* times gone up-down */
+};
+
+#if defined(__GLIBC__) && (__GLIBC__ >= 2)
+#include <net/if.h>
+#else /* not glibc */
+
+/*
+ * 0x1 to 0x10 are reused from the kernel's ifnet definitions,
+ * the others agree with the RTS_ flags defined elsewhere.
+ */
+#define IFF_UP 0x1 /* interface is up */
+#define IFF_BROADCAST 0x2 /* broadcast address valid */
+#define IFF_DEBUG 0x4 /* turn on debugging */
+#define IFF_LOOPBACK 0x8 /* software loopback net */
+#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
+
+#endif /* glibc/not glibc */
+
+#define IFF_SUBNET 0x100000 /* interface on subnetted network */
+#define IFF_PASSIVE 0x200000 /* can't tell if up/down */
+#define IFF_INTERFACE 0x400000 /* hardware interface */
+#define IFF_REMOTE 0x800000 /* interface isn't on this machine */
+
+extern struct interface *ifnet;
+
+struct interface *if_ifwithaddr(struct sockaddr *);
+struct interface *if_ifwithdstaddr(struct sockaddr *);
+struct interface *if_ifwithnet(struct sockaddr *);
+struct interface *if_iflookup(struct sockaddr *);
Index: routed/main.c
===================================================================
--- routed/main.c (nonexistent)
+++ routed/main.c (revision 5)
@@ -0,0 +1,431 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+char copyright[] =
+ "@(#) Copyright (c) 1983, 1988, 1993\n"
+ " The Regents of the University of California. All rights reserved.\n";
+
+/*
+ * From: @(#)main.c 5.23 (Berkeley) 7/1/91
+ * From: @(#)main.c 8.1 (Berkeley) 6/5/93
+ */
+char main_rcsid[] =
+ "$Id: main.c,v 1.17 2000/12/23 18:07:39 jr Exp $";
+
+#include "../version.h"
+#include <time.h>
+
+/*
+ * Routing Table Management Daemon
+ */
+
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <sys/file.h>
+
+#include <errno.h>
+/* #include <signal.h> (redundant with defs.h) */
+#include <syslog.h>
+#include <assert.h>
+#include <sys/utsname.h>
+
+#define BUFSPACE (127*1024) /* max. input buffer size to request */
+
+struct sockaddr_in addr; /* address of daemon's socket */
+int sock; /* source and sink of all data */
+char packet[MAXPACKETSIZE+1];
+int rip_port;
+
+int supplier = -1; /* process should supply updates */
+int gateway = 0; /* 1 if we are a gateway to parts beyond */
+int debug = 0;
+int ignoreptp = 0;
+struct iflist igniflist;
+struct rip *msg = (struct rip *)packet;
+int kernel_version;
+
+static void getkversion(void);
+static int getsocket(void);
+static void process(int);
+void addignoredif(char *);
+
+int
+main(int argc, char *argv[])
+{
+ int n, nfd, tflags = 0, ch;
+ struct timeval *tvp, waittime;
+ struct itimerval itval;
+ struct rip *query = msg;
+ fd_set ibits;
+ sigset_t sigset, osigset;
+
+ memset(&igniflist, 0, sizeof(struct iflist));
+ while ((ch = getopt(argc, argv, "sqtdgpi:")) != EOF) {
+ switch (ch) {
+ case 's': supplier = 1; break;
+ case 'q': supplier = 0; break;
+ case 't':
+ tflags++;
+ break;
+ case 'd':
+ debug++;
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ break;
+ case 'g': gateway = 1; break;
+ case 'p': ignoreptp = 1; break;
+ case 'i':
+ addignoredif(optarg);
+ break;
+ default:
+ fprintf(stderr, "usage: routed [ -sqtdgp ] [ -i device ]\n");
+ exit(1);
+ }
+ }
+
+ getkversion();
+
+ sock = getsocket();
+ assert(sock>=0);
+
+ openlog("routed", LOG_PID | LOG_ODELAY, LOG_DAEMON);
+
+ if (debug == 0 && tflags == 0) {
+ switch (fork()) {
+ case -1: perror("fork"); exit(1);
+ case 0: break; /* child */
+ default: exit(0); /* parent */
+ }
+ close(0);
+ close(1);
+ close(2);
+ setsid();
+ setlogmask(LOG_UPTO(LOG_WARNING));
+ }
+ else {
+ setlogmask(LOG_UPTO(LOG_DEBUG));
+ }
+
+ /*
+ * Any extra argument is considered
+ * a tracing log file.
+ *
+ * Note: because traceon() redirects stderr, anything planning to
+ * crash on startup should do so before this point.
+ */
+
+ if (argc > optind) {
+ traceon(argv[optind]);
+ }
+ while (tflags-- > 0) {
+ bumploglevel();
+ }
+
+ gettimeofday(&now, NULL);
+
+ /*
+ * Collect an initial view of the world by
+ * checking the interface configuration and the gateway kludge
+ * file. Then, send a request packet on all
+ * directly connected networks to find out what
+ * everyone else thinks.
+ */
+
+ rtinit();
+ ifinit();
+ gwkludge();
+ if (gateway > 0) {
+ rtdefault();
+ }
+ if (supplier < 0) {
+ supplier = 0;
+ }
+ query->rip_cmd = RIPCMD_REQUEST;
+ query->rip_vers = RIPVERSION;
+ if (sizeof(query->rip_nets[0].rip_dst.sa_family) > 1) {
+ /* XXX */
+ query->rip_nets[0].rip_dst.sa_family = htons((u_short)AF_UNSPEC);
+ }
+ else {
+ /* unreachable code (at least on most platforms) */
+ query->rip_nets[0].rip_dst.sa_family = AF_UNSPEC;
+ }
+ query->rip_nets[0].rip_metric = htonl((u_long)HOPCNT_INFINITY);
+
+ toall(sndmsg, 0, NULL);
+
+ signal(SIGALRM, timer);
+ signal(SIGHUP, hup);
+ signal(SIGTERM, hup);
+ signal(SIGINT, rtdeleteall);
+ signal(SIGUSR1, sigtrace);
+ signal(SIGUSR2, sigtrace);
+
+ itval.it_interval.tv_sec = TIMER_RATE;
+ itval.it_value.tv_sec = TIMER_RATE;
+ itval.it_interval.tv_usec = 0;
+ itval.it_value.tv_usec = 0;
+
+ srandom(time(NULL) ^ getpid());
+
+ if (setitimer(ITIMER_REAL, &itval, (struct itimerval *)NULL) < 0) {
+ syslog(LOG_ERR, "setitimer: %m\n");
+ }
+
+ FD_ZERO(&ibits);
+ nfd = sock + 1; /* 1 + max(fd's) */
+ for (;;) {
+ FD_SET(sock, &ibits);
+
+ /*
+ * If we need a dynamic update that was held off,
+ * needupdate will be set, and nextbcast is the time
+ * by which we want select to return. Compute time
+ * until dynamic update should be sent, and select only
+ * until then. If we have already passed nextbcast,
+ * just poll.
+ */
+ if (needupdate) {
+ waittime = nextbcast;
+ timevalsub(&waittime, &now);
+ if (waittime.tv_sec < 0) {
+ waittime.tv_sec = 0;
+ waittime.tv_usec = 0;
+ }
+ if (traceactions)
+ fprintf(ftrace,
+ "select until dynamic update %ld/%ld sec/usec\n",
+ (long)waittime.tv_sec, (long)waittime.tv_usec);
+ tvp = &waittime;
+ }
+ else {
+ tvp = (struct timeval *)NULL;
+ }
+
+ n = select(nfd, &ibits, 0, 0, tvp);
+ if (n <= 0) {
+ /*
+ * Need delayed dynamic update if select returned
+ * nothing and we timed out. Otherwise, ignore
+ * errors (e.g. EINTR).
+ */
+ if (n < 0) {
+ if (errno == EINTR)
+ continue;
+ syslog(LOG_ERR, "select: %m");
+ }
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGALRM);
+ sigprocmask(SIG_BLOCK, &sigset, &osigset);
+ if (n == 0 && needupdate) {
+ if (traceactions)
+ fprintf(ftrace,
+ "send delayed dynamic update\n");
+ (void) gettimeofday(&now,
+ (struct timezone *)NULL);
+ toall(supply, RTS_CHANGED,
+ (struct interface *)NULL);
+ lastbcast = now;
+ needupdate = 0;
+ nextbcast.tv_sec = 0;
+ }
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ continue;
+ }
+
+ gettimeofday(&now, (struct timezone *)NULL);
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGALRM);
+ sigprocmask(SIG_BLOCK, &sigset, &osigset);
+
+ if (FD_ISSET(sock, &ibits)) {
+ process(sock);
+ }
+
+ /* handle ICMP redirects */
+ sigprocmask(SIG_SETMASK, &osigset, NULL);
+ }
+}
+
+/*
+ * Put Linux kernel version into
+ * the global variable kernel_version.
+ * Example: 1.2.8 = 0x010208
+ */
+
+static
+void
+getkversion(void)
+{
+ struct utsname uts;
+ int maj, min, pl;
+
+ maj = min = pl = 0;
+ uname(&uts);
+ sscanf(uts.release, "%d.%d.%d", &maj, &min, &pl);
+ kernel_version = (maj << 16) | (min << 8) | pl;
+}
+
+void
+timevaladd(struct timeval *t1, struct timeval *t2)
+{
+
+ t1->tv_sec += t2->tv_sec;
+ if ((t1->tv_usec += t2->tv_usec) > 1000000) {
+ t1->tv_sec++;
+ t1->tv_usec -= 1000000;
+ }
+}
+
+void
+timevalsub(struct timeval *t1, struct timeval *t2)
+{
+
+ t1->tv_sec -= t2->tv_sec;
+ if ((t1->tv_usec -= t2->tv_usec) < 0) {
+ t1->tv_sec--;
+ t1->tv_usec += 1000000;
+ }
+}
+
+static
+void
+process(int fd)
+{
+ struct sockaddr from;
+ socklen_t fromlen;
+ int cc;
+ union {
+ char buf[MAXPACKETSIZE+1];
+ struct rip rip;
+ } inbuf;
+
+ for (;;) {
+ fromlen = sizeof(from);
+ cc = recvfrom(fd, &inbuf, sizeof(inbuf), 0, &from, &fromlen);
+ if (cc <= 0) {
+ if (cc < 0 && errno != EWOULDBLOCK)
+ perror("recvfrom");
+ break;
+ }
+ if (fromlen != sizeof (struct sockaddr_in)) {
+ break;
+ }
+ rip_input(&from, &inbuf.rip, cc);
+ }
+}
+
+/*
+ * This function is called during startup, and should error to stderr,
+ * not syslog, and should exit on error.
+ */
+static
+int
+getsocket(void)
+{
+ int s, on = 1;
+ struct servent *sp;
+
+ sp = getservbyname("router", "udp");
+ if (sp == NULL) {
+ fprintf(stderr, "routed: router/udp: unknown service\n");
+ exit(1);
+ }
+ rip_port = sp->s_port;
+
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s < 0) {
+ perror("socket");
+ exit(1);
+ }
+
+#ifdef SO_BROADCAST
+ if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) {
+ perror("setsockopt SO_BROADCAST");
+ exit(1);
+ }
+#endif
+
+#ifdef SO_RCVBUF
+ on = BUFSPACE;
+ while (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof(on))) {
+ if (on <= 8192) {
+ /* give up */
+ perror("setsockopt SO_RCVBUF");
+ break;
+ }
+ /* try 1k less */
+ on -= 1024;
+ }
+ if (traceactions) {
+ fprintf(ftrace, "recv buf %d\n", on);
+ }
+#endif
+
+ addr.sin_family = AF_INET;
+ addr.sin_port = rip_port;
+
+ if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
+ perror("bind");
+ close(s);
+ exit(1);
+ }
+
+ if (fcntl(s, F_SETFL, O_NONBLOCK) == -1) {
+ perror("fcntl O_NONBLOCK");
+ }
+
+ return (s);
+}
+
+/*
+ * Add single interface name to the list of ignored interface names.
+ */
+void
+addignoredif(char *ifn)
+{
+ char *ifl = NULL;
+
+ /* avoiding realloc() */
+ ifl = calloc(1, igniflist.length * IFNAMSIZ + IFNAMSIZ);
+ if (ifl == NULL) {
+ syslog(LOG_ERR, "routed: addignoredif: out of memory\n");
+ return;
+ }
+ memcpy(ifl, igniflist.array, igniflist.length * IFNAMSIZ);
+ memcpy(ifl + igniflist.length++ * IFNAMSIZ,
+ ifn,
+ strlen(ifn) >= IFNAMSIZ ? IFNAMSIZ - 1 : strlen (ifn));
+ if (igniflist.array != NULL)
+ free(igniflist.array);
+ igniflist.array = ifl;
+}
Index: routed/routed.8
===================================================================
--- routed/routed.8 (nonexistent)
+++ routed/routed.8 (revision 5)
@@ -0,0 +1,433 @@
+.\" Copyright (c) 1983, 1991, 1993
+.\" The Regents of the University of California. 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.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and 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.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+.\"
+.\" From: @(#)routed.8 6.6 (Berkeley) 3/16/91
+.\" From: @(#)routed.8 8.2 (Berkeley) 12/11/93
+.\" From: NetBSD: routed.8,v 1.6 1995/03/18 15:00:38 cgd Exp
+.\" $Id: routed.8,v 1.16 2000/12/25 14:36:27 jr Exp $
+.\"
+.Dd December 11, 1993
+.Dt ROUTED 8
+.Os "Linux NetKit (0.18)"
+.Sh NAME
+.Nm routed
+.Nd network routing daemon
+.Sh SYNOPSIS
+.Nm routed
+.Op Fl d
+.Op Fl g
+.Op Fl s
+.Op Fl q
+.Op Fl t
+.Op Fl p
+.Op Fl i Nm device
+.Op Ar logfile
+.Sh DESCRIPTION
+.Nm Routed
+is invoked at boot time to manage the network routing tables.
+The routing daemon uses a variant of the Xerox NS Routing
+Information Protocol in maintaining up to date kernel routing
+table entries.
+It used a generalized protocol capable of use with multiple
+address types, but is currently used only for Internet routing
+within a cluster of networks.
+.Pp
+In normal operation
+.Nm routed
+listens on the
+.Xr udp 4
+socket for the
+.Xr route 8
+service (see
+.Xr services 5 )
+for routing information packets. If the host is an
+internetwork router, it periodically supplies copies
+of its routing tables to any directly connected hosts
+and networks.
+.Pp
+When
+.Nm routed
+is started, it uses the
+.Dv SIOCGIFCONF
+.Xr ioctl 2
+to find those
+directly connected interfaces configured into the
+system and marked ``up'' (the software loopback interface
+is ignored). If multiple interfaces
+are present, it is assumed that the host will forward packets
+between networks.
+.Nm Routed
+then transmits a
+.Em request
+packet on each interface (using a broadcast packet if
+the interface supports it) and enters a loop, listening
+for
+.Em request
+and
+.Em response
+packets from other hosts.
+.Pp
+When a
+.Em request
+packet is received,
+.Nm routed
+formulates a reply based on the information maintained in its
+internal tables. The
+.Em response
+packet generated contains a list of known routes, each marked
+with a ``hop count'' metric (a count of 16, or greater, is
+considered ``infinite''). The metric associated with each
+route returned provides a metric
+.Em relative to the sender .
+.Pp
+.Em Response
+packets received by
+.Nm routed
+are used to update the routing tables if one of the following
+conditions is satisfied:
+.Bl -enum
+.It
+No routing table entry exists for the destination network
+or host, and the metric indicates the destination is ``reachable''
+(i.e. the hop count is not infinite).
+.It
+The source host of the packet is the same as the router in the
+existing routing table entry. That is, updated information is
+being received from the very internetwork router through which
+packets for the destination are being routed.
+.It
+The existing entry in the routing table has not been updated for
+some time (defined to be 90 seconds) and the route is at least
+as cost effective as the current route.
+.It
+The new route describes a shorter route to the destination than
+the one currently stored in the routing tables; the metric of
+the new route is compared against the one stored in the table
+to decide this.
+.El
+.Pp
+When an update is applied,
+.Nm routed
+records the change in its internal tables and updates the kernel
+routing table.
+The change is reflected in the next
+.Em response
+packet sent.
+.Pp
+In addition to processing incoming packets,
+.Nm routed
+also periodically checks the routing table entries.
+If an entry has not been updated for 3 minutes, the entry's metric
+is set to infinity and marked for deletion. Deletions are delayed
+an additional 60 seconds to insure the invalidation is propagated
+throughout the local internet.
+.Pp
+Hosts acting as internetwork routers gratuitously supply their
+routing tables every 30 seconds to all directly connected hosts
+and networks.
+The response is sent to the broadcast address on nets capable of that function,
+to the destination address on point-to-point links, and to the router's
+own address on other networks.
+The normal routing tables are bypassed when sending gratuitous responses.
+The reception of responses on each network is used to determine that the
+network and interface are functioning correctly.
+If no response is received on an interface, another route may be chosen
+to route around the interface, or the route may be dropped if no alternative
+is available.
+.Pp
+Options supported by
+.Nm routed :
+.Bl -tag -width Ds
+.It Fl d
+Enable additional debugging information to be logged,
+such as bad packets received.
+.It Fl g
+This flag is used on internetwork routers to offer a route
+to the ``default'' destination.
+This is typically used on a gateway to the Internet,
+or on a gateway that uses another routing protocol whose routes
+are not reported to other local routers.
+.It Fl s
+Supplying this
+option forces
+.Nm routed
+to supply routing information that it is acting as an internetwork
+router.
+This is the default if multiple network interfaces are present,
+or if a point-to-point link is in use.
+.It Fl q
+This
+is the opposite of the
+.Fl s
+option.
+.It Fl t
+If the
+.Fl t
+option is specified, all packets sent or received are
+printed on the standard output. In addition,
+.Nm routed
+will not divorce itself from the controlling terminal
+so that interrupts from the keyboard will kill the process.
+.It Fl p
+this option forces
+.Nm routed
+to ignore existence of all point-to-point network interfaces.
+.Nm Routed
+wont send nor receive routing updates through these interfaces
+and also wont propagate corresponding routes to remote endpoints directly
+reachable through them. Sometimes it is not desirable to send/receive
+routing information about routes through such interfaces, for example
+when point-to-point link with proxy-arp is in use.
+.It Fl i Nm dev
+this option forces
+.Nm routed
+to ignore existence of a specified network interface
+.Nm dev .
+Similarly to
+.Fl p
+flag, routed wont send nor receive routing updates through
+.Nm dev ,
+nor it will advertise direct routes via such interface.
+.El
+.Pp
+Any other argument supplied is interpreted as the full path to and name
+of file in which
+.Nm routed Ns \'s
+actions should be logged. This log contains information
+about any changes to the routing tables and, if not tracing all packets,
+a history of recent messages sent and received which are related to
+the changed route.
+With first event to be logged,
+.Nm routed
+will create log file in "/var/log/routed" directory (which has to
+exist and be readable/writeable only by root). For security reasons,
+this argument has to begin with "/var/log/routed", as
+.Nm routed
+itself does not perform other security checks towards validity of the
+remote traceon/traceoff requests it may receive. Unless
+for debugging purposes, it is strongly recommended that the logging
+path itself does not exist nor is specified as
+.Nm routed
+parameter at all.
+.Pp
+In addition to the facilities described above,
+.Nm routed
+supports the notion of ``distant''
+.Em passive
+,
+.Em active
+,
+.Em external
+and
+.Em announced
+gateway types. When
+.Nm routed
+is started up, it reads the file
+.Pa /etc/gateways
+to find gateways which may not be located using
+only information from the
+.Dv SIOGIFCONF
+.Xr ioctl 2 .
+Gateways specified in this manner should be marked passive
+if they are not expected to exchange routing information,
+while gateways marked active
+should be willing to exchange routing information (i.e.
+they should have a
+.Nm routed
+process running on the machine).
+.Pp
+Routes through
+.Nm passive
+gateways are installed in the
+kernel's routing tables by
+.Nm routed
+once upon its startup. Such routes are not included
+in any routing information transmitted.
+.Pp
+.Nm Active
+gateways are treated equally to network
+interfaces. Routing information is distributed
+to the gateway and
+.Nm routed
+listens for updates on the interface that the gateway is
+reachable through.
+.Pp
+Gateways marked
+.Nm external
+are also passive, but are not placed in the kernel
+routing table nor are they included in routing updates.
+The function of
+.Nm external
+entries is to inform
+.Nm routed
+that another routing process
+will install such a route, so that it should not install
+alternate routes to that destination.
+Such entries are only required when both routers may learn of routes
+to the same destination.
+.Pp
+Routes to networks through gateways marked as
+.Nm announced
+will be included in each routing advertisement, but won't be installed
+in the kernel routing table. This kind of entries is only required
+for the gateways that are directly reachable, but are unable
+to announce their routes, so that the rest of the RIP1 protocol-equipped
+network will know about such routes too. Entries of
+.Nm announced
+type can also be used to announce direct routes for own interfaces, that
+didn't exist at the time when
+.Nm routed
+has been started, but can be expected to come up later
+(such as routes for point-to-point interfaces).
+.Pp
+The
+.Pa /etc/gateways
+is comprised of a series of lines, each in
+the following format:
+.Bd -ragged
+.Pf < Cm net No \&|
+.Cm host Ns >
+.Ar name1
+.Cm gateway
+.Ar name2
+.Cm metric
+.Ar value
+.Pf < Cm passive No \&|
+.Cm active No \&|
+.Cm external No \&|
+.Cm announced Ns >
+.Ed
+.Pp
+The
+.Cm net
+or
+.Cm host
+keyword indicates if the route is to a network or specific host.
+.Pp
+.Ar Name1
+is the name of the destination network or host. This may be a
+symbolic name located in
+.Pa /etc/networks
+or
+.Pa /etc/hosts
+(or, if started after
+.Xr named 8 ,
+known to the name server),
+or an Internet address specified in ``dot'' notation; see
+.Xr inet 3 .
+.Pp
+.Ar Name2
+is the name or address of the gateway to which messages should
+be forwarded.
+.Pp
+.Ar Value
+is a metric indicating the hop count to the destination host
+or network.
+.Pp
+One of the keywords
+.Cm passive ,
+.Cm active ,
+.Cm external
+or
+.Cm announced
+indicates if the gateway should be treated as
+.Em passive
+or
+.Em active
+(as described above),
+whether the gateway is
+.Em external
+to the scope of the
+.Nm routed
+protocol, or whether
+the route reachable via such gateway should
+be included in the routing table announcements.
+.Pp
+Internetwork routers that are directly attached to the Arpanet or Milnet
+should use the Exterior Gateway Protocol
+.Pq Tn EGP
+to gather routing information
+rather than using a static routing table of passive gateways.
+.Tn EGP
+is required in order to provide routes for local networks to the rest
+of the Internet system.
+.Sh FILES
+.Bl -tag -width /etc/gateways -compact
+.It Pa /etc/gateways
+for distant gateways
+.El
+.Sh SEE ALSO
+.Xr udp 7 ,
+.Xr icmp 7 .
+.Rs
+.%T Internet Transport Protocols
+.%R XSIS 028112
+.%Q Xerox System Integration Standard
+.Re
+.Sh BUGS
+.Pp
+.Nm Routed
+is heavily 32bit architecture dependant. You should eventually
+consider using
+.Xr gated 8
+or
+.Xr zebra 8 .
+.Pp
+The kernel's routing tables may not correspond to those of
+.Nm routed
+when redirects change or add routes.
+.Nm Routed
+should note any redirects received by reading
+the
+.Tn ICMP
+packets received via a raw socket.
+.Pp
+.Nm Routed
+also doesn't notice of any new interface, that didn't exist prior to
+its start, but has newly appeared and come to ``up'' state after
+routed has been started, and won't announce route for such interface.
+.Pp
+.Nm Routed
+should incorporate other routing protocols.
+Using separate processes for each requires configuration options
+to avoid redundant or competing routes.
+.Pp
+.Nm Routed
+should listen to intelligent interfaces, such as an
+.Tn IMP ,
+to gather more information.
+It does not always detect unidirectional failures in network interfaces
+(e.g., when the output side fails).
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.2 .
Index: routed/startup.c
===================================================================
--- routed/startup.c (nonexistent)
+++ routed/startup.c (revision 5)
@@ -0,0 +1,545 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * From: @(#)startup.c 5.19 (Berkeley) 2/28/91
+ * From: @(#)startup.c 8.1 (Berkeley) 6/5/93
+ */
+char startup_rcsid[] =
+ "$Id: startup.c,v 1.11 2000/12/25 14:32:34 jr Exp $";
+
+
+/*
+ * Routing Table Management Daemon
+ */
+
+#include "defs.h"
+#include <sys/ioctl.h>
+/* #include <net/if.h> (redundant with defs.h) */
+#include <syslog.h>
+#include <errno.h>
+#include "pathnames.h"
+
+struct interface *ifnet;
+struct interface **ifnext = &ifnet;
+int lookforinterfaces = 1;
+int foundloopback; /* valid flag for loopaddr */
+struct sockaddr loopaddr; /* our address on loopback */
+
+static int externalinterfaces = 0; /* # of remote and local interfaces */
+
+void add_ptopt_localrt(struct interface *);
+int getnetorhostname(char *, char *, struct sockaddr_in *);
+int gethostnameornumber(char *, struct sockaddr_in *);
+
+void quit(char *s)
+{
+ int sverrno = errno;
+
+ (void) fprintf(stderr, "route: ");
+ if (s)
+ (void) fprintf(stderr, "%s: ", s);
+ (void) fprintf(stderr, "%s\n", strerror(sverrno));
+ exit(1);
+}
+
+int is_ignored(char *ifname)
+{
+ u_long i;
+
+ for (i = 0; i < igniflist.length; i++)
+ if (!(strcmp(ifname, igniflist.array + i * IFNAMSIZ)) )
+ return (1);
+
+ return (0);
+}
+
+#define ROUNDUP(a) \
+ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
+
+/*
+ * Find the network interfaces which have configured themselves.
+ * If the interface is present but not yet up (for example an
+ * ARPANET IMP), set the lookforinterfaces flag so we'll
+ * come back later and look again.
+ */
+
+void ifinit(void)
+{
+ struct interface ifs, *ifp;
+ int s, maxifaces = 16;
+ char *cp;
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ struct sockaddr_in *sin;
+ u_long i;
+
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ syslog(LOG_ERR, "socket: %m");
+ close(s);
+ return;
+ }
+ for (;;) {
+ ifc.ifc_len = sizeof(struct ifreq) * maxifaces;
+ ifc.ifc_buf = malloc(ifc.ifc_len);
+ if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+ syslog(LOG_ERR, "ioctl (get interface configuration)");
+ return;
+ }
+ /*
+ * Assume overflow (more interfaces). Increase size/repeat.
+ */
+ if (ifc.ifc_len == (int) sizeof(struct ifreq) * maxifaces) {
+ maxifaces += 16;
+ free(ifc.ifc_buf);
+ continue;
+ }
+ break;
+ }
+ lookforinterfaces = 0;
+ for (cp = ifc.ifc_buf; cp < (ifc.ifc_buf + ifc.ifc_len);
+ cp += sizeof(struct ifreq)) {
+ ifr = (struct ifreq *)cp;
+ bzero((char *)&ifs, sizeof(ifs));
+ ifs.int_addr = ifr->ifr_addr;
+ ifreq = *ifr;
+ if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "%s: ioctl (get interface flags)",
+ ifr->ifr_name);
+ continue;
+ }
+ ifs.int_flags =
+ ifreq.ifr_flags | IFF_INTERFACE;
+ if ((ifs.int_flags & IFF_UP) == 0 ||
+ ifr->ifr_addr.sa_family == AF_UNSPEC) {
+ lookforinterfaces = 1;
+ continue;
+ }
+ /* argh, this'll have to change sometime */
+ if (ifs.int_addr.sa_family != AF_INET)
+ continue;
+ if (is_ignored(ifr->ifr_name))
+ continue;
+ if (ifs.int_flags & IFF_POINTOPOINT) {
+ if (ignoreptp)
+ continue;
+ if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "%s: ioctl (get dstaddr)",
+ ifr->ifr_name);
+ continue;
+ }
+ if (ifr->ifr_addr.sa_family == AF_UNSPEC) {
+ lookforinterfaces = 1;
+ continue;
+ }
+ ifs.int_dstaddr = ifreq.ifr_dstaddr;
+ }
+ /*
+ * already known to us?
+ * This allows multiple point-to-point links
+ * to share a source address (possibly with one
+ * other link), but assumes that there will not be
+ * multiple links with the same destination address.
+ */
+ if (ifs.int_flags & IFF_POINTOPOINT) {
+ if (if_ifwithdstaddr(&ifs.int_dstaddr))
+ continue;
+ } else if (if_ifwithaddr(&ifs.int_addr))
+ continue;
+ if (ifs.int_flags & IFF_LOOPBACK) {
+ ifs.int_flags |= IFF_PASSIVE;
+ foundloopback = 1;
+ loopaddr = ifs.int_addr;
+ for (ifp = ifnet; ifp; ifp = ifp->int_next)
+ if (ifp->int_flags & IFF_POINTOPOINT)
+ add_ptopt_localrt(ifp);
+ }
+ if (ifs.int_flags & IFF_BROADCAST) {
+ if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "%s: ioctl (get broadaddr)",
+ ifr->ifr_name);
+ continue;
+ }
+ ifs.int_broadaddr = ifreq.ifr_broadaddr;
+ }
+#ifdef SIOCGIFMETRIC
+ if (ioctl(s, SIOCGIFMETRIC, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "%s: ioctl (get metric)",
+ ifr->ifr_name);
+ ifs.int_metric = 0;
+ } else
+ ifs.int_metric = ifreq.ifr_metric;
+#else
+ ifs.int_metric = 0;
+#endif
+ /*
+ * Use a minimum metric of one;
+ * treat the interface metric (default 0)
+ * as an increment to the hop count of one.
+ */
+ ifs.int_metric++;
+ if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+ syslog(LOG_ERR, "%s: ioctl (get netmask)",
+ ifr->ifr_name);
+ continue;
+ }
+ sin = (struct sockaddr_in *)&ifreq.ifr_addr;
+ ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr);
+ sin = (struct sockaddr_in *)&ifs.int_addr;
+ i = ntohl(sin->sin_addr.s_addr);
+ if (IN_CLASSA(i))
+ ifs.int_netmask = IN_CLASSA_NET;
+ else if (IN_CLASSB(i))
+ ifs.int_netmask = IN_CLASSB_NET;
+ else
+ ifs.int_netmask = IN_CLASSC_NET;
+ ifs.int_net = i & ifs.int_netmask;
+ ifs.int_subnet = i & ifs.int_subnetmask;
+ if (ifs.int_subnetmask != ifs.int_netmask)
+ ifs.int_flags |= IFF_SUBNET;
+ ifp = (struct interface *)malloc(sizeof (struct interface));
+ if (ifp == 0) {
+ printf("routed: out of memory\n");
+ break;
+ }
+ *ifp = ifs;
+ /*
+ * Count the # of directly connected networks
+ * and point to point links which aren't looped
+ * back to ourself. This is used below to
+ * decide if we should be a routing ``supplier''.
+ */
+ if ((ifs.int_flags & IFF_LOOPBACK) == 0 &&
+ ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
+ if_ifwithaddr(&ifs.int_dstaddr) == 0))
+ externalinterfaces++;
+ /*
+ * If we have a point-to-point link, we want to act
+ * as a supplier even if it's our only interface,
+ * as that's the only way our peer on the other end
+ * can tell that the link is up.
+ */
+ if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
+ supplier = 1;
+ ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
+ if (ifp->int_name == NULL) {
+ fprintf(stderr, "routed: ifinit: out of memory\n");
+ syslog(LOG_ERR, "routed: ifinit: out of memory\n");
+ goto escape;
+ }
+ strcpy(ifp->int_name, ifr->ifr_name);
+ *ifnext = ifp;
+ ifnext = &ifp->int_next;
+ traceinit(ifp);
+ addrouteforif(ifp);
+ }
+ if (externalinterfaces > 1 && supplier < 0)
+ supplier = 1;
+escape:
+ free(ifc.ifc_buf);
+ close(s);
+ return;
+}
+
+/*
+ * Add route for interface if not currently installed.
+ * Create route to other end if a point-to-point link,
+ * otherwise a route to this (sub)network.
+ * INTERNET SPECIFIC.
+ */
+
+void addrouteforif(struct interface *ifp)
+{
+ struct sockaddr_in net;
+ struct sockaddr *dst;
+ int state;
+ struct rt_entry *rt;
+
+ if (ifp->int_flags & IFF_POINTOPOINT)
+ dst = &ifp->int_dstaddr;
+ else {
+ memset(&net, 0, sizeof (net));
+ net.sin_family = AF_INET;
+ net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
+ dst = (struct sockaddr *)&net;
+ }
+ rt = rtfind(dst);
+ if (rt &&
+ (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE)
+ return;
+ if (rt)
+ rtdelete(rt);
+ /*
+ * If interface on subnetted network,
+ * install route to network as well.
+ * This is meant for external viewers.
+ */
+ if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
+ struct in_addr subnet;
+
+ subnet = net.sin_addr;
+ net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
+ rt = rtfind(dst);
+ if (rt == 0)
+ rtadd(dst, &ifp->int_addr, ifp->int_metric,
+ ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) |
+ RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET));
+ else if ((rt->rt_state & (RTS_INTERNAL|RTS_SUBNET)) ==
+ (RTS_INTERNAL|RTS_SUBNET) &&
+ ifp->int_metric < rt->rt_metric)
+ rtchange(rt, &rt->rt_router, ifp->int_metric);
+ net.sin_addr = subnet;
+ }
+ if (ifp->int_transitions++ > 0)
+ syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
+ state = ifp->int_flags &
+ (IFF_INTERFACE | IFF_PASSIVE | IFF_REMOTE | IFF_SUBNET);
+ if (ifp->int_flags & IFF_POINTOPOINT &&
+ (ntohl(((struct sockaddr_in *)&ifp->int_dstaddr)->sin_addr.s_addr) &
+ ifp->int_netmask) != ifp->int_net)
+ state &= ~RTS_SUBNET;
+ if (ifp->int_flags & IFF_LOOPBACK)
+ state |= RTS_EXTERNAL;
+ rtadd(dst, &ifp->int_addr, ifp->int_metric, state);
+ if (ifp->int_flags & IFF_POINTOPOINT && foundloopback)
+ add_ptopt_localrt(ifp);
+}
+
+/*
+ * Add route to local end of point-to-point using loopback.
+ * If a route to this network is being sent to neighbors on other nets,
+ * mark this route as subnet so we don't have to propagate it too.
+ */
+
+void add_ptopt_localrt(struct interface *ifp)
+{
+ struct rt_entry *rt;
+ struct sockaddr *dst;
+ struct sockaddr_in net;
+ int state;
+
+ state = RTS_INTERFACE | RTS_PASSIVE;
+
+ /* look for route to logical network */
+ memset(&net, 0, sizeof (net));
+ net.sin_family = AF_INET;
+ net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
+ dst = (struct sockaddr *)&net;
+ rt = rtfind(dst);
+ if (rt && rt->rt_state & RTS_INTERNAL)
+ state |= RTS_SUBNET;
+
+ dst = &ifp->int_addr;
+ if ((rt = rtfind(dst))!=NULL) {
+ if (rt && rt->rt_state & RTS_INTERFACE)
+ return;
+ rtdelete(rt);
+ }
+ rtadd(dst, &loopaddr, 1, state);
+}
+
+/*
+ * As a concession to the ARPANET we read a list of gateways
+ * from /etc/gateways and add them to our tables. This file
+ * exists at each ARPANET gateway and indicates a set of ``remote''
+ * gateways (i.e. a gateway which we can't immediately determine
+ * if it's present or not as we can do for those directly connected
+ * at the hardware level). If a gateway is marked ``passive''
+ * in the file, then we assume it doesn't have a routing process
+ * of our design and simply assume it's always present. Those
+ * not marked passive, external nor announced are treated as if they
+ * were directly connected -- they're added into the interface list
+ * so we'll send them routing updates.
+ *
+ * PASSIVE ENTRIES AREN'T NEEDED OR USED ON GATEWAYS RUNNING EGP.
+ */
+
+void gwkludge(void)
+{
+ struct sockaddr_in dst, gate;
+ FILE *fp;
+ char *type, *dname, *gname, *qual, buf[BUFSIZ];
+ struct interface *ifp;
+ int metric, n;
+ struct rt_entry route;
+
+ fp = fopen(_PATH_GATEWAYS, "r");
+ if (fp == NULL)
+ return;
+ qual = buf;
+ dname = buf + 64;
+ gname = buf + ((BUFSIZ - 64) / 3);
+ type = buf + (((BUFSIZ - 64) * 2) / 3);
+ memset(&dst, 0, sizeof (dst));
+ memset(&gate, 0, sizeof (gate));
+ memset(&route, 0, sizeof(route));
+ /*
+ * format:
+ * {net | host} XX gateway XX metric DD [passive | external | announced]
+ */
+#define readentry(fp) \
+ fscanf((fp), "%s %s gateway %s metric %d %s\n", \
+ type, dname, gname, &metric, qual)
+ for (;;) {
+ if ((n = readentry(fp)) == EOF)
+ break;
+ /*
+ * Lusertrap. Vendors should ship the line
+ *
+ * CONFIGME CONFIGME gateway CONFIGME metric 1
+ *
+ */
+ if (strcmp(type,"CONFIGME")==0)
+ {
+ fprintf(stderr,"Not starting gated. Please configure first.\n");
+ exit(1);
+ }
+ if (!getnetorhostname(type, dname, &dst))
+ continue;
+ if (!gethostnameornumber(gname, &gate))
+ continue;
+ if (metric == 0) /* XXX */
+ metric = 1;
+ if (strcmp(qual, "passive") == 0) {
+ /*
+ * Passive entries aren't placed in our tables,
+ * only the kernel's, so we don't copy all of the
+ * external routing information within a net.
+ * Internal machines should use the default
+ * route to a suitable gateway (like us).
+ */
+ route.rt_dst = *(struct sockaddr *) &dst;
+ route.rt_router = *(struct sockaddr *) &gate;
+ route.rt_flags = RTF_UP;
+ if (strcmp(type, "host") == 0)
+ route.rt_flags |= RTF_HOST;
+ if (metric)
+ route.rt_flags |= RTF_GATEWAY;
+ (void) rtioctl(ADD, &route.rt_rt);
+ continue;
+ }
+ if (strcmp(qual, "external") == 0) {
+ /*
+ * Entries marked external are handled
+ * by other means, e.g. EGP,
+ * and are placed in our tables only
+ * to prevent overriding them
+ * with something else.
+ */
+ rtadd((struct sockaddr *)&dst,
+ (struct sockaddr *)&gate, metric,
+ RTS_EXTERNAL|RTS_PASSIVE);
+ continue;
+ }
+ if (strcmp(qual, "announced") == 0) {
+ /*
+ * Entries marked "announced" are added
+ * into our internal tables and advertised,
+ * but not added to the kernel routing table.
+ * This allows sort of route "injection" to RIP1
+ * network for routes through directly reachable
+ * gateways that arent capable of RIP1 advertising
+ * themselves.
+ */
+ rtadd((struct sockaddr *)&dst,
+ (struct sockaddr *)&gate, metric,
+ RTS_CHANGED|RTS_PASSIVE|RTS_INTERNAL);
+ continue;
+ }
+ /* assume no duplicate entries */
+ externalinterfaces++;
+ ifp = (struct interface *)malloc(sizeof (*ifp));
+ memset(ifp, 0, sizeof (*ifp));
+ ifp->int_flags = IFF_REMOTE;
+ /* can't identify broadcast capability */
+ ifp->int_net = inet_netof_subnet(dst.sin_addr);
+ if (strcmp(type, "host") == 0) {
+ ifp->int_flags |= IFF_POINTOPOINT;
+ ifp->int_dstaddr = *((struct sockaddr *)&dst);
+ }
+ ifp->int_addr = *((struct sockaddr *)&gate);
+ ifp->int_metric = metric;
+ ifp->int_next = ifnet;
+ ifnet = ifp;
+ addrouteforif(ifp);
+ }
+ fclose(fp);
+}
+
+int getnetorhostname(char *type, char *name, struct sockaddr_in *sin)
+{
+
+ if (strcmp(type, "net") == 0) {
+ struct netent *np = getnetbyname(name);
+ int n;
+
+ if (np == 0)
+ n = inet_network(name);
+ else {
+ if (np->n_addrtype != AF_INET)
+ return (0);
+ n = np->n_net;
+ /*
+ * getnetbyname returns right-adjusted value.
+ */
+ if (n < 128)
+ n <<= IN_CLASSA_NSHIFT;
+ else if (n < 65536)
+ n <<= IN_CLASSB_NSHIFT;
+ else
+ n <<= IN_CLASSC_NSHIFT;
+ }
+ sin->sin_family = AF_INET;
+ sin->sin_addr = inet_makeaddr(n, INADDR_ANY);
+ return (1);
+ }
+ if (strcmp(type, "host") == 0)
+ return (gethostnameornumber(name, sin));
+ return (0);
+}
+
+int gethostnameornumber(char *name, struct sockaddr_in *sin)
+{
+ struct hostent *hp;
+
+ if (inet_aton(name, &sin->sin_addr) == 0) {
+ hp = gethostbyname(name);
+ if (hp == 0)
+ return (0);
+ memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
+ sin->sin_family = hp->h_addrtype;
+ } else
+ sin->sin_family = AF_INET;
+ return (1);
+}
Index: routed/tables.c
===================================================================
--- routed/tables.c (nonexistent)
+++ routed/tables.c (revision 5)
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * From: @(#)tables.c 5.17 (Berkeley) 6/1/90
+ * From: @(#)tables.c 8.1 (Berkeley) 6/5/93
+ */
+char tables_rcsid[] =
+ "$Id: tables.c,v 1.13 2000/12/25 14:41:54 jr Exp $";
+
+
+/*
+ * Routing Table Management Daemon
+ */
+
+#include "defs.h"
+#include <sys/ioctl.h>
+#include <syslog.h>
+#include <errno.h>
+#include <search.h>
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+#define FIXLEN(s) { }
+
+static int install = !DEBUG; /* if 1 call kernel */
+struct rthash nethash[ROUTEHASHSIZ];
+struct rthash hosthash[ROUTEHASHSIZ];
+
+/*
+ * Lookup dst in the tables for an exact match.
+ */
+struct rt_entry *rtlookup(struct sockaddr *dst)
+{
+ register struct rt_entry *rt;
+ register struct rthash *rh;
+ register u_int hash;
+ struct afhash h;
+ int doinghost = 1;
+
+ if (dst->sa_family >= af_max)
+ return (0);
+ (*afswitch[dst->sa_family].af_hash)(dst, &h);
+ hash = h.afh_hosthash;
+ rh = &hosthash[hash & ROUTEHASHMASK];
+again:
+ for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+ if (rt->rt_hash != hash)
+ continue;
+ if (equal(&rt->rt_dst, dst))
+ return (rt);
+ }
+ if (doinghost) {
+ doinghost = 0;
+ hash = h.afh_nethash;
+ rh = &nethash[hash & ROUTEHASHMASK];
+ goto again;
+ }
+ return (0);
+}
+
+struct sockaddr wildcard; /* zero valued cookie for wildcard searches */
+
+/*
+ * Find a route to dst as the kernel would.
+ */
+
+struct rt_entry *rtfind(struct sockaddr *dst)
+{
+ register struct rt_entry *rt;
+ register struct rthash *rh;
+ register u_int hash;
+ struct afhash h;
+ int af = dst->sa_family;
+ int doinghost = 1, (*match)(struct sockaddr *,struct sockaddr *)=NULL;
+
+ if (af >= af_max)
+ return (0);
+ (*afswitch[af].af_hash)(dst, &h);
+ hash = h.afh_hosthash;
+ rh = &hosthash[hash & ROUTEHASHMASK];
+
+again:
+ for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+ if (rt->rt_hash != hash)
+ continue;
+ if (doinghost) {
+ if (equal(&rt->rt_dst, dst))
+ return (rt);
+ } else {
+ if (rt->rt_dst.sa_family == af &&
+ (*match)(&rt->rt_dst, dst))
+ return (rt);
+ }
+ }
+ if (doinghost) {
+ doinghost = 0;
+ hash = h.afh_nethash;
+ rh = &nethash[hash & ROUTEHASHMASK];
+ match = afswitch[af].af_netmatch;
+ goto again;
+ }
+ return (0);
+}
+
+void rtadd(struct sockaddr *dst, struct sockaddr *gate, int metric, int state)
+{
+ struct afhash h;
+ register struct rt_entry *rt;
+ struct rthash *rh;
+ int af = dst->sa_family, flags;
+ u_int hash;
+ char buf1[256], buf2[256];
+
+ if (af >= af_max)
+ return;
+ (*afswitch[af].af_hash)(dst, &h);
+ flags = (*afswitch[af].af_rtflags)(dst);
+ /*
+ * Subnet flag isn't visible to kernel, move to state. XXX
+ */
+ FIXLEN(dst);
+ FIXLEN(gate);
+ if (flags & RTF_SUBNET) {
+ state |= RTS_SUBNET;
+ flags &= ~RTF_SUBNET;
+ }
+ if (flags & RTF_HOST) {
+ hash = h.afh_hosthash;
+ rh = &hosthash[hash & ROUTEHASHMASK];
+ } else {
+ hash = h.afh_nethash;
+ rh = &nethash[hash & ROUTEHASHMASK];
+ }
+ rt = (struct rt_entry *)malloc(sizeof (*rt));
+ if (rt == 0)
+ return;
+ rt->rt_hash = hash;
+ rt->rt_dst = *dst;
+ rt->rt_router = *gate;
+ rt->rt_timer = 0;
+ rt->rt_flags = RTF_UP | flags;
+ rt->rt_state = state | RTS_CHANGED;
+ rt->rt_ifp = if_ifwithdstaddr(&rt->rt_dst);
+ if (rt->rt_ifp == 0)
+ rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ if ((state & RTS_INTERFACE) == 0)
+ rt->rt_flags |= RTF_GATEWAY;
+ rt->rt_metric = metric;
+ insque((struct qelem *)rt, (struct qelem *)rh);
+ TRACE_ACTION("ADD", rt);
+ /*
+ * If the ioctl fails because the gateway is unreachable
+ * from this host, discard the entry. This should only
+ * occur because of an incorrect entry in /etc/gateways.
+ */
+ if ((rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 &&
+ rtioctl(ADD, &rt->rt_rt) < 0) {
+ if (errno != EEXIST && gate->sa_family < af_max)
+ syslog(LOG_ERR,
+ "adding route to net/host %s through gateway %s: %m\n",
+ (*afswitch[dst->sa_family].af_format)(dst, buf1,
+ sizeof(buf1)),
+ (*afswitch[gate->sa_family].af_format)(gate, buf2,
+ sizeof(buf2)));
+ perror("ADD ROUTE");
+ if (errno == ENETUNREACH) {
+ TRACE_ACTION("DELETE", rt);
+ remque((struct qelem *)rt);
+ free((char *)rt);
+ }
+ }
+}
+
+void rtchange(struct rt_entry *rt, struct sockaddr *gate, short metric)
+{
+ int add = 0, delete = 0, newgateway = 0;
+ struct rtuentry oldroute;
+
+ FIXLEN(gate);
+ FIXLEN(&(rt->rt_router));
+ FIXLEN(&(rt->rt_dst));
+ if (!equal(&rt->rt_router, gate)) {
+ newgateway++;
+ TRACE_ACTION("CHANGE FROM ", rt);
+ } else if (metric != rt->rt_metric)
+ TRACE_NEWMETRIC(rt, metric);
+ if ((rt->rt_state & RTS_INTERNAL) == 0) {
+ /*
+ * If changing to different router, we need to add
+ * new route and delete old one if in the kernel.
+ * If the router is the same, we need to delete
+ * the route if has become unreachable, or re-add
+ * it if it had been unreachable.
+ */
+ if (newgateway) {
+ add++;
+ if (rt->rt_metric != HOPCNT_INFINITY)
+ delete++;
+ } else if (metric == HOPCNT_INFINITY)
+ delete++;
+ else if (rt->rt_metric == HOPCNT_INFINITY)
+ add++;
+ }
+ /* Linux 1.3.12 and up */
+ if (kernel_version >= 0x01030b) {
+ if (add && delete && rt->rt_metric == metric)
+ delete = 0;
+ } else {
+ /* Linux 1.2.x and 1.3.7 - 1.3.11 */
+ if (add && delete)
+ delete = 0;
+ }
+
+ if (delete)
+ oldroute = rt->rt_rt;
+ if ((rt->rt_state & RTS_INTERFACE) && delete) {
+ rt->rt_state &= ~RTS_INTERFACE;
+ rt->rt_flags |= RTF_GATEWAY;
+ if (metric > rt->rt_metric && delete)
+ syslog(LOG_ERR, "%s route to interface %s (timed out)",
+ add? "changing" : "deleting",
+ rt->rt_ifp ? rt->rt_ifp->int_name : "?");
+ }
+ if (add) {
+ rt->rt_router = *gate;
+ rt->rt_ifp = if_ifwithdstaddr(&rt->rt_router);
+ if (rt->rt_ifp == 0)
+ rt->rt_ifp = if_ifwithnet(&rt->rt_router);
+ }
+ rt->rt_metric = metric;
+ rt->rt_state |= RTS_CHANGED;
+ if (newgateway)
+ TRACE_ACTION("CHANGE TO ", rt);
+ if (add && rtioctl(ADD, &rt->rt_rt) < 0)
+ perror("ADD ROUTE");
+ if (delete && rtioctl(DELETE, &oldroute) < 0)
+ perror("DELETE ROUTE");
+}
+
+void rtdelete(struct rt_entry *rt)
+{
+
+ TRACE_ACTION("DELETE", rt);
+ FIXLEN(&(rt->rt_router));
+ FIXLEN(&(rt->rt_dst));
+ if (rt->rt_metric < HOPCNT_INFINITY) {
+ if ((rt->rt_state & (RTS_INTERFACE|RTS_INTERNAL)) == RTS_INTERFACE)
+ syslog(LOG_ERR,
+ "deleting route to interface %s? (timed out?)",
+ rt->rt_ifp->int_name);
+ if ((rt->rt_state & (RTS_INTERNAL | RTS_EXTERNAL)) == 0 &&
+ rtioctl(DELETE, &rt->rt_rt) < 0)
+ perror("rtdelete");
+ }
+ remque((struct qelem *)rt);
+ free((char *)rt);
+}
+
+void rtdeleteall(int sig)
+{
+ register struct rthash *rh;
+ register struct rt_entry *rt;
+ struct rthash *base = hosthash;
+ int doinghost = 1, i;
+
+again:
+ for (i = 0; i < ROUTEHASHSIZ; i++) {
+ rh = &base[i];
+ rt = rh->rt_forw;
+ for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+ if (rt->rt_state & RTS_INTERFACE ||
+ rt->rt_metric >= HOPCNT_INFINITY)
+ continue;
+ TRACE_ACTION("DELETE", rt);
+ if ((rt->rt_state & (RTS_INTERNAL|RTS_EXTERNAL)) == 0 &&
+ rtioctl(DELETE, &rt->rt_rt) < 0)
+ perror("rtdeleteall");
+ }
+ }
+ if (doinghost) {
+ doinghost = 0;
+ base = nethash;
+ goto again;
+ }
+ exit(sig);
+}
+
+/*
+ * If we have an interface to the wide, wide world,
+ * add an entry for an Internet default route (wildcard) to the internal
+ * tables and advertise it. This route is not added to the kernel routes,
+ * but this entry prevents us from listening to other people's defaults
+ * and installing them in the kernel here.
+ */
+
+void rtdefault(void)
+{
+
+ rtadd((struct sockaddr *)&inet_default,
+ (struct sockaddr *)&inet_default, 1,
+ RTS_CHANGED | RTS_PASSIVE | RTS_INTERNAL);
+}
+
+void rtinit(void)
+{
+ register struct rthash *rh;
+ int i;
+
+ for (i = 0; i < ROUTEHASHSIZ; i++) {
+ rh = &nethash[i];
+ rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
+ }
+ for (i = 0; i < ROUTEHASHSIZ; i++) {
+ rh = &hosthash[i];
+ rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
+ }
+}
+
+int rtioctl(int action, struct rtuentry *ort)
+{
+ struct rtentry rt;
+ unsigned int netmask;
+ unsigned int dst;
+
+ if (install == 0)
+ return (errno = 0);
+
+#undef rt_flags
+#undef rt_ifp
+#undef rt_metric
+#undef rt_dst
+
+ rt.rt_flags = (ort->rtu_flags & (RTF_UP|RTF_GATEWAY|RTF_HOST));
+ rt.rt_metric = ort->rtu_metric;
+ /*
+ * SIOCADDRT ioctl in linux kernels v. 2.1.15 and up will no longer
+ * add direct route to subnet/host through interface, even if the
+ * specified gateway's IP is the same as IP of that interface (BSDism).
+ * -- if this is the case, assure that no matter what kernel we use,
+ * the subnet route to directly attached network is always added
+ * to KRT as direct one.
+ */
+ if (rt.rt_flags & RTF_GATEWAY) {
+ rt.rt_dev = NULL;
+ rt.rt_gateway = *(struct sockaddr *)&ort->rtu_router;
+ } else {
+ rt.rt_dev = ort->rtu_ifp->int_name;
+ /*
+ * We could add a direct route to the KRT this way
+ * on whatever kernel, but kernels v. 2.1.15 and up
+ * add such route immediately as soon as the interface
+ * is labelled with IFF_UP. However, the resulting route
+ * would be added twice, since kernel distinguishes
+ * between direct route it added itself and the one
+ * added explicitly by SIOCADDRT ioctl. So instead,
+ * we safely exit with "route successfully added" sign, here.
+ */
+ if (kernel_version >= 0x02010f)
+ return 0;
+ }
+ rt.rt_dst = *(struct sockaddr *)&ort->rtu_dst;
+ dst = ((struct sockaddr_in *)&rt.rt_dst)->sin_addr.s_addr;
+ if (rt.rt_flags & RTF_HOST)
+ netmask = 0xffffffff;
+ else
+ netmask = inet_maskof(dst);
+ ((struct sockaddr_in *)&rt.rt_genmask)->sin_family = AF_INET;
+ ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr = netmask;
+
+ if (traceactions) {
+ fprintf(ftrace, "rtioctl %s %08lx/%08lx\n",
+ action == ADD ? "ADD" : "DEL",
+ (unsigned long int)ntohl(dst),
+ (unsigned long int)ntohl(netmask));
+ fflush(ftrace);
+ }
+
+ switch (action) {
+
+ case ADD:
+ return (ioctl(sock, SIOCADDRT, (char *)&rt));
+
+ case DELETE:
+ return (ioctl(sock, SIOCDELRT, (char *)&rt));
+
+ default:
+ return (-1);
+ }
+}
Index: routed/timer.c
===================================================================
--- routed/timer.c (nonexistent)
+++ routed/timer.c (revision 5)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * From: @(#)timer.c 5.10 (Berkeley) 2/28/91
+ * From: @(#)timer.c 8.1 (Berkeley) 6/5/93
+ */
+char timer_rcsid[] =
+ "$Id: timer.c,v 1.8 2000/12/25 14:43:05 jr Exp $";
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#include "defs.h"
+
+static int faketime;
+
+/*
+ * Timer routine. Performs routing information supply
+ * duties and manages timers on routing table entries.
+ * Management of the RTS_CHANGED bit assumes that we broadcast
+ * each time called.
+ */
+
+void timer(int signum)
+{
+ register struct rthash *rh;
+ register struct rt_entry *rt;
+ struct rthash *base = hosthash;
+ int doinghost = 1, timetobroadcast;
+
+ (void)signum;
+
+ (void) gettimeofday(&now, (struct timezone *)NULL);
+ faketime += TIMER_RATE;
+ if (lookforinterfaces && (faketime % CHECK_INTERVAL) == 0)
+ ifinit();
+ timetobroadcast = supplier && (faketime % SUPPLY_INTERVAL) == 0;
+again:
+ for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
+ rt = rh->rt_forw;
+ for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
+ /*
+ * We don't advance time on a routing entry for
+ * a passive gateway or interface.
+ */
+ if ((rt->rt_state & (RTS_PASSIVE|RTS_INTERFACE)) == 0)
+ rt->rt_timer += TIMER_RATE;
+ if (rt->rt_timer >= GARBAGE_TIME) {
+ rt = rt->rt_back;
+ rtdelete(rt->rt_forw);
+ continue;
+ }
+ if (rt->rt_timer >= EXPIRE_TIME &&
+ rt->rt_metric < HOPCNT_INFINITY)
+ rtchange(rt, &rt->rt_router, HOPCNT_INFINITY);
+ rt->rt_state &= ~RTS_CHANGED;
+ }
+ }
+ if (doinghost) {
+ doinghost = 0;
+ base = nethash;
+ goto again;
+ }
+ if (timetobroadcast) {
+ toall(supply, 0, (struct interface *)NULL);
+ lastbcast = now;
+ lastfullupdate = now;
+ needupdate = 0; /* cancel any pending dynamic update */
+ nextbcast.tv_sec = 0;
+ }
+}
+
+/*
+ * On hangup, let everyone know we're going away.
+ */
+
+void hup(int signum)
+{
+ register struct rthash *rh;
+ register struct rt_entry *rt;
+ struct rthash *base = hosthash;
+ int doinghost = 1;
+
+ (void)signum;
+
+ if (supplier) {
+again:
+ for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) {
+ rt = rh->rt_forw;
+ for (; rt != (struct rt_entry *)rh; rt = rt->rt_forw)
+ rt->rt_metric = HOPCNT_INFINITY;
+ }
+ if (doinghost) {
+ doinghost = 0;
+ base = nethash;
+ goto again;
+ }
+ toall(supply, 0, (struct interface *)NULL);
+ }
+ exit(1);
+}
Index: routed/trace.c
===================================================================
--- routed/trace.c (nonexistent)
+++ routed/trace.c (revision 5)
@@ -0,0 +1,471 @@
+/*
+ * Copyright (c) 1983, 1988, 1993
+ * The Regents of the University of California. 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+/*
+ * From: @(#)trace.c 5.11 (Berkeley) 2/28/91
+ * From: @(#)trace.c 8.1 (Berkeley) 6/5/93
+ */
+char trace_rcsid[] =
+ "$Id: trace.c,v 1.16 2000/07/22 23:25:11 dholland Exp $";
+
+
+/*
+ * Routing Table Management Daemon
+ */
+#define RIPCMDS
+#include "defs.h"
+#include <sys/stat.h>
+/* #include <signal.h> <--- unused? */
+#include <fcntl.h>
+#include <syslog.h>
+#include <errno.h>
+#include "pathnames.h"
+#include <time.h>
+
+#define NRECORDS 50 /* size of circular trace buffer */
+
+FILE *ftrace = NULL /*stdout*/; /* output trace file */
+int traceactions=0; /* on/off */
+int tracepackets; /* watch packets as they go by */
+int tracehistory; /* on/off */
+static int tracecontents; /* watch packet contents as they go by */
+
+static struct timeval lastlog;
+static char *savetracename;
+
+
+static int iftraceinit(struct interface *, struct ifdebug *);
+void dumpif(FILE *, struct interface *);
+void dumptrace(FILE *, char *, struct ifdebug *);
+
+void traceinit(struct interface *ifp)
+{
+
+ if (iftraceinit(ifp, &ifp->int_input) &&
+ iftraceinit(ifp, &ifp->int_output))
+ return;
+ tracehistory = 0;
+ fprintf(stderr, "traceinit: can't init %s\n", ifp->int_name);
+}
+
+static int iftraceinit(struct interface *ifp, struct ifdebug *ifd)
+{
+ struct iftrace *t;
+
+ ifd->ifd_records =
+ (struct iftrace *)malloc(NRECORDS * sizeof (struct iftrace));
+ if (ifd->ifd_records == 0)
+ return (0);
+ ifd->ifd_front = ifd->ifd_records;
+ ifd->ifd_count = 0;
+ for (t = ifd->ifd_records; t < ifd->ifd_records + NRECORDS; t++) {
+ t->ift_size = 0;
+ t->ift_packet = 0;
+ }
+ ifd->ifd_if = ifp;
+ return (1);
+}
+
+void traceon(char *file)
+{
+ struct stat stbuf;
+ int fd;
+ const char *logdir = _PATH_LOGDIR;
+
+ if (ftrace != NULL)
+ return;
+
+ /*
+ * Trace file requests could come from anywhere...
+ */
+
+ if (strncmp(file, logdir, strlen(logdir)) || strstr(file, "/../")) {
+ syslog(LOG_ERR, "Cannot log to %s: not under %s\n",
+ file, logdir);
+ return;
+ }
+
+ /*
+ * Also check that the environment is sane.
+ */
+ if (stat(logdir, &stbuf)<0 || !S_ISDIR(stbuf.st_mode)) {
+ syslog(LOG_ERR, "Configuration problem: %s does not exist "
+ "or is not a directory", logdir);
+ syslog(LOG_ERR, "Logging disabled");
+ return;
+ }
+
+ if ((stbuf.st_mode & 022)!=0 || stbuf.st_uid!=0) {
+ syslog(LOG_ERR, "Configuration problem: wrong permissions for "
+ "%s (should be mode 700 and owned by root)",
+ logdir);
+ syslog(LOG_ERR, "Logging disabled");
+ return;
+ }
+
+ /*
+ * 7/22/00 took out O_EXCL on the grounds that since we're
+ * checking that the file is in the log dir, and the log
+ * dir is supposed to be root-only, appending to an
+ * existing file is not particularly evil.
+ *
+ * If Linux ever supports O_NOLINK that should go in here though.
+ */
+ fd = open(file, O_WRONLY|O_APPEND|O_CREAT|O_NDELAY, 0600);
+
+ if (fd == -1) {
+ syslog(LOG_ERR, "Cannot log to %s: %s\n",
+ file, strerror(errno));
+ return;
+ }
+ if (fstat(fd, &stbuf) >= 0 && !S_ISREG(stbuf.st_mode)) {
+ syslog(LOG_ERR, "Cannot log to %s: not a regular file\n",
+ file);
+ return;
+ }
+
+ fcntl(fd, F_SETFL, 0); /* Turn NDELAY off */
+
+ savetracename = file;
+ (void) gettimeofday(&now, (struct timezone *)NULL);
+ ftrace = fdopen(fd, "a");
+ if (ftrace == NULL)
+ return;
+ fflush(stdout);
+ fflush(stderr);
+ dup2(fileno(ftrace), 1);
+ dup2(fileno(ftrace), 2);
+ traceactions = 1;
+ fprintf(ftrace, "Tracing enabled %s\n", ctime(&now.tv_sec));
+}
+
+void traceoff(void)
+{
+ if (!traceactions)
+ return;
+ if (ftrace != NULL) {
+ int fd = open(_PATH_DEVNULL, O_RDWR);
+
+ if (fd<0) {
+ fprintf(ftrace, "Disable tracing: /dev/null: %s\n",
+ strerror(errno));
+ return;
+ }
+
+ fprintf(ftrace, "Tracing disabled %s\n",
+ ctime(&now.tv_sec));
+ fflush(ftrace);
+ (void) dup2(fd, 1);
+ (void) dup2(fd, 2);
+ (void) close(fd);
+ fclose(ftrace);
+ ftrace = NULL;
+ }
+ traceactions = 0;
+ tracehistory = 0;
+ tracepackets = 0;
+ tracecontents = 0;
+}
+
+void sigtrace(int s)
+{
+
+ if (s == SIGUSR2)
+ traceoff();
+ else if (ftrace == NULL && savetracename)
+ traceon(savetracename);
+ else
+ bumploglevel();
+}
+
+/*
+ * Move to next higher level of tracing when -t option processed or
+ * SIGUSR1 is received. Successive levels are:
+ * traceactions
+ * traceactions + tracepackets
+ * traceactions + tracehistory (packets and contents after change)
+ * traceactions + tracepackets + tracecontents
+ */
+
+void bumploglevel(void)
+{
+
+ (void) gettimeofday(&now, NULL);
+ if (traceactions == 0) {
+ traceactions++;
+ if (ftrace)
+ fprintf(ftrace, "Tracing actions started %s\n",
+ ctime(&now.tv_sec));
+ } else if (tracepackets == 0) {
+ tracepackets++;
+ tracehistory = 0;
+ tracecontents = 0;
+ if (ftrace)
+ fprintf(ftrace, "Tracing packets started %s\n",
+ ctime(&now.tv_sec));
+ } else if (tracehistory == 0) {
+ tracehistory++;
+ if (ftrace)
+ fprintf(ftrace, "Tracing history started %s\n",
+ ctime(&now.tv_sec));
+ } else {
+ tracepackets++;
+ tracecontents++;
+ tracehistory = 0;
+ if (ftrace)
+ fprintf(ftrace, "Tracing packet contents started %s\n",
+ ctime(&now.tv_sec));
+ }
+ if (ftrace)
+ fflush(ftrace);
+}
+
+void trace(struct ifdebug *ifd, struct sockaddr *who, char *p, int len,int m)
+{
+ struct iftrace *t;
+
+ if (ifd->ifd_records == 0)
+ return;
+ t = ifd->ifd_front++;
+ if (ifd->ifd_front >= ifd->ifd_records + NRECORDS)
+ ifd->ifd_front = ifd->ifd_records;
+ if (ifd->ifd_count < NRECORDS)
+ ifd->ifd_count++;
+ if (t->ift_size > 0 && t->ift_size < len && t->ift_packet) {
+ free(t->ift_packet);
+ t->ift_packet = 0;
+ }
+ t->ift_stamp = now;
+ t->ift_who = *who;
+ if (len > 0 && t->ift_packet == 0) {
+ t->ift_packet = malloc(len);
+ if (t->ift_packet == 0)
+ len = 0;
+ }
+ if (len > 0)
+ memcpy(t->ift_packet, p, len);
+ t->ift_size = len;
+ t->ift_metric = m;
+}
+
+void traceaction(FILE *fd, char *action, struct rt_entry *rt)
+{
+ struct sockaddr_in *dst, *gate;
+ static struct bits {
+ int t_bits;
+ const char *t_name;
+ } flagbits[] = {
+ { RTF_UP, "UP" },
+ { RTF_GATEWAY, "GATEWAY" },
+ { RTF_HOST, "HOST" },
+ { 0, 0 }
+ }, statebits[] = {
+ { RTS_PASSIVE, "PASSIVE" },
+ { RTS_REMOTE, "REMOTE" },
+ { RTS_INTERFACE,"INTERFACE" },
+ { RTS_CHANGED, "CHANGED" },
+ { RTS_INTERNAL, "INTERNAL" },
+ { RTS_EXTERNAL, "EXTERNAL" },
+ { RTS_SUBNET, "SUBNET" },
+ { 0, 0 }
+ };
+ struct bits *p;
+ int first;
+ char *cp;
+
+ if (fd == NULL)
+ return;
+ if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
+ fprintf(fd, "\n%.19s:\n", ctime(&now.tv_sec));
+ lastlog = now;
+ }
+ fprintf(fd, "%s ", action);
+ dst = (struct sockaddr_in *)&rt->rt_dst;
+ gate = (struct sockaddr_in *)&rt->rt_router;
+ fprintf(fd, "dst %s, ", inet_ntoa(dst->sin_addr));
+ fprintf(fd, "router %s, metric %d, flags",
+ inet_ntoa(gate->sin_addr), rt->rt_metric);
+ cp = " %s";
+ for (first = 1, p = flagbits; p->t_bits > 0; p++) {
+ if ((rt->rt_flags & p->t_bits) == 0)
+ continue;
+ fprintf(fd, cp, p->t_name);
+ if (first) {
+ cp = "|%s";
+ first = 0;
+ }
+ }
+ fprintf(fd, " state");
+ cp = " %s";
+ for (first = 1, p = statebits; p->t_bits > 0; p++) {
+ if ((rt->rt_state & p->t_bits) == 0)
+ continue;
+ fprintf(fd, cp, p->t_name);
+ if (first) {
+ cp = "|%s";
+ first = 0;
+ }
+ }
+ fprintf(fd, " timer %d\n", rt->rt_timer);
+ if (tracehistory && !tracepackets &&
+ (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp)
+ dumpif(fd, rt->rt_ifp);
+ fflush(fd);
+ if (ferror(fd))
+ traceoff();
+}
+
+void tracenewmetric(FILE *fd, struct rt_entry *rt, int newmetric)
+{
+ struct sockaddr_in *dst, *gate;
+
+ if (fd == NULL)
+ return;
+ if (lastlog.tv_sec != now.tv_sec || lastlog.tv_usec != now.tv_usec) {
+ fprintf(fd, "\n%.19s:\n", ctime(&now.tv_sec));
+ lastlog = now;
+ }
+ dst = (struct sockaddr_in *)&rt->rt_dst;
+ gate = (struct sockaddr_in *)&rt->rt_router;
+ fprintf(fd, "CHANGE metric dst %s, ", inet_ntoa(dst->sin_addr));
+ fprintf(fd, "router %s, from %d to %d\n",
+ inet_ntoa(gate->sin_addr), rt->rt_metric, newmetric);
+ fflush(fd);
+ if (ferror(fd))
+ traceoff();
+}
+
+void dumpif(FILE *fd, struct interface *ifp)
+{
+ if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) {
+ fprintf(fd, "*** Packet history for interface %s ***\n",
+ ifp->int_name);
+ dumptrace(fd, "from", &ifp->int_input);
+ fprintf(fd, "*** end packet history ***\n");
+ }
+}
+
+void dumptrace(FILE *fd, char *dir, struct ifdebug *ifd)
+{
+ struct iftrace *t;
+ char *cp = !strcmp(dir, "to") ? "Output" : "Input";
+
+ if (ifd->ifd_front == ifd->ifd_records &&
+ ifd->ifd_front->ift_size == 0) {
+ fprintf(fd, "%s: no packets.\n", cp);
+ fflush(fd);
+ return;
+ }
+ fprintf(fd, "%s trace:\n", cp);
+ t = ifd->ifd_front - ifd->ifd_count;
+ if (t < ifd->ifd_records)
+ t += NRECORDS;
+ for ( ; ifd->ifd_count; ifd->ifd_count--, t++) {
+ if (t >= ifd->ifd_records + NRECORDS)
+ t = ifd->ifd_records;
+ if (t->ift_size == 0)
+ continue;
+ dumppacket(fd, dir, &t->ift_who,
+ t->ift_packet, t->ift_size, &t->ift_stamp);
+ }
+}
+
+void dumppacket(FILE *fd, char *dir, struct sockaddr *sa,
+ char *cp, int size, struct timeval *stamp)
+{
+ struct rip *msg = (struct rip *)cp;
+ struct sockaddr_in *who=(struct sockaddr_in *)sa;
+ struct netinfo *n;
+
+ if (fd == NULL)
+ return;
+ if (msg->rip_cmd && msg->rip_cmd < RIPCMD_MAX)
+ fprintf(fd, "%s %s %s.%d %.19s:\n", ripcmds[msg->rip_cmd],
+ dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port),
+ ctime(&stamp->tv_sec));
+ else {
+ fprintf(fd, "Bad cmd 0x%x %s %s.%d %.19s\n", msg->rip_cmd,
+ dir, inet_ntoa(who->sin_addr), ntohs(who->sin_port),
+ ctime(&stamp->tv_sec));
+ fprintf(fd, "size=%d cp=%p packet=%p\n", size, cp, packet);
+ fflush(fd);
+ return;
+ }
+ if (tracepackets && tracecontents == 0) {
+ fflush(fd);
+ return;
+ }
+ switch (msg->rip_cmd) {
+
+ case RIPCMD_REQUEST:
+ case RIPCMD_RESPONSE:
+ size -= 4 * sizeof (char);
+ n = msg->rip_nets;
+ for (; size > 0; n++, size -= sizeof (struct netinfo)) {
+ if (size < (int)sizeof (struct netinfo)) {
+ fprintf(fd, "(truncated record, len %d)\n",
+ size);
+ break;
+ }
+ if (sizeof(n->rip_dst.sa_family) > 1)
+ n->rip_dst.sa_family = ntohs(n->rip_dst.sa_family);
+
+ switch ((int)n->rip_dst.sa_family) {
+
+ case AF_INET:
+ fprintf(fd, "\tdst %s metric %ld\n",
+#define satosin(sa) ((struct sockaddr_in *)&sa)
+ inet_ntoa(satosin(n->rip_dst)->sin_addr),
+ (long int)ntohl(n->rip_metric));
+ break;
+
+ default:
+ fprintf(fd, "\taf %d? metric %ld\n",
+ n->rip_dst.sa_family,
+ (long int)ntohl(n->rip_metric));
+ break;
+ }
+ }
+ break;
+
+ case RIPCMD_TRACEON:
+ fprintf(fd, "\tfile=%*s\n", size, msg->rip_tracefile);
+ break;
+
+ case RIPCMD_TRACEOFF:
+ break;
+ }
+ fflush(fd);
+ if (ferror(fd))
+ traceoff();
+}
Index: routed
===================================================================
--- routed (nonexistent)
+++ routed (revision 5)
Property changes on: routed
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: version.h
===================================================================
--- version.h (nonexistent)
+++ version.h (revision 5)
@@ -0,0 +1,5 @@
+/*
+ * String to embed in binaries to identify package
+ */
+
+char pkg[]="$NetKit: netkit-routed-0.18 $";
Index: .
===================================================================
--- . (nonexistent)
+++ . (revision 5)
Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~