diff options
author | rgrimes <rgrimes@FreeBSD.org> | 1994-05-26 06:39:07 +0000 |
---|---|---|
committer | rgrimes <rgrimes@FreeBSD.org> | 1994-05-26 06:39:07 +0000 |
commit | 2a27bd86e6002c871e3b5561a5334653bb222a77 (patch) | |
tree | 9c2944770734d3bd64a72d3a0abca1f69087e278 /usr.sbin/XNSrouted | |
parent | d038e02fd667ab6c02875840105798aaa7029504 (diff) | |
download | FreeBSD-src-2a27bd86e6002c871e3b5561a5334653bb222a77.zip FreeBSD-src-2a27bd86e6002c871e3b5561a5334653bb222a77.tar.gz |
BSD 4.4 Lite sbin -> usr.sbin Sources
Note: The sources for XNSrouted and routed are being imported to usr.sbin
instead of sbin.
Diffstat (limited to 'usr.sbin/XNSrouted')
-rw-r--r-- | usr.sbin/XNSrouted/Makefile | 9 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/XNSrouted.8 | 186 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/af.c | 246 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/af.h | 64 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/defs.h | 94 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/if.c | 147 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/input.c | 189 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/interface.h | 90 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/main.c | 255 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/output.c | 147 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/protocol.h | 85 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/startup.c | 274 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/table.h | 99 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/tables.c | 319 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/timer.c | 139 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/tools/query.c | 232 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/trace.c | 313 | ||||
-rw-r--r-- | usr.sbin/XNSrouted/trace.h | 96 |
18 files changed, 2984 insertions, 0 deletions
diff --git a/usr.sbin/XNSrouted/Makefile b/usr.sbin/XNSrouted/Makefile new file mode 100644 index 0000000..1b3cf0e --- /dev/null +++ b/usr.sbin/XNSrouted/Makefile @@ -0,0 +1,9 @@ +# @(#)Makefile 8.1 (Berkeley) 6/5/93 + +PROG= XNSrouted +MAN8= XNSrouted.0 +SRCS= af.c if.c input.c main.c output.c startup.c tables.c timer.c trace.c +DPADD= ${LIBCOMPAT} +LDADD= -lcompat + +.include <bsd.prog.mk> diff --git a/usr.sbin/XNSrouted/XNSrouted.8 b/usr.sbin/XNSrouted/XNSrouted.8 new file mode 100644 index 0000000..7b278bd --- /dev/null +++ b/usr.sbin/XNSrouted/XNSrouted.8 @@ -0,0 +1,186 @@ +.\" Copyright (c) 1986, 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. +.\" +.\" @(#)XNSrouted.8 8.1 (Berkeley) 6/5/93 +.\" +.Dd June 5, 1993 +.Dt XNSROUTED 8 +.Os BSD 4.3 +.Sh NAME +.Nm XNSrouted +.Nd NS Routing Information Protocol daemon +.Sh SYNOPSIS +.Nm XNSrouted +.Op Fl q +.Op Fl s +.Op Fl t +.Op Ar logfile +.Sh DESCRIPTION +.Nm XNSrouted +is invoked at boot time to manage the Xerox NS routing tables. +The NS routing daemon uses the Xerox NS Routing +Information Protocol in maintaining up to date kernel routing +table entries. +.Pp +Available options: +.Bl -tag -width logfile +.It Fl q +Do not supply routing information (opposite of +.Fl s +option below). +.It Fl s +Forces +.Nm XNSrouted +to supply routing information whether it is acting as an internetwork +router or not. +.It Fl t +All packets sent or received are +printed on the standard output. In addition, +.Nm XNSrouted +will not divorce itself from the controlling terminal +so that interrupts from the keyboard will kill the process. +.It Ar logfile +Name of file in which +.Nm XNSrouted Ns 's +actions should be logged. This log contains information +about any changes to the routing tables and a history of +recent messages sent and received which are related to +the changed route. +.El +.Pp +In normal operation +.Nm XNSrouted +listens +for routing information packets. If the host is connected to +multiple NS networks, it periodically supplies copies +of its routing tables to any directly connected hosts +and networks. +.Pp +When +.Nm XNSrouted +is started, it uses the +.Dv SIOCGIFCONF +.Xr ioctl 2 +to find those +directly connected interfaces configured into the +system and marked +.Dq up +(the software loopback interface +is ignored). If multiple interfaces +are present, it is assumed the host will forward packets +between networks. +.Nm XNSrouted +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 XNSrouted +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 +.Dq hop count +metric (a count of 16, or greater, is +considered +.Dq infinite ) . +The metric associated with each +route returned provides a metric +.Em relative to the sender . +.Pp +.Em Response +packets received by +.Nm XNSrouted +are used to update the routing tables if one of the following +conditions is satisfied: +.Bl -bullet +.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 XNSrouted +records the change in its internal tables and generates a +.Em response +packet to all directly connected hosts and networks. +.Xr Routed 8 +waits a short period +of time (no more than 30 seconds) before modifying the kernel's +routing tables to allow possible unstable situations to settle. +.Pp +In addition to processing incoming packets, +.Nm XNSrouted +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 +to other routers. +.Pp +Hosts acting as internetwork routers gratuitously supply their +routing tables every 30 seconds to all directly connected hosts +and networks. +.Sh SEE ALSO +.Xr idp 4 +.Rs +.%T "Internet Transport Protocols" +.%R "XSIS 028112" +.%Q "Xerox System Integration Standard" +.Re +.Sh HISTORY +The +.Nm +command appeared in +.Bx 4.3 . diff --git a/usr.sbin/XNSrouted/af.c b/usr.sbin/XNSrouted/af.c new file mode 100644 index 0000000..6c81b47 --- /dev/null +++ b/usr.sbin/XNSrouted/af.c @@ -0,0 +1,246 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)af.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +#include "defs.h" + +/* + * Address family support routines + */ +int null_hash(), null_netmatch(), null_output(), + null_portmatch(), null_portcheck(), + null_checkhost(), null_ishost(), null_canon(); +int xnnet_hash(), xnnet_netmatch(), xnnet_output(), + xnnet_portmatch(), + xnnet_checkhost(), xnnet_ishost(), xnnet_canon(); +#define NIL \ + { null_hash, null_netmatch, null_output, \ + null_portmatch, null_portcheck, null_checkhost, \ + null_ishost, null_canon } +#define XNSNET \ + { xnnet_hash, xnnet_netmatch, xnnet_output, \ + xnnet_portmatch, xnnet_portmatch, xnnet_checkhost, \ + xnnet_ishost, xnnet_canon } + +struct afswitch afswitch[AF_MAX] = + { NIL, NIL, NIL, NIL, NIL, NIL, XNSNET, NIL, NIL, NIL, NIL }; + +struct sockaddr_ns xnnet_default = { sizeof(struct sockaddr_ns), AF_NS }; + +union ns_net ns_anynet; +union ns_net ns_zeronet; + +xnnet_hash(sns, hp) + register struct sockaddr_ns *sns; + struct afhash *hp; +{ + register long hash = 0; + register u_short *s = sns->sns_addr.x_host.s_host; + union ns_net_u net; + + net.net_e = sns->sns_addr.x_net; + hp->afh_nethash = net.long_e; + hash = *s++; hash <<= 8; hash += *s++; hash <<= 8; hash += *s; + hp->afh_hosthash = hash; +} + +xnnet_netmatch(sxn1, sxn2) + struct sockaddr_ns *sxn1, *sxn2; +{ + return (ns_neteq(sxn1->sns_addr, sxn2->sns_addr)); +} + +/* + * Verify the message is from the right port. + */ +xnnet_portmatch(sns) + register struct sockaddr_ns *sns; +{ + + return (ntohs(sns->sns_addr.x_port) == IDPPORT_RIF ); +} + + +/* + * xns output routine. + */ +#ifdef DEBUG +int do_output = 0; +#endif +xnnet_output(flags, sns, size) + int flags; + struct sockaddr_ns *sns; + int size; +{ + struct sockaddr_ns dst; + + dst = *sns; + sns = &dst; + if (sns->sns_addr.x_port == 0) + sns->sns_addr.x_port = htons(IDPPORT_RIF); +#ifdef DEBUG + if(do_output || ntohs(msg->rip_cmd) == RIPCMD_REQUEST) +#endif + /* + * Kludge to allow us to get routes out to machines that + * don't know their addresses yet; send to that address on + * ALL connected nets + */ + if (ns_neteqnn(sns->sns_addr.x_net, ns_zeronet)) { + extern struct interface *ifnet; + register struct interface *ifp; + + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + sns->sns_addr.x_net = + satons_addr(ifp->int_addr).x_net; + (void) sendto(s, msg, size, flags, + (struct sockaddr *)sns, sizeof (*sns)); + } + return; + } + + (void) sendto(s, msg, size, flags, + (struct sockaddr *)sns, sizeof (*sns)); +} + +/* + * Return 1 if we want this route. + * We use this to disallow route net G entries for one for multiple + * point to point links. + */ +xnnet_checkhost(sns) + struct sockaddr_ns *sns; +{ + register struct interface *ifp = if_ifwithnet(sns); + /* + * We want this route if there is no more than one + * point to point interface with this network. + */ + if (ifp == 0 || (ifp->int_flags & IFF_POINTOPOINT)==0) return (1); + return (ifp->int_sq.n == ifp->int_sq.p); +} + +/* + * Return 1 if the address is + * for a host, 0 for a network. + */ +xnnet_ishost(sns) +struct sockaddr_ns *sns; +{ + register u_short *s = sns->sns_addr.x_host.s_host; + + if ((s[0]==0xffff) && (s[1]==0xffff) && (s[2]==0xffff)) + return (0); + else + return (1); +} + +xnnet_canon(sns) + struct sockaddr_ns *sns; +{ + + sns->sns_addr.x_port = 0; +} + +/*ARGSUSED*/ +null_hash(addr, hp) + struct sockaddr *addr; + struct afhash *hp; +{ + + hp->afh_nethash = hp->afh_hosthash = 0; +} + +/*ARGSUSED*/ +null_netmatch(a1, a2) + struct sockaddr *a1, *a2; +{ + + return (0); +} + +/*ARGSUSED*/ +null_output(s, f, a1, n) + int s, f; + struct sockaddr *a1; + int n; +{ + + ; +} + +/*ARGSUSED*/ +null_portmatch(a1) + struct sockaddr *a1; +{ + + return (0); +} + +/*ARGSUSED*/ +null_portcheck(a1) + struct sockaddr *a1; +{ + + return (0); +} + +/*ARGSUSED*/ +null_ishost(a1) + struct sockaddr *a1; +{ + + return (0); +} + +/*ARGSUSED*/ +null_checkhost(a1) + struct sockaddr *a1; +{ + + return (0); +} + +/*ARGSUSED*/ +null_canon(a1) + struct sockaddr *a1; +{ + + ; +} diff --git a/usr.sbin/XNSrouted/af.h b/usr.sbin/XNSrouted/af.h new file mode 100644 index 0000000..9b74463 --- /dev/null +++ b/usr.sbin/XNSrouted/af.h @@ -0,0 +1,64 @@ +/* + * 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. + * + * @(#)af.h 5.1 (Berkeley) 6/4/85 (routed/af.h) + * + * @(#)af.h 8.1 (Berkeley) 6/5/93 + */ + +/* + * Routing table management daemon. + */ + +/* + * Per address family routines. + */ +struct afswitch { + int (*af_hash)(); /* returns keys based on address */ + int (*af_netmatch)(); /* verifies net # matching */ + int (*af_output)(); /* interprets address for sending */ + int (*af_portmatch)(); /* packet from some other router? */ + int (*af_portcheck)(); /* packet from privileged peer? */ + int (*af_checkhost)(); /* tells if address for host or net */ + int (*af_ishost)(); /* tells if address is valid */ + int (*af_canon)(); /* canonicalize address for compares */ +}; + +/* + * Structure returned by af_hash routines. + */ +struct afhash { + u_int afh_hosthash; /* host based hash */ + u_int afh_nethash; /* network based hash */ +}; + +struct afswitch afswitch[AF_MAX]; /* table proper */ diff --git a/usr.sbin/XNSrouted/defs.h b/usr.sbin/XNSrouted/defs.h new file mode 100644 index 0000000..c380e81 --- /dev/null +++ b/usr.sbin/XNSrouted/defs.h @@ -0,0 +1,94 @@ +/* + * 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. + * + * @(#)defs.h 8.1 (Berkeley) 6/5/93 + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <net/route.h> +#include <netns/ns.h> +#include <netns/idp.h> +#if defined(vax) || defined(pdp11) +#define xnnet(x) ((u_long) (x)->rip_dst[1] << 16 | (u_long) (x)->rip_dst[0] ) +#else +#define xnnet(x) ((u_long) (x)->rip_dst[0] << 16 | (u_long) (x)->rip_dst[1] ) +#endif +#define IDPPORT_RIF 1 + +#include <stdio.h> +#include <syslog.h> + +#include "protocol.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 (5*60) + +#define equal(a1, a2) \ + (bcmp((caddr_t)(a1), (caddr_t)(a2), sizeof (struct sockaddr)) == 0) +#define min(a,b) ((a)>(b)?(b):(a)) + +struct sockaddr_ns addr; /* Daemon's Address */ +int s; /* Socket to listen on */ +int kmem; +int supplier; /* process should supply updates */ +int install; /* if 1 call kernel */ +int lookforinterfaces; /* if 1 probe kernel for new up interfaces */ +int performnlist; /* if 1 check if /vmunix has changed */ +int externalinterfaces; /* # of remote and local interfaces */ +int timeval; /* local idea of time */ +int noteremoterequests; /* squawk on requests from non-local nets */ +int r; /* Routing socket to install updates with */ +struct sockaddr_ns ns_netmask; /* Used in installing routes */ + +char packet[MAXPACKETSIZE+sizeof(struct idp)+1]; +struct rip *msg; + +char **argv0; + +int sndmsg(); +int supply(); +int cleanup(); +int rtioctl(); +#define ADD 1 +#define DELETE 2 +#define CHANGE 3 diff --git a/usr.sbin/XNSrouted/if.c b/usr.sbin/XNSrouted/if.c new file mode 100644 index 0000000..422f757 --- /dev/null +++ b/usr.sbin/XNSrouted/if.c @@ -0,0 +1,147 @@ +/* + * 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. + * + * static char sccsid[] = "@(#)if.c 5.1 (Berkeley) 6/4/85"; (routed/if.c) + */ + +#ifndef lint +static char sccsid[] = "@(#)if.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#include "defs.h" + +extern struct interface *ifnet; + +/* + * Find the interface with address addr. + */ +struct interface * +if_ifwithaddr(addr) + struct sockaddr *addr; +{ + register struct interface *ifp; + +#define same(a1, a2) \ + (bcmp((caddr_t)((a1)->sa_data), (caddr_t)((a2)->sa_data), 14) == 0) + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if (ifp->int_flags & IFF_REMOTE) + continue; + if (ifp->int_addr.sa_family != addr->sa_family) + continue; + if (same(&ifp->int_addr, addr)) + break; + if ((ifp->int_flags & IFF_BROADCAST) && + same(&ifp->int_broadaddr, addr)) + break; + } + return (ifp); +} + +/* + * Find the point-to-point interface with destination address addr. + */ +struct interface * +if_ifwithdstaddr(addr) + struct sockaddr *addr; +{ + register struct interface *ifp; + + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if ((ifp->int_flags & IFF_POINTOPOINT) == 0) + continue; + if (same(&ifp->int_dstaddr, addr)) + break; + } + return (ifp); +} + +/* + * Find the interface on the network + * of the specified address. + */ +struct interface * +if_ifwithnet(addr) + register struct sockaddr *addr; +{ + register struct interface *ifp; + register int af = addr->sa_family; + register int (*netmatch)(); + + if (af >= AF_MAX) + return (0); + netmatch = afswitch[af].af_netmatch; + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if (ifp->int_flags & IFF_REMOTE) + continue; + if (af != ifp->int_addr.sa_family) + continue; + if ((*netmatch)(addr, &ifp->int_addr)) + break; + } + return (ifp); +} + +/* + * Find an interface from which the specified address + * should have come from. Used for figuring out which + * interface a packet came in on -- for tracing. + */ +struct interface * +if_iflookup(addr) + struct sockaddr *addr; +{ + register struct interface *ifp, *maybe; + register int af = addr->sa_family; + register int (*netmatch)(); + + if (af >= AF_MAX) + return (0); + maybe = 0; + netmatch = afswitch[af].af_netmatch; + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if (ifp->int_addr.sa_family != af) + continue; + if (same(&ifp->int_addr, addr)) + break; + if ((ifp->int_flags & IFF_BROADCAST) && + same(&ifp->int_broadaddr, addr)) + break; + if (maybe == 0 && (*netmatch)(addr, &ifp->int_addr)) + maybe = ifp; + } + if (ifp == 0) + ifp = maybe; + return (ifp); +} diff --git a/usr.sbin/XNSrouted/input.c b/usr.sbin/XNSrouted/input.c new file mode 100644 index 0000000..b64fca2 --- /dev/null +++ b/usr.sbin/XNSrouted/input.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)input.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * XNS Routing Table Management Daemon + */ +#include "defs.h" + +struct sockaddr * +xns_nettosa(net) +union ns_net net; +{ + static struct sockaddr_ns sxn; + extern char ether_broadcast_addr[6]; + + bzero(&sxn, sizeof (struct sockaddr_ns)); + sxn.sns_family = AF_NS; + sxn.sns_len = sizeof (sxn); + sxn.sns_addr.x_net = net; + sxn.sns_addr.x_host = *(union ns_host *)ether_broadcast_addr; + return( (struct sockaddr *)&sxn); + +} + +/* + * Process a newly received packet. + */ +rip_input(from, size) + struct sockaddr *from; + int size; +{ + struct rt_entry *rt; + struct netinfo *n; + struct interface *ifp; + int newsize; + struct afswitch *afp; + + + ifp = 0; + TRACE_INPUT(ifp, from, size); + if (from->sa_family >= AF_MAX) + return; + afp = &afswitch[from->sa_family]; + + size -= sizeof (u_short) /* command */; + n = msg->rip_nets; + + switch (ntohs(msg->rip_cmd)) { + + case RIPCMD_REQUEST: + newsize = 0; + while (size > 0) { + if (size < sizeof (struct netinfo)) + break; + size -= sizeof (struct netinfo); + + /* + * A single entry with rip_dst == DSTNETS_ALL and + * metric ``infinity'' means ``all routes''. + */ + if (ns_neteqnn(n->rip_dst, ns_anynet) && + ntohs(n->rip_metric) == HOPCNT_INFINITY && + size == 0) { + ifp = if_ifwithnet(from); + supply(from, 0, ifp); + return; + } + /* + * request for specific nets + */ + rt = rtlookup(xns_nettosa(n->rip_dst)); + if (ftrace) { + fprintf(ftrace, + "specific request for %s", + xns_nettoa(n->rip_dst)); + fprintf(ftrace, + " yields route %x\n", + rt); + } + n->rip_metric = htons( rt == 0 ? HOPCNT_INFINITY : + min(rt->rt_metric+1, HOPCNT_INFINITY)); + n++; + newsize += sizeof (struct netinfo); + } + if (newsize > 0) { + msg->rip_cmd = htons(RIPCMD_RESPONSE); + newsize += sizeof (u_short); + /* should check for if with dstaddr(from) first */ + (*afp->af_output)(0, from, newsize); + ifp = if_ifwithnet(from); + TRACE_OUTPUT(ifp, from, newsize); + if (ftrace) { + fprintf(ftrace, + "request arrived on interface %s\n", + ifp->int_name); + } + } + return; + + case RIPCMD_RESPONSE: + /* verify message came from a router */ + if ((*afp->af_portmatch)(from) == 0) + return; + (*afp->af_canon)(from); + /* are we talking to ourselves? */ + if (ifp = if_ifwithaddr(from)) { + rt = rtfind(from); + if (rt == 0 || (rt->rt_state & RTS_INTERFACE) == 0) + addrouteforif(ifp); + else + rt->rt_timer = 0; + return; + } + /* Update timer for interface on which the packet arrived. + * If from other end of a point-to-point link that isn't + * in the routing tables, (re-)add the route. + */ + if ((rt = rtfind(from)) && (rt->rt_state & RTS_INTERFACE)) { + if(ftrace) fprintf(ftrace, "Got route\n"); + rt->rt_timer = 0; + } else if (ifp = if_ifwithdstaddr(from)) { + if(ftrace) fprintf(ftrace, "Got partner\n"); + addrouteforif(ifp); + } + for (; size > 0; size -= sizeof (struct netinfo), n++) { + struct sockaddr *sa; + if (size < sizeof (struct netinfo)) + break; + if ((unsigned) ntohs(n->rip_metric) >= HOPCNT_INFINITY) + continue; + rt = rtfind(sa = xns_nettosa(n->rip_dst)); + if (rt == 0) { + rtadd(sa, from, ntohs(n->rip_metric), 0); + continue; + } + + /* + * Update if from gateway and different, + * from anywhere and shorter, or getting stale and equivalent. + */ + if ((equal(from, &rt->rt_router) && + ntohs(n->rip_metric) != rt->rt_metric ) || + (unsigned) ntohs(n->rip_metric) < rt->rt_metric || + (rt->rt_timer > (EXPIRE_TIME/2) && + rt->rt_metric == ntohs(n->rip_metric))) { + rtchange(rt, from, ntohs(n->rip_metric)); + rt->rt_timer = 0; + } + } + return; + } +} diff --git a/usr.sbin/XNSrouted/interface.h b/usr.sbin/XNSrouted/interface.h new file mode 100644 index 0000000..64e1580 --- /dev/null +++ b/usr.sbin/XNSrouted/interface.h @@ -0,0 +1,90 @@ +/* + * 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. + * + * @(#)interface.h 8.1 (Berkeley) 6/5/93 + */ + +/* + * Routing table management daemon. + */ + +/* + * 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. + * We list only one address for each interface, the AF_XNS one. + */ +#define NIFADDR 3 +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 */ + 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 */ +/*XNS Specific entry */ + struct sameq { + struct sameq *n; /* q of other pt-to-pt links */ + struct sameq *p; /* with same net # */ + } int_sq; +}; + +/* + * 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_ROUTE 0x8 /* routing entry installed */ +#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */ + +#define IFF_PASSIVE 0x2000 /* can't tell if up/down */ +#define IFF_INTERFACE 0x4000 /* hardware interface */ +#define IFF_REMOTE 0x8000 /* interface isn't on this machine */ + +struct interface *if_ifwithaddr(); +struct interface *if_ifwithdstaddr(); +struct interface *if_ifwithnet(); +struct interface *if_iflookup(); diff --git a/usr.sbin/XNSrouted/main.c b/usr.sbin/XNSrouted/main.c new file mode 100644 index 0000000..601a005 --- /dev/null +++ b/usr.sbin/XNSrouted/main.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1985, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * XNS Routing Information Protocol Daemon + */ +#include "defs.h" +#include <sys/time.h> + +#include <net/if.h> + +#include <errno.h> +#include <nlist.h> +#include <signal.h> +#include <paths.h> + +int supplier = -1; /* process should supply updates */ +extern int gateway; + +struct rip *msg = (struct rip *) &packet[sizeof (struct idp)]; +void hup(), fkexit(), timer(); + +main(argc, argv) + int argc; + char *argv[]; +{ + int cc; + struct sockaddr from; + u_char retry; + + argv0 = argv; + argv++, argc--; + while (argc > 0 && **argv == '-') { + if (strcmp(*argv, "-s") == 0) { + supplier = 1; + argv++, argc--; + continue; + } + if (strcmp(*argv, "-q") == 0) { + supplier = 0; + argv++, argc--; + continue; + } + if (strcmp(*argv, "-R") == 0) { + noteremoterequests++; + argv++, argc--; + continue; + } + if (strcmp(*argv, "-t") == 0) { + tracepackets++; + argv++, argc--; + ftrace = stderr; + tracing = 1; + continue; + } + if (strcmp(*argv, "-g") == 0) { + gateway = 1; + argv++, argc--; + continue; + } + if (strcmp(*argv, "-l") == 0) { + gateway = -1; + argv++, argc--; + continue; + } + fprintf(stderr, + "usage: xnsrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ]\n"); + exit(1); + } + + +#ifndef DEBUG + if (!tracepackets) + daemon(0, 0); +#endif + openlog("XNSrouted", LOG_PID, LOG_DAEMON); + + addr.sns_family = AF_NS; + addr.sns_len = sizeof(addr); + addr.sns_port = htons(IDPPORT_RIF); + ns_anynet.s_net[0] = ns_anynet.s_net[1] = -1; + ns_netmask.sns_addr.x_net = ns_anynet; + ns_netmask.sns_len = 6; + r = socket(AF_ROUTE, SOCK_RAW, 0); + /* later, get smart about lookingforinterfaces */ + if (r) + shutdown(r, 0); /* for now, don't want reponses */ + else { + fprintf(stderr, "routed: no routing socket\n"); + exit(1); + } + s = getsocket(SOCK_DGRAM, 0, &addr); + if (s < 0) + exit(1); + /* + * Any extra argument is considered + * a tracing log file. + */ + if (argc > 0) + traceon(*argv); + /* + * Collect an initial view of the world by + * snooping in the kernel. Then, send a request packet on all + * directly connected networks to find out what + * everyone else thinks. + */ + rtinit(); + ifinit(); + if (supplier < 0) + supplier = 0; + /* request the state of the world */ + msg->rip_cmd = htons(RIPCMD_REQUEST); + msg->rip_nets[0].rip_dst = ns_anynet; + msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); + toall(sndmsg); + signal(SIGALRM, timer); + signal(SIGHUP, hup); + signal(SIGINT, hup); + signal(SIGEMT, fkexit); + timer(); + + + for (;;) + process(s); + +} + +process(fd) + int fd; +{ + struct sockaddr from; + int fromlen = sizeof (from), cc, omask; + struct idp *idp = (struct idp *)packet; + + cc = recvfrom(fd, packet, sizeof (packet), 0, &from, &fromlen); + if (cc <= 0) { + if (cc < 0 && errno != EINTR) + syslog(LOG_ERR, "recvfrom: %m"); + return; + } + if (tracepackets > 1 && ftrace) { + fprintf(ftrace,"rcv %d bytes on %s ", cc, xns_ntoa(&idp->idp_dna)); + fprintf(ftrace," from %s\n", xns_ntoa(&idp->idp_sna)); + } + + if (noteremoterequests && !ns_neteqnn(idp->idp_sna.x_net, ns_zeronet) + && !ns_neteq(idp->idp_sna, idp->idp_dna)) + { + syslog(LOG_ERR, + "net of interface (%s) != net on ether (%s)!\n", + xns_nettoa(idp->idp_dna.x_net), + xns_nettoa(idp->idp_sna.x_net)); + } + + /* We get the IDP header in front of the RIF packet*/ + cc -= sizeof (struct idp); +#define mask(s) (1<<((s)-1)) + omask = sigblock(mask(SIGALRM)); + rip_input(&from, cc); + sigsetmask(omask); +} + +getsocket(type, proto, sns) + int type, proto; + struct sockaddr_ns *sns; +{ + int domain = sns->sns_family; + int retry, s, on = 1; + + retry = 1; + while ((s = socket(domain, type, proto)) < 0 && retry) { + syslog(LOG_ERR, "socket: %m"); + sleep(5 * retry); + retry <<= 1; + } + if (retry == 0) + return (-1); + while (bind(s, (struct sockaddr *)sns, sizeof (*sns)) < 0 && retry) { + syslog(LOG_ERR, "bind: %m"); + sleep(5 * retry); + retry <<= 1; + } + if (retry == 0) + return (-1); + if (domain==AF_NS) { + struct idp idp; + if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { + syslog(LOG_ERR, "setsockopt SEE HEADERS: %m"); + exit(1); + } + idp.idp_pt = NSPROTO_RI; + if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { + syslog(LOG_ERR, "setsockopt SET HEADER: %m"); + exit(1); + } + } + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + syslog(LOG_ERR, "setsockopt SO_BROADCAST: %m"); + exit(1); + } + return (s); +} + +/* + * Fork and exit on EMT-- for profiling. + */ +void +fkexit() +{ + if (fork() == 0) + exit(0); +} diff --git a/usr.sbin/XNSrouted/output.c b/usr.sbin/XNSrouted/output.c new file mode 100644 index 0000000..fae1c39 --- /dev/null +++ b/usr.sbin/XNSrouted/output.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#include "defs.h" + +/* + * Apply the function "f" to all non-passive + * interfaces. If the interface supports the + * use of broadcasting use it, otherwise address + * the output to the known router. + */ +toall(f) + int (*f)(); +{ + register struct interface *ifp; + register struct sockaddr *dst; + register int flags; + extern struct interface *ifnet; + + for (ifp = ifnet; ifp; ifp = ifp->int_next) { + if (ifp->int_flags & IFF_PASSIVE) + continue; + dst = ifp->int_flags & IFF_BROADCAST ? &ifp->int_broadaddr : + ifp->int_flags & IFF_POINTOPOINT ? &ifp->int_dstaddr : + &ifp->int_addr; + flags = ifp->int_flags & IFF_INTERFACE ? MSG_DONTROUTE : 0; + (*f)(dst, flags, ifp); + } +} + +/* + * Output a preformed packet. + */ +/*ARGSUSED*/ +sndmsg(dst, flags, ifp) + struct sockaddr *dst; + int flags; + struct interface *ifp; +{ + + (*afswitch[dst->sa_family].af_output) + (flags, dst, sizeof (struct rip)); + TRACE_OUTPUT(ifp, dst, sizeof (struct rip)); +} + +/* + * Supply dst with the contents of the routing tables. + * If this won't fit in one packet, chop it up into several. + */ +supply(dst, flags, ifp) + struct sockaddr *dst; + int flags; + struct interface *ifp; +{ + register struct rt_entry *rt; + register struct rthash *rh; + register struct netinfo *nn; + register struct netinfo *n = msg->rip_nets; + struct rthash *base = hosthash; + struct sockaddr_ns *sns = (struct sockaddr_ns *) dst; + int (*output)() = afswitch[dst->sa_family].af_output; + int doinghost = 1, size, metric; + union ns_net net; + + msg->rip_cmd = ntohs(RIPCMD_RESPONSE); +again: + for (rh = base; rh < &base[ROUTEHASHSIZ]; rh++) + for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) { + size = (char *)n - (char *)msg; + if (size > MAXPACKETSIZE - sizeof (struct netinfo)) { + (*output)(flags, dst, size); + TRACE_OUTPUT(ifp, dst, size); + n = msg->rip_nets; + } + sns = (struct sockaddr_ns *)&rt->rt_dst; + if ((rt->rt_flags & (RTF_HOST|RTF_GATEWAY)) == RTF_HOST) + sns = (struct sockaddr_ns *)&rt->rt_router; + metric = min(rt->rt_metric + 1, HOPCNT_INFINITY); + net = sns->sns_addr.x_net; + /* + * Make sure that we don't put out a two net entries + * for a pt to pt link (one for the G route, one for the if) + * This is a kludge, and won't work if there are lots of nets. + */ + for (nn = msg->rip_nets; nn < n; nn++) { + if (ns_neteqnn(net, nn->rip_dst)) { + if (metric < ntohs(nn->rip_metric)) + nn->rip_metric = htons(metric); + goto next; + } + } + n->rip_dst = net; + n->rip_metric = htons(metric); + n++; + next:; + } + if (doinghost) { + doinghost = 0; + base = nethash; + goto again; + } + if (n != msg->rip_nets) { + size = (char *)n - (char *)msg; + (*output)(flags, dst, size); + TRACE_OUTPUT(ifp, dst, size); + } +} diff --git a/usr.sbin/XNSrouted/protocol.h b/usr.sbin/XNSrouted/protocol.h new file mode 100644 index 0000000..72b0ddb --- /dev/null +++ b/usr.sbin/XNSrouted/protocol.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + * + * @(#)protocol.h 8.1 (Berkeley) 6/5/93 + */ + +/* + * Xerox Routing Information Protocol + * + */ + +struct netinfo { + union ns_net rip_dst; /* destination net */ + u_short rip_metric; /* cost of route */ +}; + +struct rip { + u_short rip_cmd; /* request/response */ + struct netinfo rip_nets[1]; /* variable length */ +}; + +/* + * Packet types. + */ +#define RIPCMD_REQUEST 1 /* want info */ +#define RIPCMD_RESPONSE 2 /* responding to request */ + +#define RIPCMD_MAX 3 +#ifdef RIPCMDS +char *ripcmds[RIPCMD_MAX] = + { "#0", "REQUEST", "RESPONSE" }; +#endif + +#define HOPCNT_INFINITY 16 /* per Xerox NS */ +#define DSTNETS_ALL 0xffffffff /* per Xerox NS */ +#define MAXPACKETSIZE 512 /* max broadcast size */ + +extern union ns_net ns_anynet; +extern union ns_net ns_zeronet; + +/* + * Timer values used in managing the routing table. + * Every update forces an entry's timer to be reset. After + * EXPIRE_TIME without updates, the entry is marked invalid, + * but held onto until GARBAGE_TIME so that others may + * see it "be deleted". + */ +#define TIMER_RATE 30 /* alarm clocks every 30 seconds */ + +#define SUPPLY_INTERVAL 30 /* time to supply tables */ + +#define EXPIRE_TIME 180 /* time to mark entry invalid */ +#define GARBAGE_TIME 240 /* time to garbage collect */ diff --git a/usr.sbin/XNSrouted/startup.c b/usr.sbin/XNSrouted/startup.c new file mode 100644 index 0000000..bcb5615 --- /dev/null +++ b/usr.sbin/XNSrouted/startup.c @@ -0,0 +1,274 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)startup.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#include "defs.h" + +#include <sys/param.h> +#include <sys/ioctl.h> +#include <sys/sysctl.h> + +#include <net/if.h> +#include <net/if_dl.h> + +#include <nlist.h> +#include <stdlib.h> + +struct interface *ifnet; +int lookforinterfaces = 1; +int performnlist = 1; +int gateway = 0; +int externalinterfaces = 0; /* # of remote and local interfaces */ +char ether_broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + +void +quit(s) + char *s; +{ + extern int errno; + int sverrno = errno; + + (void) fprintf(stderr, "route: "); + if (s) + (void) fprintf(stderr, "%s: ", s); + (void) fprintf(stderr, "%s\n", strerror(sverrno)); + exit(1); + /* NOTREACHED */ +} + +struct rt_addrinfo info; +/* Sleazy use of local variables throughout file, warning!!!! */ +#define netmask info.rti_info[RTAX_NETMASK] +#define ifaaddr info.rti_info[RTAX_IFA] +#define brdaddr info.rti_info[RTAX_BRD] + +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len)) + +void +rt_xaddrs(cp, cplim, rtinfo) + register caddr_t cp, cplim; + register struct rt_addrinfo *rtinfo; +{ + register struct sockaddr *sa; + register int i; + + bzero(rtinfo->rti_info, sizeof(rtinfo->rti_info)); + for (i = 0; (i < RTAX_MAX) && (cp < cplim); i++) { + if ((rtinfo->rti_addrs & (1 << i)) == 0) + continue; + rtinfo->rti_info[i] = sa = (struct sockaddr *)cp; + ADVANCE(cp, sa); + } +} + +/* + * 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. + */ +ifinit() +{ + struct interface ifs, *ifp; + size_t needed; + int mib[6], no_nsaddr = 0, flags = 0; + char *buf, *cplim, *cp; + register struct if_msghdr *ifm; + register struct ifa_msghdr *ifam; + struct sockaddr_dl *sdl; + u_long i; + + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = AF_NS; + mib[4] = NET_RT_IFLIST; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + quit("route-sysctl-estimate"); + if ((buf = malloc(needed)) == NULL) + quit("malloc"); + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + lookforinterfaces = 0; + cplim = buf + needed; + for (cp = buf; cp < cplim; cp += ifm->ifm_msglen) { + ifm = (struct if_msghdr *)cp; + if (ifm->ifm_type == RTM_IFINFO) { + bzero(&ifs, sizeof(ifs)); + ifs.int_flags = flags = ifm->ifm_flags | IFF_INTERFACE; + if ((flags & IFF_UP) == 0 || no_nsaddr) + lookforinterfaces = 1; + sdl = (struct sockaddr_dl *) (ifm + 1); + sdl->sdl_data[sdl->sdl_nlen] = 0; + no_nsaddr = 1; + continue; + } + if (ifm->ifm_type != RTM_NEWADDR) + quit("ifinit: out of sync"); + if ((flags & IFF_UP) == 0) + continue; + ifam = (struct ifa_msghdr *)ifm; + info.rti_addrs = ifam->ifam_addrs; + rt_xaddrs((char *)(ifam + 1), cp + ifam->ifam_msglen, &info); + if (ifaaddr == 0) { + syslog(LOG_ERR, "%s: (get addr)", sdl->sdl_data); + continue; + } + ifs.int_addr = *ifaaddr; + if (ifs.int_addr.sa_family != AF_NS) + continue; + no_nsaddr = 0; + if (ifs.int_flags & IFF_POINTOPOINT) { + if (brdaddr == 0) { + syslog(LOG_ERR, "%s: (get dstaddr)", + sdl->sdl_data); + continue; + } + if (brdaddr->sa_family == AF_UNSPEC) { + lookforinterfaces = 1; + continue; + } + ifs.int_dstaddr = *brdaddr; + } + if (ifs.int_flags & IFF_BROADCAST) { + if (brdaddr == 0) { + syslog(LOG_ERR, "%s: (get broadaddr)", + sdl->sdl_data); + continue; + } + ifs.int_dstaddr = *brdaddr; + } + /* + * already known to us? + * what makes a POINTOPOINT if unique is its dst addr, + * NOT its source address + */ + if ( ((ifs.int_flags & IFF_POINTOPOINT) && + if_ifwithdstaddr(&ifs.int_dstaddr)) || + ( ((ifs.int_flags & IFF_POINTOPOINT) == 0) && + if_ifwithaddr(&ifs.int_addr))) + continue; + /* no one cares about software loopback interfaces */ + if (ifs.int_flags & IFF_LOOPBACK) + continue; + ifp = (struct interface *) + malloc(sdl->sdl_nlen + 1 + sizeof(ifs)); + if (ifp == 0) { + syslog(LOG_ERR, "XNSrouted: out of memory\n"); + lookforinterfaces = 1; + 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_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 = (char *)(ifp + 1); + strcpy(ifp->int_name, sdl->sdl_data); + ifp->int_metric = ifam->ifam_metric; + ifp->int_next = ifnet; + ifnet = ifp; + traceinit(ifp); + addrouteforif(ifp); + } + if (externalinterfaces > 1 && supplier < 0) + supplier = 1; + free(buf); +} + +addrouteforif(ifp) + struct interface *ifp; +{ + struct sockaddr_ns net; + struct sockaddr *dst; + int state, metric; + struct rt_entry *rt; + + if (ifp->int_flags & IFF_POINTOPOINT) { + int (*match)(); + register struct interface *ifp2 = ifnet; + register struct interface *ifprev = ifnet; + + dst = &ifp->int_dstaddr; + + /* Search for interfaces with the same net */ + ifp->int_sq.n = ifp->int_sq.p = &(ifp->int_sq); + match = afswitch[dst->sa_family].af_netmatch; + if (match) + for (ifp2 = ifnet; ifp2; ifp2 =ifp2->int_next) { + if (ifp->int_flags & IFF_POINTOPOINT == 0) + continue; + if ((*match)(&ifp2->int_dstaddr,&ifp->int_dstaddr)) { + insque(&ifp2->int_sq,&ifp->int_sq); + break; + } + } + } else { + dst = &ifp->int_broadaddr; + } + rt = rtlookup(dst); + if (rt) + rtdelete(rt); + if (tracing) + fprintf(stderr, "Adding route to interface %s\n", ifp->int_name); + if (ifp->int_transitions++ > 0) + syslog(LOG_ERR, "re-installing interface %s", ifp->int_name); + rtadd(dst, &ifp->int_addr, ifp->int_metric, + ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE)); +} + diff --git a/usr.sbin/XNSrouted/table.h b/usr.sbin/XNSrouted/table.h new file mode 100644 index 0000000..1de2a95 --- /dev/null +++ b/usr.sbin/XNSrouted/table.h @@ -0,0 +1,99 @@ +/* + * 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. + * + * @(#)table.h 5.1 (Berkeley) 6/4/85 (routed/table.h) + * + * @(#)table.h 8.1 (Berkeley) 6/5/93 + */ + +/* + * Routing table management daemon. + */ + +/* + * Routing table structure; differs a bit from kernel tables. + * + * Note: the union below must agree in the first 4 members + * so the ioctl's will work. + */ +struct rthash { + struct rt_entry *rt_forw; + struct rt_entry *rt_back; +}; + +#ifdef RTM_ADD +#define rtentry ortentry +#endif + +struct rt_entry { + struct rt_entry *rt_forw; + struct rt_entry *rt_back; + union { + struct rtentry rtu_rt; + struct { + u_long rtu_hash; + struct sockaddr rtu_dst; + struct sockaddr rtu_router; + short rtu_flags; + short rtu_state; + int rtu_timer; + int rtu_metric; + struct interface *rtu_ifp; + } rtu_entry; + } rt_rtu; +}; + +#define rt_rt rt_rtu.rtu_rt /* pass to ioctl */ +#define rt_hash rt_rtu.rtu_entry.rtu_hash /* for net or host */ +#define rt_dst rt_rtu.rtu_entry.rtu_dst /* match value */ +#define rt_router rt_rtu.rtu_entry.rtu_router /* who to forward to */ +#define rt_flags rt_rtu.rtu_entry.rtu_flags /* kernel flags */ +#define rt_timer rt_rtu.rtu_entry.rtu_timer /* for invalidation */ +#define rt_state rt_rtu.rtu_entry.rtu_state /* see below */ +#define rt_metric rt_rtu.rtu_entry.rtu_metric /* cost of route */ +#define rt_ifp rt_rtu.rtu_entry.rtu_ifp /* interface to take */ + +#define ROUTEHASHSIZ 32 /* must be a power of 2 */ +#define ROUTEHASHMASK (ROUTEHASHSIZ - 1) + +/* + * "State" of routing table entry. + */ +#define RTS_CHANGED 0x1 /* route has been altered recently */ +#define RTS_PASSIVE IFF_PASSIVE /* don't time out route */ +#define RTS_INTERFACE IFF_INTERFACE /* route is for network interface */ +#define RTS_REMOTE IFF_REMOTE /* route is for ``remote'' entity */ + +struct rthash nethash[ROUTEHASHSIZ]; +struct rthash hosthash[ROUTEHASHSIZ]; +struct rt_entry *rtlookup(); +struct rt_entry *rtfind(); diff --git a/usr.sbin/XNSrouted/tables.c b/usr.sbin/XNSrouted/tables.c new file mode 100644 index 0000000..4b00dc5 --- /dev/null +++ b/usr.sbin/XNSrouted/tables.c @@ -0,0 +1,319 @@ +/* + * Copyright (c) 1985, 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#include "defs.h" +#include <sys/ioctl.h> +#include <errno.h> + +#ifndef DEBUG +#define DEBUG 0 +#endif + +extern char *xns_ntoa(); +#define FIXLEN(s) { if ((s)->sa_len == 0) (s)->sa_len = sizeof (*(s));} + +int install = !DEBUG; /* if 1 call kernel */ +int delete = 1; +/* + * Lookup dst in the tables for an exact match. + */ +struct rt_entry * +rtlookup(dst) + 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); +} + +/* + * Find a route to dst as the kernel would. + */ +struct rt_entry * +rtfind(dst) + 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)(); + + 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); +} + +rtadd(dst, gate, metric, state) + struct sockaddr *dst, *gate; + int metric, state; +{ + struct afhash h; + register struct rt_entry *rt; + struct rthash *rh; + int af = dst->sa_family, flags; + u_int hash; + + FIXLEN(dst); + FIXLEN(gate); + if (af >= AF_MAX) + return; + (*afswitch[af].af_hash)(dst, &h); + flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0; + 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_metric = metric; + rt->rt_timer = 0; + rt->rt_flags = RTF_UP | flags; + rt->rt_state = state | RTS_CHANGED; + rt->rt_ifp = if_ifwithnet(&rt->rt_router); + if (metric) + rt->rt_flags |= RTF_GATEWAY; + insque(rt, 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 (install && rtioctl(ADD, &rt->rt_rt) < 0) { + if (errno != EEXIST) + perror("SIOCADDRT"); + if (errno == ENETUNREACH) { + TRACE_ACTION(DELETE, rt); + remque(rt); + free((char *)rt); + } + } +} + +rtchange(rt, gate, metric) + struct rt_entry *rt; + struct sockaddr *gate; + short metric; +{ + int doioctl = 0, metricchanged = 0; + struct rtentry oldroute; + + FIXLEN(gate); + if (!equal(&rt->rt_router, gate)) + doioctl++; + if (metric != rt->rt_metric) + metricchanged++; + if (doioctl || metricchanged) { + TRACE_ACTION(CHANGE FROM, rt); + if (doioctl) { + oldroute = rt->rt_rt; + rt->rt_router = *gate; + } + rt->rt_metric = metric; + if ((rt->rt_state & RTS_INTERFACE) && metric) { + rt->rt_state &= ~RTS_INTERFACE; + syslog(LOG_ERR, + "changing route from interface %s (timed out)", + rt->rt_ifp->int_name); + } + if (metric) + rt->rt_flags |= RTF_GATEWAY; + else + rt->rt_flags &= ~RTF_GATEWAY; + rt->rt_state |= RTS_CHANGED; + TRACE_ACTION(CHANGE TO, rt); + } + if (doioctl && install) { +#ifndef RTM_ADD + if (rtioctl(ADD, &rt->rt_rt) < 0) + syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m", + xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr), + xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr)); + if (delete && rtioctl(DELETE, &oldroute) < 0) + perror("rtioctl DELETE"); +#else + if (delete == 0) { + if (rtioctl(ADD, &rt->rt_rt) >= 0) + return; + } else { + if (rtioctl(CHANGE, &rt->rt_rt) >= 0) + return; + } + syslog(LOG_ERR, "rtioctl ADD dst %s, gw %s: %m", + xns_ntoa(&((struct sockaddr_ns *)&rt->rt_dst)->sns_addr), + xns_ntoa(&((struct sockaddr_ns *)&rt->rt_router)->sns_addr)); +#endif + } +} + +rtdelete(rt) + struct rt_entry *rt; +{ + + struct sockaddr *sa = &(rt->rt_rt.rt_gateway); + FIXLEN(sa); +#undef rt_dst + sa = &(rt->rt_rt.rt_dst); + FIXLEN(sa); + if (rt->rt_state & RTS_INTERFACE) { + syslog(LOG_ERR, "deleting route to interface %s (timed out)", + rt->rt_ifp->int_name); + } + TRACE_ACTION(DELETE, rt); + if (install && rtioctl(DELETE, &rt->rt_rt) < 0) + perror("rtioctl DELETE"); + remque(rt); + free((char *)rt); +} + +rtinit() +{ + register struct rthash *rh; + + for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) + rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; + for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++) + rh->rt_forw = rh->rt_back = (struct rt_entry *)rh; +} +int seqno; + +rtioctl(action, ort) + int action; + struct ortentry *ort; +{ +#ifndef RTM_ADD + switch (action) { + + case ADD: + return (ioctl(s, SIOCADDRT, (char *)ort)); + + case DELETE: + return (ioctl(s, SIOCDELRT, (char *)ort)); + + default: + return (-1); + } +#else /* RTM_ADD */ + struct { + struct rt_msghdr w_rtm; + struct sockaddr w_dst; + struct sockaddr w_gate; + struct sockaddr_ns w_netmask; + } w; +#define rtm w.w_rtm + + bzero((char *)&w, sizeof(w)); + rtm.rtm_msglen = sizeof(w); + rtm.rtm_version = RTM_VERSION; + rtm.rtm_type = (action == ADD ? RTM_ADD : + (action == DELETE ? RTM_DELETE : RTM_CHANGE)); +#undef rt_flags + rtm.rtm_flags = ort->rt_flags; + rtm.rtm_seq = ++seqno; + rtm.rtm_addrs = RTA_DST|RTA_GATEWAY; + bcopy((char *)&ort->rt_dst, (char *)&w.w_dst, sizeof(w.w_dst)); + bcopy((char *)&ort->rt_gateway, (char *)&w.w_gate, sizeof(w.w_gate)); + w.w_gate.sa_family = w.w_dst.sa_family = AF_NS; + w.w_gate.sa_len = w.w_dst.sa_len = sizeof(w.w_dst); + if (rtm.rtm_flags & RTF_HOST) { + rtm.rtm_msglen -= sizeof(w.w_netmask); + } else { + w.w_netmask = ns_netmask; + rtm.rtm_msglen -= 8; + } + errno = 0; + return write(r, (char *)&w, rtm.rtm_msglen); +#endif /* RTM_ADD */ +} diff --git a/usr.sbin/XNSrouted/timer.c b/usr.sbin/XNSrouted/timer.c new file mode 100644 index 0000000..32c2bff --- /dev/null +++ b/usr.sbin/XNSrouted/timer.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)timer.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#include "defs.h" + +int timeval = -TIMER_RATE; + +/* + * Timer routine. Performs routing information supply + * duties and manages timers on routing table entries. + */ +void +timer() +{ + register struct rthash *rh; + register struct rt_entry *rt; + struct rthash *base = hosthash; + int doinghost = 1, timetobroadcast; + + timeval += TIMER_RATE; + if (lookforinterfaces && (timeval % CHECK_INTERVAL) == 0) + ifinit(); + timetobroadcast = supplier && (timeval % 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 that for our only interface. + * The latter is excused because we don't act as + * a routing information supplier and hence would + * time it out. This is fair as if it's down + * we're cut off from the world anyway and it's + * not likely we'll grow any new hardware in + * the mean time. + */ + if (!(rt->rt_state & RTS_PASSIVE) && + (supplier || !(rt->rt_state & RTS_INTERFACE))) + rt->rt_timer += TIMER_RATE; + if (rt->rt_timer >= EXPIRE_TIME) + rt->rt_metric = HOPCNT_INFINITY; + if (rt->rt_timer >= GARBAGE_TIME) { + rt = rt->rt_back; + /* Perhaps we should send a REQUEST for this route? */ + rtdelete(rt->rt_forw); + continue; + } + if (rt->rt_state & RTS_CHANGED) { + rt->rt_state &= ~RTS_CHANGED; + /* don't send extraneous packets */ + if (!supplier || timetobroadcast) + continue; + msg->rip_cmd = htons(RIPCMD_RESPONSE); + msg->rip_nets[0].rip_dst = + (satons_addr(rt->rt_dst)).x_net; + msg->rip_nets[0].rip_metric = + htons(min(rt->rt_metric+1, HOPCNT_INFINITY)); + toall(sndmsg); + } + } + } + if (doinghost) { + doinghost = 0; + base = nethash; + goto again; + } + if (timetobroadcast) + toall(supply); + alarm(TIMER_RATE); +} + +/* + * On hangup, let everyone know we're going away. + */ +void +hup() +{ + register struct rthash *rh; + register struct rt_entry *rt; + struct rthash *base = hosthash; + int doinghost = 1; + + 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); + } + exit(1); +} diff --git a/usr.sbin/XNSrouted/tools/query.c b/usr.sbin/XNSrouted/tools/query.c new file mode 100644 index 0000000..7deeac0 --- /dev/null +++ b/usr.sbin/XNSrouted/tools/query.c @@ -0,0 +1,232 @@ +/*- + * Copyright (c) 1983, 1986, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code includes software contributed to Berkeley by + * Bill Nesheim at Cornell University. + * + * 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. + */ + +#ifndef lint +static char copyright[] = +"@(#) Copyright (c) 1983, 1986, 1993\n\ + The Regents of the University of California. All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)query.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +#include <sys/param.h> +#include <sys/protosw.h> +#include <sys/socket.h> +#include <sys/time.h> +#include <netinet/in.h> +#include <netns/ns.h> +#include <netns/idp.h> +#include <errno.h> +#include <stdio.h> +#include <netdb.h> +#include "../protocol.h" +#define IDPPORT_RIF 1 + +#define WTIME 5 /* Time to wait for responses */ + +int s; +int timedout, timeout(); +char packet[MAXPACKETSIZE]; +extern int errno; +struct sockaddr_ns myaddr = {sizeof(myaddr), AF_NS}; +char *ns_ntoa(); +struct ns_addr ns_addr(); +main(argc, argv) +int argc; +char *argv[]; +{ + int cc, count, bits; + struct sockaddr from; + int fromlen = sizeof(from); + struct timeval notime; + + if (argc < 2) { + printf("usage: query hosts...\n"); + exit(1); + } + s = getsocket(SOCK_DGRAM, 0); + if (s < 0) { + perror("socket"); + exit(2); + } + + argv++, argc--; + query(argv,argc); + + /* + * Listen for returning packets; + * may be more than one packet per host. + */ + bits = 1 << s; + bzero(¬ime, sizeof(notime)); + signal(SIGALRM, timeout); + alarm(WTIME); + while (!timedout || + select(20, &bits, 0, 0, ¬ime) > 0) { + struct nspacket { + struct idp hdr; + char data[512]; + } response; + cc = recvfrom(s, &response, sizeof (response), 0, + &from, &fromlen); + if (cc <= 0) { + if (cc < 0) { + if (errno == EINTR) + continue; + perror("recvfrom"); + (void) close(s); + exit(1); + } + continue; + } + rip_input(&from, response.data, cc); + count--; + } +} +static struct sockaddr_ns router = {sizeof(myaddr), AF_NS}; +static struct ns_addr zero_addr; +static short allones[] = {-1, -1, -1}; + +query(argv,argc) +char **argv; +{ + register struct rip *msg = (struct rip *)packet; + char *host = *argv; + int flags = 0; + struct ns_addr specific; + + if (bcmp(*argv, "-r", 3) == 0) { + flags = MSG_DONTROUTE; argv++; argc--; + } + host = *argv; + router.sns_addr = ns_addr(host); + router.sns_addr.x_port = htons(IDPPORT_RIF); + if (ns_hosteq(zero_addr, router.sns_addr)) { + router.sns_addr.x_host = *(union ns_host *) allones; + } + msg->rip_cmd = htons(RIPCMD_REQUEST); + msg->rip_nets[0].rip_dst = *(union ns_net *) allones; + msg->rip_nets[0].rip_metric = htons(HOPCNT_INFINITY); + if (argc > 0) { + specific = ns_addr(*argv); + msg->rip_nets[0].rip_dst = specific.x_net; + specific.x_host = zero_addr.x_host; + specific.x_port = zero_addr.x_port; + printf("Net asked for was %s\n", ns_ntoa(specific)); + } + if (sendto(s, packet, sizeof (struct rip), flags, + &router, sizeof(router)) < 0) + perror(host); +} + +/* + * Handle an incoming routing packet. + */ +rip_input(from, msg, size) + struct sockaddr_ns *from; + register struct rip *msg; + int size; +{ + struct netinfo *n; + char *name; + int lna, net, subnet; + struct hostent *hp; + struct netent *np; + static struct ns_addr work; + + if (htons(msg->rip_cmd) != RIPCMD_RESPONSE) + return; + printf("from %s\n", ns_ntoa(from->sns_addr)); + size -= sizeof (struct idp); + size -= sizeof (short); + n = msg->rip_nets; + while (size > 0) { + union ns_net_u net; + if (size < sizeof (struct netinfo)) + break; + net.net_e = n->rip_dst; + printf("\t%d, metric %d\n", ntohl(net.long_e), + ntohs(n->rip_metric)); + size -= sizeof (struct netinfo), n++; + } +} + +timeout() +{ + timedout = 1; +} +getsocket(type, proto) + int type, proto; +{ + struct sockaddr_ns *sns = &myaddr; + int domain = sns->sns_family; + int retry, s, on = 1; + + retry = 1; + while ((s = socket(domain, type, proto)) < 0 && retry) { + perror("socket"); + sleep(5 * retry); + retry <<= 1; + } + if (retry == 0) + return (-1); + while (bind(s, sns, sizeof (*sns), 0) < 0 && retry) { + perror("bind"); + sleep(5 * retry); + retry <<= 1; + } + if (retry == 0) + return (-1); + if (domain==AF_NS) { + struct idp idp; + if (setsockopt(s, 0, SO_HEADERS_ON_INPUT, &on, sizeof(on))) { + perror("setsockopt SEE HEADERS"); + exit(1); + } + idp.idp_pt = NSPROTO_RI; + if (setsockopt(s, 0, SO_DEFAULT_HEADERS, &idp, sizeof(idp))) { + perror("setsockopt SET HEADERS"); + exit(1); + } + } + if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + perror("setsockopt SO_BROADCAST"); + exit(1); + } + return (s); +} diff --git a/usr.sbin/XNSrouted/trace.c b/usr.sbin/XNSrouted/trace.c new file mode 100644 index 0000000..385bb9b --- /dev/null +++ b/usr.sbin/XNSrouted/trace.c @@ -0,0 +1,313 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + */ + +#ifndef lint +static char sccsid[] = "@(#)trace.c 8.1 (Berkeley) 6/5/93"; +#endif /* not lint */ + +/* + * Routing Table Management Daemon + */ +#define RIPCMDS +#include <stdlib.h> +#include "defs.h" + +#define NRECORDS 50 /* size of circular trace buffer */ +#ifdef DEBUG +FILE *ftrace = stdout; +int tracing = 1; +#else DEBUG +FILE *ftrace = NULL; +int tracing = 0; +#endif + +char *xns_ntoa(); + +traceinit(ifp) + register struct interface *ifp; +{ + static int iftraceinit(); + + if (iftraceinit(ifp, &ifp->int_input) && + iftraceinit(ifp, &ifp->int_output)) + return; + tracing = 0; + syslog(LOG_ERR, "traceinit: can't init %s\n", ifp->int_name); +} + +static +iftraceinit(ifp, ifd) + struct interface *ifp; + register struct ifdebug *ifd; +{ + register 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); +} + +traceon(file) + char *file; +{ + + if (ftrace != NULL) + return; + ftrace = fopen(file, "a"); + if (ftrace == NULL) + return; + dup2(fileno(ftrace), 1); + dup2(fileno(ftrace), 2); + tracing = 1; +} + +traceoff() +{ + if (!tracing) + return; + if (ftrace != NULL) + fclose(ftrace); + ftrace = NULL; + tracing = 0; +} + +trace(ifd, who, p, len, m) + register struct ifdebug *ifd; + struct sockaddr *who; + char *p; + int len, m; +{ + register 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_packet) + free(t->ift_packet); + t->ift_packet = 0; + t->ift_stamp = time(0); + t->ift_who = *who; + if (len > 0) { + t->ift_packet = malloc(len); + if (t->ift_packet) + bcopy(p, t->ift_packet, len); + else + len = 0; + } + t->ift_size = len; + t->ift_metric = m; +} + +traceaction(fd, action, rt) + FILE *fd; + char *action; + struct rt_entry *rt; +{ + struct sockaddr_ns *dst, *gate; + static struct bits { + int t_bits; + char *t_name; + } flagbits[] = { + { RTF_UP, "UP" }, + { RTF_GATEWAY, "GATEWAY" }, + { RTF_HOST, "HOST" }, + { 0 } + }, statebits[] = { + { RTS_PASSIVE, "PASSIVE" }, + { RTS_REMOTE, "REMOTE" }, + { RTS_INTERFACE,"INTERFACE" }, + { RTS_CHANGED, "CHANGED" }, + { 0 } + }; + register struct bits *p; + register int first; + char *cp; + struct interface *ifp; + + if (fd == NULL) + return; + fprintf(fd, "%s ", action); + dst = (struct sockaddr_ns *)&rt->rt_dst; + gate = (struct sockaddr_ns *)&rt->rt_router; + fprintf(fd, "dst %s, ", xns_ntoa(&dst->sns_addr)); + fprintf(fd, "router %s, metric %d, flags", + xns_ntoa(&gate->sns_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; + } + } + putc('\n', fd); + if (!tracepackets && (rt->rt_state & RTS_PASSIVE) == 0 && rt->rt_ifp) + dumpif(fd, rt->rt_ifp); + fflush(fd); +} + +dumpif(fd, ifp) + register struct interface *ifp; + FILE *fd; +{ + if (ifp->int_input.ifd_count || ifp->int_output.ifd_count) { + fprintf(fd, "*** Packet history for interface %s ***\n", + ifp->int_name); + dumptrace(fd, "to", &ifp->int_output); + dumptrace(fd, "from", &ifp->int_input); + fprintf(fd, "*** end packet history ***\n"); + } +} + +dumptrace(fd, dir, ifd) + FILE *fd; + char *dir; + register struct ifdebug *ifd; +{ + register 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); + 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; + fprintf(fd, "%.24s: metric=%d\n", ctime(&t->ift_stamp), + t->ift_metric); + dumppacket(fd, dir, &t->ift_who, t->ift_packet, t->ift_size); + } +} + +dumppacket(fd, dir, who, cp, size) + FILE *fd; + struct sockaddr_ns *who; /* should be sockaddr */ + char *dir, *cp; + register int size; +{ + register struct rip *msg = (struct rip *)cp; + register struct netinfo *n; + char *xns_nettoa(); + + if (msg->rip_cmd && ntohs(msg->rip_cmd) < RIPCMD_MAX) + fprintf(fd, "%s %s %s#%x", ripcmds[ntohs(msg->rip_cmd)], + dir, xns_ntoa(&who->sns_addr), ntohs(who->sns_addr.x_port)); + else { + fprintf(fd, "Bad cmd 0x%x %s %s#%x\n", ntohs(msg->rip_cmd), + dir, xns_ntoa(&who->sns_addr), ntohs(who->sns_addr.x_port)); + fprintf(fd, "size=%d cp=%x packet=%x\n", size, cp, packet); + return; + } + switch (ntohs(msg->rip_cmd)) { + + case RIPCMD_REQUEST: + case RIPCMD_RESPONSE: + fprintf(fd, ":\n"); + size -= sizeof (u_short); + n = msg->rip_nets; + for (; size > 0; n++, size -= sizeof (struct netinfo)) { + if (size < sizeof (struct netinfo)) + break; + fprintf(fd, "\tnet %s metric %d\n", + xns_nettoa(n->rip_dst), + ntohs(n->rip_metric)); + } + break; + + } +} + +union ns_net_u net; + +char * +xns_nettoa(val) +union ns_net val; +{ + static char buf[100]; + net.net_e = val; + (void)sprintf(buf, "%lx", ntohl(net.long_e)); + return (buf); +} + + +char * +xns_ntoa(addr) +struct ns_addr *addr; +{ + static char buf[100]; + + (void)sprintf(buf, "%s#%x:%x:%x:%x:%x:%x", + xns_nettoa(addr->x_net), + addr->x_host.c_host[0], addr->x_host.c_host[1], + addr->x_host.c_host[2], addr->x_host.c_host[3], + addr->x_host.c_host[4], addr->x_host.c_host[5]); + + return(buf); +} diff --git a/usr.sbin/XNSrouted/trace.h b/usr.sbin/XNSrouted/trace.h new file mode 100644 index 0000000..b7cf3a8 --- /dev/null +++ b/usr.sbin/XNSrouted/trace.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * This file includes significant work done at Cornell University by + * Bill Nesheim. That work included by permission. + * + * 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. + * + * @(#)trace.h 8.1 (Berkeley) 6/5/93 + */ + +/* + * Xerox Routing Information Protocol. + */ + +/* + * Trace record format. + */ +struct iftrace { + time_t ift_stamp; /* time stamp */ + struct sockaddr ift_who; /* from/to */ + char *ift_packet; /* pointer to packet */ + short ift_size; /* size of packet */ + short ift_metric; /* metric */ +}; + +/* + * Per interface packet tracing buffers. An incoming and + * outgoing circular buffer of packets is maintained, per + * interface, for debugging. Buffers are dumped whenever + * an interface is marked down. + */ +struct ifdebug { + struct iftrace *ifd_records; /* array of trace records */ + struct iftrace *ifd_front; /* next empty trace record */ + int ifd_count; /* number of unprinted records */ + struct interface *ifd_if; /* for locating stuff */ +}; + +/* + * Packet tracing stuff. + */ +int tracepackets; /* watch packets as they go by */ +int tracing; /* on/off */ +FILE *ftrace; /* output trace file */ + +#define TRACE_ACTION(action, route) { \ + if (tracing) \ + traceaction(ftrace, "action", route); \ + } +#define TRACE_INPUT(ifp, src, size) { \ + if (tracing) { \ + ifp = if_iflookup(src); \ + if (ifp) \ + trace(&ifp->int_input, src, &packet[sizeof(struct idp)], size, \ + ntohl(ifp->int_metric)); \ + } \ + if (tracepackets && ftrace) \ + dumppacket(ftrace, "from", src, &packet[sizeof(struct idp)], size); \ + } +#define TRACE_OUTPUT(ifp, dst, size) { \ + if (tracing) { \ + ifp = if_iflookup(dst); \ + if (ifp) \ + trace(&ifp->int_output, dst, &packet[sizeof(struct idp)], size, ifp->int_metric); \ + } \ + if (tracepackets && ftrace) \ + dumppacket(ftrace, "to", dst, &packet[sizeof(struct idp)], size); \ + } |