Annotation of 43BSDReno/contrib/isode-beta/snmp/routes.c, revision 1.1.1.1

1.1       root        1: /* routes.c - MIB support of the routing tables */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/snmp/RCS/routes.c,v 7.2 90/05/22 20:30:31 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/snmp/RCS/routes.c,v 7.2 90/05/22 20:30:31 mrose Exp $
                      9:  *
                     10:  * Contributed by NYSERNet Inc.  This work was partially supported by the
                     11:  * U.S. Defense Advanced Research Projects Agency and the Rome Air Development
                     12:  * Center of the U.S. Air Force Systems Command under contract number
                     13:  * F30602-88-C-0016.
                     14:  *
                     15:  *
                     16:  * $Log:       routes.c,v $
                     17:  * Revision 7.2  90/05/22  20:30:31  mrose
                     18:  * cache
                     19:  * 
                     20:  * Revision 7.1  89/12/01  08:25:48  mrose
                     21:  * touch-up
                     22:  * 
                     23:  * Revision 7.0  89/11/23  22:23:21  mrose
                     24:  * Release 6.0
                     25:  * 
                     26:  */
                     27: 
                     28: /*
                     29:  *                               NOTICE
                     30:  *
                     31:  *    Acquisition, use, and distribution of this module and related
                     32:  *    materials are subject to the restrictions of a license agreement.
                     33:  *    Consult the Preface in the User's Manual for the full terms of
                     34:  *    this agreement.
                     35:  *
                     36:  */
                     37: 
                     38: 
                     39: #include <stdio.h>
                     40: #include "mib.h"
                     41: #include "interfaces.h"
                     42: #include "routes.h"
                     43: 
                     44: /*  */
                     45: 
                     46: static int routeNumber;
                     47: static struct rtetab  *rts = NULL;
                     48: static struct rtetab **rtp;
                     49: 
                     50: struct rtetab *rts_inet = NULL;
                     51: #ifdef BSD44
                     52: struct rtetab *rts_iso = NULL;
                     53: #endif
                     54: 
                     55: static int     first_time = 1;
                     56: static int     flush_cache = 0;
                     57: 
                     58: /*  */
                     59: 
                     60: static int  rt_compar (a, b)
                     61: register struct rtetab **a,
                     62:                       **b;
                     63: {
                     64:     int            i;
                     65: 
                     66:     if ((i = (*a) -> rt_dst.sa.sa_family - (*b) -> rt_dst.sa.sa_family))
                     67:        return (i > 0 ? 1 : -1);
                     68: 
                     69:     return elem_cmp ((*a) -> rt_instance, (*a) -> rt_insize,
                     70:                     (*b) -> rt_instance, (*b) -> rt_insize);
                     71: }
                     72: 
                     73: 
                     74: int    get_routes (offset)
                     75: int    offset;
                     76: {
                     77:     register int   i;
                     78:     int            rthashsize,
                     79:            tblsize;
                     80:     struct mbuf **rtaddr,
                     81:                **rtnet,
                     82:                **rthost;
                     83:     register struct rtetab  *rt,
                     84:                            *rp;
                     85:     struct nlist nzs;
                     86:     register struct nlist *nz = &nzs;
                     87:     static   int lastq = -1;
                     88: 
                     89:     if (quantum == lastq)
                     90:        return OK;
                     91:     if (!flush_cache
                     92:            && offset == type_SNMP_PDUs_get__next__request
                     93:            && quantum == lastq + 1) {                  /* XXX: caching! */
                     94:        lastq = quantum;
                     95:        return OK;
                     96:     }
                     97:     lastq = quantum, flush_cache = 0;
                     98: 
                     99:     for (rt = rts; rt; rt = rp) {
                    100:        rp = rt -> rt_next;
                    101: 
                    102:        free ((char *) rt);
                    103:     }
                    104:     rts = rts_inet = NULL;
                    105: #ifdef BSD44
                    106:     rts_iso = NULL;
                    107: #endif
                    108: 
                    109:     rtp = &rts, routeNumber = 0;
                    110: #ifdef BSD44
                    111:     if (nl[N_RADIX_NODE_HEAD].n_value) {
                    112:        if (get_radix_nodes () == NOTOK)
                    113:            goto out1;
                    114: 
                    115:        goto sort_routes;
                    116:     }
                    117: #endif
                    118: 
                    119:     if (getkmem (nl + N_RTHASHSIZE, (caddr_t) &rthashsize, sizeof rthashsize)
                    120:            == NOTOK)
                    121:        return NOTOK;
                    122:     if (rthashsize == 0)               /* XXX: why is this? */
                    123:        rthashsize = 8;
                    124:     tblsize = rthashsize * sizeof *rtaddr;
                    125:     if ((rtnet = (struct mbuf **) malloc ((unsigned) (tblsize))) == NULL
                    126:            || (rthost = (struct mbuf **) malloc ((unsigned) (tblsize)))
                    127:                    == NULL)
                    128:        adios (NULLCP, "out of memory");
                    129:     if (getkmem (nl + N_RTNET, (caddr_t) rtnet, tblsize) == NOTOK
                    130:            || getkmem (nl + N_RTHOST, (caddr_t) rthost, tblsize) == NOTOK)
                    131:        goto out2;
                    132: 
                    133:     nz -> n_name = "struct route";
                    134:     for (rtaddr = rtnet; rtaddr; rtaddr = rthost, rthost = NULL)
                    135:        for (i = 0; i < rthashsize; i++) {
                    136:            register struct mbuf *m;
                    137:            struct mbuf    ms;
                    138:            register struct rtentry *re;
                    139: 
                    140:            for (m = rtaddr[i];
                    141:                     nz -> n_value = (unsigned long) m;
                    142:                     m = ms.m_next) {
                    143:                if (getkmem (nz, (char *) &ms, sizeof ms) == NOTOK)
                    144:                    goto out2;
                    145: 
                    146: #ifndef        BSD44
                    147:                re = mtod (&ms, struct rtentry *);
                    148: #else
                    149:                re = (struct rtentry *) ms.m_dat;
                    150: #endif
                    151:                if (get_route (re) == NOTOK)
                    152:                    goto out2;
                    153:            }
                    154:        }
                    155: 
                    156:     free ((char *) rtnet);
                    157:     free ((char *) rthost);
                    158: 
                    159: #ifdef BSD44
                    160: sort_routes: ;
                    161: #endif
                    162:     if (routeNumber > 1) {
                    163:        register struct rtetab **base,
                    164:                               **rte;
                    165: 
                    166:        if ((base = (struct rtetab **)
                    167:                            malloc ((unsigned) (routeNumber * sizeof *base)))
                    168:                == NULL)
                    169:            adios (NULLCP, "out of memory");
                    170: 
                    171:        rte = base;
                    172:        for (rt = rts; rt; rt = rt -> rt_next)
                    173:            *rte++ = rt;
                    174: 
                    175:        qsort ((char *) base, routeNumber, sizeof *base, rt_compar);
                    176: 
                    177:        rtp = base;
                    178:        rt = rts = *rtp++;
                    179:        rts_inet = NULL;
                    180: #ifdef BSD44
                    181:        rts_iso = NULL;
                    182: #endif
                    183:        while (rtp < rte) {
                    184:            switch (rt -> rt_dst.sa.sa_family) {
                    185:                case AF_INET:
                    186:                    if (rts_inet == NULL)
                    187:                        rts_inet = rt;
                    188:                    break;
                    189: 
                    190: #ifdef BSD44
                    191:                case AF_ISO:
                    192:                    if (rts_iso == NULL)
                    193:                        rts_iso = rt;
                    194:                    break;
                    195: #endif
                    196:            }
                    197: 
                    198:            rt -> rt_next = *rtp;
                    199:            rt = *rtp++;
                    200:        }
                    201:        switch (rt -> rt_dst.sa.sa_family) {
                    202:            case AF_INET:
                    203:                if (rts_inet == NULL)
                    204:                    rts_inet = rt;
                    205:                break;
                    206: 
                    207: #ifdef BSD44
                    208:            case AF_ISO:
                    209:                if (rts_iso == NULL)
                    210:                    rts_iso = rt;
                    211:                break;
                    212: #endif
                    213:        }
                    214:        rt -> rt_next = NULL;
                    215: 
                    216:        free ((char *) base);
                    217:     }
                    218: 
                    219:     first_time = 0;
                    220:     return OK;
                    221: 
                    222: out2: ;
                    223:     free ((char *) rtnet);
                    224:     free ((char *) rthost);
                    225: 
                    226: #ifdef BSD44
                    227: out1: ;
                    228: #endif
                    229:     for (rt = rts; rt; rt = rp) {
                    230:        rp = rt -> rt_next;
                    231: 
                    232:        free ((char *) rt);
                    233:     }
                    234:     rts = rts_inet = NULL;
                    235: #ifdef BSD44
                    236:     rts_iso = NULL;
                    237: #endif
                    238: 
                    239:     return NOTOK;
                    240: }
                    241: 
                    242: /* */
                    243: 
                    244: static int  get_route (re)
                    245: register struct rtentry *re;
                    246: {
                    247:     register struct rtetab *rt,
                    248:                           *rz;
                    249: #ifdef BSD44
                    250:     union sockaddr_un rtsock;
                    251:     struct nlist nzs;
                    252:     register struct nlist *nz = &nzs;
                    253: #endif
                    254:     OIDentifier        oids;
                    255: 
                    256: #ifdef BSD44
                    257:     nz -> n_name = "union sockaddr_un",
                    258:     nz -> n_value = (unsigned long) rt_key (re);
                    259:     if (getkmem (nz, (caddr_t) &rtsock, sizeof rtsock) == NOTOK)
                    260:        return NOTOK;
                    261: #endif
                    262: 
                    263:     if ((rt = (struct rtetab *) calloc (1, sizeof *rt)) == NULL)
                    264:        adios (NULLCP, "out of memory");
                    265:     rt -> rt_rt = *re;     /* struct copy */
                    266: 
                    267: #ifndef        BSD44
                    268:     rt -> rt_dst.sa = re -> rt_dst;            /* struct copy */
                    269: 
                    270:     rt -> rt_gateway.sa = re -> rt_gateway;    /*   .. */
                    271: #else
                    272:     rt -> rt_dst = rtsock;                     /* struct copy */
                    273: 
                    274:     nz -> n_name = "union sockaddr_un",
                    275:     nz -> n_value = (unsigned long) re -> rt_gateway;
                    276:     if (getkmem (nz, (caddr_t) &rt -> rt_gateway, sizeof rt -> rt_gateway)
                    277:            == NOTOK)
                    278:        return NOTOK;
                    279: #endif
                    280: 
                    281:     switch (rt -> rt_dst.sa.sa_family) {
                    282:        case AF_INET:
                    283:            rt -> rt_insize =
                    284:                ipaddr2oid (rt -> rt_instance, &rt -> rt_dst.un_in.sin_addr);
                    285:            if (rts_inet == NULL)       /* in case routeNumber == 1 */
                    286:                rts_inet = rt;
                    287:            break;
                    288: 
                    289: #ifdef BSD44
                    290:        case AF_ISO:
                    291:            rt -> rt_insize =
                    292:                clnpaddr2oid (rt -> rt_instance,
                    293:                              &rt -> rt_dst.un_iso.siso_addr);
                    294:            if (rts_iso == NULL)        /* in case routeNumber == 1 */
                    295:                rts_iso = rt;
                    296:            break;
                    297: #endif
                    298: 
                    299:        default:
                    300:            bzero ((char *) rt -> rt_instance, sizeof rt -> rt_instance);
                    301:            rt -> rt_insize = 0;
                    302:            break;
                    303:     }
                    304:     
                    305:     for (rz = rts; rz; rz = rz -> rt_next)
                    306:        if (rz -> rt_dst.sa.sa_family == rt -> rt_dst.sa.sa_family
                    307:                && elem_cmp (rz -> rt_instance, rz -> rt_insize,
                    308:                             rt -> rt_instance, rt -> rt_insize) == 0)
                    309:            break;
                    310:     if (rz) {
                    311:        if (first_time) {
                    312:            oids.oid_elements = rt -> rt_instance;
                    313:            oids.oid_nelem = rt -> rt_insize;
                    314:            advise (LLOG_EXCEPTIONS, NULLCP,
                    315:                    "duplicate routes for destination %d/%s",
                    316:                    rt -> rt_dst.sa.sa_family, sprintoid (&oids));
                    317:        }
                    318: 
                    319:        rt -> rt_instance[rt -> rt_insize++] = ++rz -> rt_magic;
                    320:     }
                    321: 
                    322:     *rtp = rt, rtp = &rt -> rt_next, routeNumber++;
                    323: 
                    324:     if (debug && first_time) {
                    325:        oids.oid_elements = rt -> rt_instance;
                    326:        oids.oid_nelem = rt -> rt_insize;
                    327:        advise (LLOG_DEBUG, NULLCP,
                    328:                "add route: %d/%s on interface 0x%x with flags %d",
                    329:                rt -> rt_dst.sa.sa_family, sprintoid (&oids), re -> rt_ifp,
                    330:                re -> rt_flags);
                    331:     }
                    332: 
                    333:     return OK;
                    334: }
                    335: 
                    336: /*  */
                    337: 
                    338: #ifdef BSD44
                    339: static int  get_radix_nodes () {
                    340:     struct radix_node_head *rnh,
                    341:                            head;
                    342:     struct nlist nzs;
                    343:     register struct nlist *nz = &nzs;
                    344: 
                    345:     if (getkmem (nl + N_RADIX_NODE_HEAD, (caddr_t) &rnh, sizeof rnh) == NOTOK)
                    346:        return NOTOK;
                    347: 
                    348:     while (rnh) {
                    349:        nz -> n_name = "struct radix_node_head",
                    350:        nz -> n_value = (unsigned long) rnh;
                    351:        if (getkmem (nz, (caddr_t) &head, sizeof head) == NOTOK)
                    352:            return NOTOK;
                    353:        rnh = head.rnh_next;
                    354: 
                    355:        if (head.rnh_af == AF_UNSPEC)
                    356:            continue;
                    357: 
                    358:        if (get_radix_node (head.rnh_treetop) == NOTOK)
                    359:            return NOTOK;
                    360:     }
                    361: 
                    362:     return OK;
                    363: }
                    364: 
                    365: /*  */
                    366: 
                    367: static int  get_radix_node (rn)
                    368: struct radix_node *rn;
                    369: {
                    370:     struct radix_node rnode;
                    371:     struct rtentry rtentry;
                    372:     struct nlist nzs;
                    373:     register struct nlist *nz = &nzs;
                    374: 
                    375:     for (;;) {
                    376:        nz -> n_name = "struct radix_node",
                    377:        nz -> n_value = (unsigned long) rn;
                    378:        if (getkmem (nz, (caddr_t) &rnode, sizeof rnode) == NOTOK)
                    379:            return NOTOK;
                    380: 
                    381:        if (rnode.rn_b < 0) {
                    382:            if (!(rnode.rn_flags & RNF_ROOT)) {
                    383:                nz -> n_name = "struct rtentry",
                    384:                nz -> n_value = (unsigned long) rn;
                    385:                if (getkmem (nz, (caddr_t) &rtentry, sizeof rtentry) == NOTOK)
                    386:                    return NOTOK;
                    387: 
                    388:                if (get_route (&rtentry) == NOTOK)
                    389:                    return NOTOK;
                    390:            }
                    391: 
                    392:            if (rn = rnode.rn_dupedkey)
                    393:                continue;
                    394:        }
                    395:        else {
                    396:            if (get_radix_node (rnode.rn_l) == NOTOK
                    397:                    || get_radix_node (rnode.rn_r) == NOTOK)
                    398:                return NOTOK;
                    399:        }
                    400: 
                    401:        return OK;
                    402:     }
                    403: }
                    404: #endif
                    405: 
                    406: /*  */
                    407: 
                    408: struct rtetab *get_rtent (ip, len, head, isnext)
                    409: register unsigned int *ip;
                    410: int    len;
                    411: struct rtetab *head;
                    412: int    isnext;
                    413: {
                    414:     int            family;
                    415:     register struct rtetab *rt;
                    416: 
                    417:     if (head)
                    418:        family = head -> rt_dst.sa.sa_family;
                    419:     for (rt = head; rt; rt = rt -> rt_next)
                    420:        if (rt -> rt_dst.sa.sa_family != family)
                    421:            break;
                    422:        else
                    423:            switch (elem_cmp (rt -> rt_instance, rt -> rt_insize, ip, len)) {
                    424:                case 0:
                    425:                    if (!isnext)
                    426:                        return rt;
                    427:                    if ((rt = rt -> rt_next) == NULL
                    428:                            || rt -> rt_dst.sa.sa_family != family)
                    429:                        goto out;
                    430:                    /* else fall... */
                    431: 
                    432:                case 1:
                    433:                    return (isnext ? rt : NULL);
                    434:            }
                    435: 
                    436: out: ;
                    437:     flush_cache = 1;
                    438: 
                    439:     return NULL;
                    440: }

unix.superglobalmegacorp.com

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