|
|
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;
}