|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T r
Length: 9189 (0x23e5) Types: TextFile Names: »routes.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/snmp/routes.c«
/* routes.c - MIB support of the routing tables */ #ifndef lint static char *rcsid = "$Header: /f/osi/snmp/RCS/routes.c,v 7.1 89/12/01 08:25:48 mrose Exp $"; #endif /* * $Header: /f/osi/snmp/RCS/routes.c,v 7.1 89/12/01 08:25:48 mrose Exp $ * * Contributed by NYSERNet Inc. This work was partially supported by the * U.S. Defense Advanced Research Projects Agency and the Rome Air Development * Center of the U.S. Air Force Systems Command under contract number * F30602-88-C-0016. * * * $Log: routes.c,v $ * Revision 7.1 89/12/01 08:25:48 mrose * touch-up * * Revision 7.0 89/11/23 22:23:21 mrose * Release 6.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ #include <stdio.h> #include "mib.h" #include "interfaces.h" #include "routes.h" /* \f */ static int routeNumber; static struct rtetab *rts = NULL; static struct rtetab **rtp; struct rtetab *rts_inet = NULL; #ifdef BSD44 struct rtetab *rts_iso = NULL; #endif static int first_time = 1; /* \f */ static int rt_compar (a, b) register struct rtetab **a, **b; { int i; if ((i = (*a) -> rt_dst.sa.sa_family - (*b) -> rt_dst.sa.sa_family)) return (i > 0 ? 1 : -1); return elem_cmp ((*a) -> rt_instance, (*a) -> rt_insize, (*b) -> rt_instance, (*b) -> rt_insize); } int get_routes () { register int i; int rthashsize, tblsize; struct mbuf **rtaddr, **rtnet, **rthost; register struct rtetab *rt, *rp; struct nlist nzs; register struct nlist *nz = &nzs; static int lastq = -1; if (quantum == lastq) return OK; lastq = quantum; for (rt = rts; rt; rt = rp) { rp = rt -> rt_next; free ((char *) rt); } rts = rts_inet = NULL; #ifdef BSD44 rts_iso = NULL; #endif rtp = &rts, routeNumber = 0; #ifdef BSD44 if (nl[N_RADIX_NODE_HEAD].n_value) { if (get_radix_nodes () == NOTOK) goto out1; goto sort_routes; } #endif if (getkmem (nl + N_RTHASHSIZE, (caddr_t) &rthashsize, sizeof rthashsize) == NOTOK) return NOTOK; if (rthashsize == 0) /* XXX: why is this? */ rthashsize = 8; tblsize = rthashsize * sizeof *rtaddr; if ((rtnet = (struct mbuf **) malloc ((unsigned) (tblsize))) == NULL || (rthost = (struct mbuf **) malloc ((unsigned) (tblsize))) == NULL) adios (NULLCP, "out of memory"); if (getkmem (nl + N_RTNET, (caddr_t) rtnet, tblsize) == NOTOK || getkmem (nl + N_RTHOST, (caddr_t) rthost, tblsize) == NOTOK) goto out2; nz -> n_name = "struct route"; for (rtaddr = rtnet; rtaddr; rtaddr = rthost, rthost = NULL) for (i = 0; i < rthashsize; i++) { register struct mbuf *m; struct mbuf ms; register struct rtentry *re; for (m = rtaddr[i]; nz -> n_value = (unsigned long) m; m = ms.m_next) { if (getkmem (nz, (char *) &ms, sizeof ms) == NOTOK) goto out2; #ifndef BSD44 re = mtod (&ms, struct rtentry *); #else re = (struct rtentry *) ms.m_dat; #endif if (get_route (re) == NOTOK) goto out2; } } free ((char *) rtnet); free ((char *) rthost); #ifdef BSD44 sort_routes: ; #endif if (routeNumber > 1) { register struct rtetab **base, **rte; if ((base = (struct rtetab **) malloc ((unsigned) (routeNumber * sizeof *base))) == NULL) adios (NULLCP, "out of memory"); rte = base; for (rt = rts; rt; rt = rt -> rt_next) *rte++ = rt; qsort ((char *) base, routeNumber, sizeof *base, rt_compar); rtp = base; rt = rts = *rtp++; rts_inet = NULL; #ifdef BSD44 rts_iso = NULL; #endif while (rtp < rte) { switch (rt -> rt_dst.sa.sa_family) { case AF_INET: if (rts_inet == NULL) rts_inet = rt; break; #ifdef BSD44 case AF_ISO: if (rts_iso == NULL) rts_iso = rt; break; #endif } rt -> rt_next = *rtp; rt = *rtp++; } switch (rt -> rt_dst.sa.sa_family) { case AF_INET: if (rts_inet == NULL) rts_inet = rt; break; #ifdef BSD44 case AF_ISO: if (rts_iso == NULL) rts_iso = rt; break; #endif } rt -> rt_next = NULL; free ((char *) base); } first_time = 0; return OK; out2: ; free ((char *) rtnet); free ((char *) rthost); #ifdef BSD44 out1: ; #endif for (rt = rts; rt; rt = rp) { rp = rt -> rt_next; free ((char *) rt); } rts = rts_inet = NULL; #ifdef BSD44 rts_iso = NULL; #endif return NOTOK; } /* \f */ static int get_route (re) register struct rtentry *re; { register struct rtetab *rt, *rz; #ifdef BSD44 union sockaddr_un rtsock; struct nlist nzs; register struct nlist *nz = &nzs; #endif OIDentifier oids; #ifdef BSD44 nz -> n_name = "union sockaddr_un", nz -> n_value = (unsigned long) rt_key (re); if (getkmem (nz, (caddr_t) &rtsock, sizeof rtsock) == NOTOK) return NOTOK; #endif if ((rt = (struct rtetab *) calloc (1, sizeof *rt)) == NULL) adios (NULLCP, "out of memory"); rt -> rt_rt = *re; /* struct copy */ #ifndef BSD44 rt -> rt_dst.sa = re -> rt_dst; /* struct copy */ rt -> rt_gateway.sa = re -> rt_gateway; /* .. */ #else rt -> rt_dst = rtsock; /* struct copy */ nz -> n_name = "union sockaddr_un", nz -> n_value = (unsigned long) re -> rt_gateway; if (getkmem (nz, (caddr_t) &rt -> rt_gateway, sizeof rt -> rt_gateway) == NOTOK) return NOTOK; #endif switch (rt -> rt_dst.sa.sa_family) { case AF_INET: rt -> rt_insize = ipaddr2oid (rt -> rt_instance, &rt -> rt_dst.un_in.sin_addr); if (rts_inet == NULL) /* in case routeNumber == 1 */ rts_inet = rt; break; #ifdef BSD44 case AF_ISO: rt -> rt_insize = clnpaddr2oid (rt -> rt_instance, &rt -> rt_dst.un_iso.siso_addr); if (rts_iso == NULL) /* in case routeNumber == 1 */ rts_iso = rt; break; #endif default: bzero ((char *) rt -> rt_instance, sizeof rt -> rt_instance); rt -> rt_insize = 0; break; } for (rz = rts; rz; rz = rz -> rt_next) if (rz -> rt_dst.sa.sa_family == rt -> rt_dst.sa.sa_family && elem_cmp (rz -> rt_instance, rz -> rt_insize, rt -> rt_instance, rt -> rt_insize) == 0) break; if (rz) { if (first_time) { oids.oid_elements = rt -> rt_instance; oids.oid_nelem = rt -> rt_insize; advise (LLOG_EXCEPTIONS, NULLCP, "duplicate routes for destination %d/%s", rt -> rt_dst.sa.sa_family, sprintoid (&oids)); } rt -> rt_instance[rt -> rt_insize++] = ++rz -> rt_magic; } *rtp = rt, rtp = &rt -> rt_next, routeNumber++; if (debug && first_time) { oids.oid_elements = rt -> rt_instance; oids.oid_nelem = rt -> rt_insize; advise (LLOG_DEBUG, NULLCP, "add route: %d/%s on interface 0x%x with flags %d", rt -> rt_dst.sa.sa_family, sprintoid (&oids), re -> rt_ifp, re -> rt_flags); } return OK; } /* \f */ #ifdef BSD44 static int get_radix_nodes () { struct radix_node_head *rnh, head; struct nlist nzs; register struct nlist *nz = &nzs; if (getkmem (nl + N_RADIX_NODE_HEAD, (caddr_t) &rnh, sizeof rnh) == NOTOK) return NOTOK; while (rnh) { nz -> n_name = "struct radix_node_head", nz -> n_value = (unsigned long) rnh; if (getkmem (nz, (caddr_t) &head, sizeof head) == NOTOK) return NOTOK; rnh = head.rnh_next; if (head.rnh_af == AF_UNSPEC) continue; if (get_radix_node (head.rnh_treetop) == NOTOK) return NOTOK; } return OK; } /* \f */ static int get_radix_node (rn) struct radix_node *rn; { struct radix_node rnode; struct rtentry rtentry; struct nlist nzs; register struct nlist *nz = &nzs; for (;;) { nz -> n_name = "struct radix_node", nz -> n_value = (unsigned long) rn; if (getkmem (nz, (caddr_t) &rnode, sizeof rnode) == NOTOK) return NOTOK; if (rnode.rn_b < 0) { if (!(rnode.rn_flags & RNF_ROOT)) { nz -> n_name = "struct rtentry", nz -> n_value = (unsigned long) rn; if (getkmem (nz, (caddr_t) &rtentry, sizeof rtentry) == NOTOK) return NOTOK; if (get_route (&rtentry) == NOTOK) return NOTOK; } if (rn = rnode.rn_dupedkey) continue; } else { if (get_radix_node (rnode.rn_l) == NOTOK || get_radix_node (rnode.rn_r) == NOTOK) return NOTOK; } return OK; } } #endif /* \f */ struct rtetab *get_rtent (ip, len, head, isnext) register unsigned int *ip; int len; struct rtetab *head; int isnext; { int family; register struct rtetab *rt; if (head) family = head -> rt_dst.sa.sa_family; for (rt = head; rt; rt = rt -> rt_next) if (rt -> rt_dst.sa.sa_family != family) break; else switch (elem_cmp (rt -> rt_instance, rt -> rt_insize, ip, len)) { case 0: if (!isnext) return rt; if ((rt = rt -> rt_next) == NULL || rt -> rt_dst.sa.sa_family != family) return NULL; /* else fall... */ case 1: return (isnext ? rt : NULL); } return NULL; }