Annotation of 42BSD/etc/routed/tables.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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