1: /*
   2:  * Copyright (c) 1985 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  */
   7: 
   8: 
   9: #ifndef lint
  10: static char sccsid[] = "@(#)tables.c	5.5 (Berkeley) 2/14/86";
  11: #endif not lint
  12: 
  13: /*
  14:  * Routing Table Management Daemon
  15:  */
  16: #include "defs.h"
  17: #include <sys/ioctl.h>
  18: #include <errno.h>
  19: 
  20: #ifndef DEBUG
  21: #define DEBUG   0
  22: #endif
  23: 
  24: int install = !DEBUG;       /* if 1 call kernel */
  25: int delete = 1;
  26: /*
  27:  * Lookup dst in the tables for an exact match.
  28:  */
  29: struct rt_entry *
  30: rtlookup(dst)
  31:     struct sockaddr *dst;
  32: {
  33:     register struct rt_entry *rt;
  34:     register struct rthash *rh;
  35:     register u_int hash;
  36:     struct afhash h;
  37:     int doinghost = 1;
  38: 
  39:     if (dst->sa_family >= AF_MAX)
  40:         return (0);
  41:     (*afswitch[dst->sa_family].af_hash)(dst, &h);
  42:     hash = h.afh_hosthash;
  43:     rh = &hosthash[hash & ROUTEHASHMASK];
  44: again:
  45:     for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
  46:         if (rt->rt_hash != hash)
  47:             continue;
  48:         if (equal(&rt->rt_dst, dst))
  49:             return (rt);
  50:     }
  51:     if (doinghost) {
  52:         doinghost = 0;
  53:         hash = h.afh_nethash;
  54:         rh = &nethash[hash & ROUTEHASHMASK];
  55:         goto again;
  56:     }
  57:     return (0);
  58: }
  59: 
  60: /*
  61:  * Find a route to dst as the kernel would.
  62:  */
  63: struct rt_entry *
  64: rtfind(dst)
  65:     struct sockaddr *dst;
  66: {
  67:     register struct rt_entry *rt;
  68:     register struct rthash *rh;
  69:     register u_int hash;
  70:     struct afhash h;
  71:     int af = dst->sa_family;
  72:     int doinghost = 1, (*match)();
  73: 
  74:     if (af >= AF_MAX)
  75:         return (0);
  76:     (*afswitch[af].af_hash)(dst, &h);
  77:     hash = h.afh_hosthash;
  78:     rh = &hosthash[hash & ROUTEHASHMASK];
  79: 
  80: again:
  81:     for (rt = rh->rt_forw; rt != (struct rt_entry *)rh; rt = rt->rt_forw) {
  82:         if (rt->rt_hash != hash)
  83:             continue;
  84:         if (doinghost) {
  85:             if (equal(&rt->rt_dst, dst))
  86:                 return (rt);
  87:         } else {
  88:             if (rt->rt_dst.sa_family == af &&
  89:                 (*match)(&rt->rt_dst, dst))
  90:                 return (rt);
  91:         }
  92:     }
  93:     if (doinghost) {
  94:         doinghost = 0;
  95:         hash = h.afh_nethash;
  96:         rh = &nethash[hash & ROUTEHASHMASK];
  97:         match = afswitch[af].af_netmatch;
  98:         goto again;
  99:     }
 100:     return (0);
 101: }
 102: 
 103: rtadd(dst, gate, metric, state)
 104:     struct sockaddr *dst, *gate;
 105:     int metric, state;
 106: {
 107:     struct afhash h;
 108:     register struct rt_entry *rt;
 109:     struct rthash *rh;
 110:     int af = dst->sa_family, flags;
 111:     u_int hash;
 112: 
 113:     if (af >= AF_MAX)
 114:         return;
 115:     (*afswitch[af].af_hash)(dst, &h);
 116:     flags = (*afswitch[af].af_ishost)(dst) ? RTF_HOST : 0;
 117:     if (flags & RTF_HOST) {
 118:         hash = h.afh_hosthash;
 119:         rh = &hosthash[hash & ROUTEHASHMASK];
 120:     } else {
 121:         hash = h.afh_nethash;
 122:         rh = &nethash[hash & ROUTEHASHMASK];
 123:     }
 124:     rt = (struct rt_entry *)malloc(sizeof (*rt));
 125:     if (rt == 0)
 126:         return;
 127:     rt->rt_hash = hash;
 128:     rt->rt_dst = *dst;
 129:     rt->rt_router = *gate;
 130:     rt->rt_metric = metric;
 131:     rt->rt_timer = 0;
 132:     rt->rt_flags = RTF_UP | flags;
 133:     rt->rt_state = state | RTS_CHANGED;
 134:     rt->rt_ifp = if_ifwithnet(&rt->rt_router);
 135:     if (metric)
 136:         rt->rt_flags |= RTF_GATEWAY;
 137:     insque(rt, rh);
 138:     TRACE_ACTION(ADD, rt);
 139:     /*
 140: 	 * If the ioctl fails because the gateway is unreachable
 141: 	 * from this host, discard the entry.  This should only
 142: 	 * occur because of an incorrect entry in /etc/gateways.
 143: 	 */
 144:     if (install && ioctl(s, SIOCADDRT, (char *)&rt->rt_rt) < 0) {
 145:         syslog(LOG_ERR,"SIOCADDRT: %m");
 146:         if (errno == ENETUNREACH) {
 147:             TRACE_ACTION(DELETE, rt);
 148:             remque(rt);
 149:             free((char *)rt);
 150:         }
 151:     }
 152: }
 153: 
 154: rtchange(rt, gate, metric)
 155:     struct rt_entry *rt;
 156:     struct sockaddr *gate;
 157:     short metric;
 158: {
 159:     int doioctl = 0, metricchanged = 0;
 160:     struct rtentry oldroute;
 161: 
 162:     if (!equal(&rt->rt_router, gate))
 163:         doioctl++;
 164:     if (metric != rt->rt_metric)
 165:         metricchanged++;
 166:     if (doioctl || metricchanged) {
 167:         TRACE_ACTION(CHANGE FROM, rt);
 168:         if (doioctl) {
 169:             oldroute = rt->rt_rt;
 170:             rt->rt_router = *gate;
 171:         }
 172:         rt->rt_metric = metric;
 173:         if ((rt->rt_state & RTS_INTERFACE) && metric) {
 174:             rt->rt_state &= ~RTS_INTERFACE;
 175:             syslog(LOG_ERR,
 176:                 "changing route from interface %s (timed out)",
 177:                 rt->rt_ifp->int_name);
 178:         }
 179:         if (metric)
 180:             rt->rt_flags |= RTF_GATEWAY;
 181:         else
 182:             rt->rt_flags &= ~RTF_GATEWAY;
 183:         rt->rt_state |= RTS_CHANGED;
 184:         TRACE_ACTION(CHANGE TO, rt);
 185:     }
 186:     if (doioctl && install) {
 187:         if (ioctl(s, SIOCADDRT, (char *)&rt->rt_rt) < 0)
 188:             syslog(LOG_ERR,"SIOCADDRT %m");
 189:         if (delete)
 190:         if (ioctl(s, SIOCDELRT, (char *)&oldroute) < 0)
 191:             syslog(LOG_ERR,"SIOCDELRT %m");
 192:     }
 193: }
 194: 
 195: rtdelete(rt)
 196:     struct rt_entry *rt;
 197: {
 198: 
 199:     if (rt->rt_state & RTS_INTERFACE) {
 200:         syslog(LOG_ERR, "deleting route to interface %s (timed out)",
 201:             rt->rt_ifp->int_name);
 202:     }
 203:     TRACE_ACTION(DELETE, rt);
 204:     if (install && ioctl(s, SIOCDELRT, (char *)&rt->rt_rt))
 205:         perror("SIOCDELRT");
 206:     remque(rt);
 207:     free((char *)rt);
 208: }
 209: 
 210: rtinit()
 211: {
 212:     register struct rthash *rh;
 213: 
 214:     for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++)
 215:         rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
 216:     for (rh = hosthash; rh < &hosthash[ROUTEHASHSIZ]; rh++)
 217:         rh->rt_forw = rh->rt_back = (struct rt_entry *)rh;
 218: }

Defined functions

rtadd defined in line 103; used 2 times
rtchange defined in line 154; used 1 times
rtdelete defined in line 195; used 2 times
rtfind defined in line 63; used 4 times
rtinit defined in line 210; used 1 times

Defined variables

delete defined in line 25; used 1 times
install defined in line 24; used 3 times
sccsid defined in line 10; never used

Defined macros

DEBUG defined in line 21; used 2 times
Last modified: 1986-02-15
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1404
Valid CSS Valid XHTML 1.0 Strict