summaryrefslogtreecommitdiffstats
path: root/usr.sbin/IPXrouted/tables.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/IPXrouted/tables.c')
-rw-r--r--usr.sbin/IPXrouted/tables.c419
1 files changed, 0 insertions, 419 deletions
diff --git a/usr.sbin/IPXrouted/tables.c b/usr.sbin/IPXrouted/tables.c
deleted file mode 100644
index aebc792..0000000
--- a/usr.sbin/IPXrouted/tables.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/*
- * Copyright (c) 1985, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Copyright (c) 1995 John Hay. 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.
- *
- * $FreeBSD$
- */
-
-#ifndef lint
-static const 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>
-#include <search.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#ifndef DEBUG
-#define DEBUG 0
-#endif
-
-#define FIXLEN(s) { if ((s)->sa_len == 0) (s)->sa_len = sizeof (*(s));}
-
-int install = !DEBUG; /* if 1 call kernel */
-int delete = 1;
-
-struct rthash nethash[ROUTEHASHSIZ];
-
-/*
- * Lookup dst in the tables for an exact match.
- */
-struct rt_entry *
-rtlookup(struct sockaddr *dst)
-{
- register struct rt_entry *rt;
- register struct rthash *rh;
- register u_int hash;
- struct afhash h;
-
- if (dst->sa_family >= AF_MAX)
- return (0);
- (*afswitch[dst->sa_family].af_hash)(dst, &h);
- hash = h.afh_nethash;
- rh = &nethash[hash & ROUTEHASHMASK];
- 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);
- }
- return (0);
-}
-
-/*
- * Find a route to dst as the kernel would.
- */
-struct rt_entry *
-rtfind(struct sockaddr *dst)
-{
- register struct rt_entry *rt;
- register struct rthash *rh;
- register u_int hash;
- struct afhash h;
- int af = dst->sa_family;
- int (*match)() = 0;
-
- if (af >= AF_MAX)
- return (0);
- (*afswitch[af].af_hash)(dst, &h);
-
- hash = h.afh_nethash;
- rh = &nethash[hash & ROUTEHASHMASK];
- match = afswitch[af].af_netmatch;
- for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
- if (rt->rt_hash != hash)
- continue;
- if (rt->rt_dst.sa_family == af &&
- (*match)(&rt->rt_dst, dst))
- return (rt);
- }
- return (0);
-}
-
-void
-rtadd(struct sockaddr *dst, struct sockaddr *gate, short metric,
- short ticks, int 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;
- 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_ticks = ticks;
- rt->rt_timer = 0;
- rt->rt_flags = RTF_UP | flags;
- rt->rt_state = state | RTS_CHANGED;
- rt->rt_ifp = if_ifwithnet(&rt->rt_router);
- rt->rt_clone = NULL;
- 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);
- }
- }
-}
-
-void
-rtadd_clone(struct rt_entry *ort, struct sockaddr *dst,
- struct sockaddr *gate, short metric, short ticks, int state)
-{
- struct afhash h;
- register struct rt_entry *rt;
- 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;
- hash = h.afh_nethash;
- 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_ticks = ticks;
- rt->rt_timer = 0;
- rt->rt_flags = RTF_UP | flags;
- rt->rt_state = state | RTS_CHANGED;
- rt->rt_ifp = if_ifwithnet(&rt->rt_router);
- rt->rt_clone = NULL;
- rt->rt_forw = NULL;
- rt->rt_back = NULL;
- if (metric)
- rt->rt_flags |= RTF_GATEWAY;
-
- while(ort->rt_clone != NULL)
- ort = ort->rt_clone;
- ort->rt_clone = rt;
- TRACE_ACTION("ADD_CLONE", rt);
-}
-
-void
-rtchange(struct rt_entry *rt, struct sockaddr *gate, short metric,
- short ticks)
-{
- int doioctl = 0, metricchanged = 0;
-
- FIXLEN(gate);
- /*
- * Handling of clones.
- * When the route changed and it had clones, handle it special.
- * 1. If the new route is cheaper than the clone(s), free the clones.
- * 2. If the new route is the same cost, it may be one of the clones,
- * search for it and free it.
- * 3. If the new route is more expensive than the clone(s), use the
- * values of the clone(s).
- */
- if (rt->rt_clone) {
- if ((ticks < rt->rt_clone->rt_ticks) ||
- ((ticks == rt->rt_clone->rt_ticks) &&
- (metric < rt->rt_clone->rt_metric))) {
- /*
- * Free all clones.
- */
- struct rt_entry *trt, *nrt;
-
- trt = rt->rt_clone;
- rt->rt_clone = NULL;
- while(trt) {
- nrt = trt->rt_clone;
- free((char *)trt);
- trt = nrt;
- }
- } else if ((ticks == rt->rt_clone->rt_ticks) &&
- (metric == rt->rt_clone->rt_metric)) {
- struct rt_entry *prt, *trt;
-
- prt = rt;
- trt = rt->rt_clone;
-
- while(trt) {
- if (equal(&trt->rt_router, gate)) {
- prt->rt_clone = trt->rt_clone;
- free(trt);
- trt = prt->rt_clone;
- } else {
- prt = trt;
- trt = trt->rt_clone;
- }
- }
- } else {
- /*
- * Use the values of the first clone.
- * Delete the corresponding clone.
- */
- struct rt_entry *trt;
-
- trt = rt->rt_clone;
- rt->rt_clone = rt->rt_clone->rt_clone;
- metric = trt->rt_metric;
- ticks = trt->rt_ticks;
- *gate = trt->rt_router;
- free((char *)trt);
- }
- }
-
- if (!equal(&rt->rt_router, gate))
- doioctl++;
- if ((metric != rt->rt_metric) || (ticks != rt->rt_ticks))
- metricchanged++;
- if (doioctl || metricchanged) {
- TRACE_ACTION("CHANGE FROM", rt);
- if (doioctl) {
- rt->rt_router = *gate;
- }
- rt->rt_metric = metric;
- rt->rt_ticks = ticks;
- if ((rt->rt_state & RTS_INTERFACE) && metric) {
- rt->rt_state &= ~RTS_INTERFACE;
- if(rt->rt_ifp)
- syslog(LOG_ERR,
- "changing route from interface %s (timed out)",
- rt->rt_ifp->int_name);
- else
- syslog(LOG_ERR,
- "changing route from interface ??? (timed out)");
- }
- if (metric)
- rt->rt_flags |= RTF_GATEWAY;
- else
- rt->rt_flags &= ~RTF_GATEWAY;
- rt->rt_ifp = if_ifwithnet(&rt->rt_router);
- 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",
- ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_dst)->sipx_addr),
- ipx_ntoa(&((struct sockaddr_ipx *)&rt->rt_router)->sipx_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",
- ipxdp_ntoa(&((struct sockaddr_ipx *)&rt->rt_dst)->sipx_addr),
- ipxdp_ntoa(&((struct sockaddr_ipx *)&rt->rt_router)->sipx_addr));
-#endif
- }
-}
-
-void
-rtdelete(struct rt_entry *rt)
-{
-
- struct sockaddr *sa = &(rt->rt_router);
- FIXLEN(sa);
- sa = &(rt->rt_dst);
- FIXLEN(sa);
- if (rt->rt_clone) {
- /*
- * If there is a clone we just do a rt_change to it.
- */
- struct rt_entry *trt = rt->rt_clone;
- rtchange(rt, &trt->rt_router, trt->rt_metric, trt->rt_ticks);
- return;
- }
- if (rt->rt_state & RTS_INTERFACE) {
- if (rt->rt_ifp)
- syslog(LOG_ERR,
- "deleting route to interface %s (timed out)",
- rt->rt_ifp->int_name);
- else
- syslog(LOG_ERR,
- "deleting route to interface ??? (timed out)");
- }
- TRACE_ACTION("DELETE", rt);
- if (install && rtioctl(DELETE, &rt->rt_rt) < 0)
- perror("rtioctl DELETE");
- remque(rt);
- free((char *)rt);
-}
-
-void
-rtinit(void)
-{
- register struct rthash *rh;
-
- for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
- rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
-}
-int seqno;
-
-int
-rtioctl(int action, struct rtuentry *ort)
-{
-#ifndef RTM_ADD
- if (install == 0)
- return (errno = 0);
-
- ort->rtu_rtflags = ort->rtu_flags;
-
- 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_ipx 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));
- rtm.rtm_flags = ort->rtu_flags;
- rtm.rtm_seq = ++seqno;
- rtm.rtm_addrs = RTA_DST|RTA_GATEWAY;
- bcopy((char *)&ort->rtu_dst, (char *)&w.w_dst, sizeof(w.w_dst));
- bcopy((char *)&ort->rtu_router, (char *)&w.w_gate, sizeof(w.w_gate));
- w.w_gate.sa_family = w.w_dst.sa_family = AF_IPX;
- 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 {
- rtm.rtm_addrs |= RTA_NETMASK;
- w.w_netmask = ipx_netmask;
- rtm.rtm_msglen -= sizeof(w.w_netmask) - ipx_netmask.sipx_len;
- }
- errno = 0;
- return write(r, (char *)&w, rtm.rtm_msglen);
-#endif /* RTM_ADD */
-}
OpenPOWER on IntegriCloud