Annotation of 43BSD/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.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: }

unix.superglobalmegacorp.com

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