Annotation of 43BSDTahoe/etc/XNSrouted/tables.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.