1
0
Files
irix-657m-src/eoe/cmd/bsd/gated/rt_nss.c
2022-09-29 17:59:04 +03:00

181 lines
4.0 KiB
C

/*
* CENTER FOR THEORY AND SIMULATION IN SCIENCE AND ENGINEERING
* CORNELL UNIVERSITY
*
* Portions of this software may fall under the following
* copyrights:
*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* GATED - based on Kirton's EGP, UC Berkeley's routing daemon (routed),
* and DCN's HELLO routing Protocol.
*/
#ifndef lint
static char *rcsid = "$Header: /proj/irix6.5.7m/isms/eoe/cmd/bsd/gated/RCS/rt_nss.c,v 1.1 1989/09/18 19:02:19 jleong Exp $";
#endif not lint
/*
* Some modified from Routing Table Management Daemon routed/tables.c.
*
*/
#include "include.h"
#ifdef NSS
/*
* Add a route for the virtual interface route by using the IP address
* specified for the hostid.
*
*/
addrouteforbackbone()
{
struct sockaddr_in gateway;
struct interface *ifp;
bzero((char *)&gateway, sizeof (gateway));
gateway.sin_family = AF_INET;
gateway.sin_addr.s_addr = gethostid();
if ((ifp = if_withnet(&gateway)) == NULL) {
TRACE_EXT("addrouteforbackbone: no interface for %s\n", inet_ntoa(gateway.sin_addr));
return;
} else {
addrouteforif(ifp);
}
}
/*
* Returns EGP routes metric distribution
*/
egp_metric_distrib(metric_dist, max_metric)
int *metric_dist;
int max_metric;
{
struct rt_entry *rt;
struct rthash *rh;
bzero((char *) metric_dist, sizeof(int) * max_metric);
for (rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) {
for (rt = rh->rt_forw; rt != (struct rt_entry *) rh; rt = rt->rt_forw) {
if ((rt->rt_state & RTS_EXTERIOR) == 0)
continue;
if (rt->rt_proto != RTPROTO_EGP)
continue;
if (rt->rt_metric > max_metric) {
TRACE_INT("egp_metric_distrib: max_metric %d, rt_metric %d\n",
max_metric, rt->rt_metric);
continue;
}
metric_dist[rt->rt_metric]++;
}
}
}
struct rt_entry *
rt_lookupnext(dst)
struct sockaddr_in *dst;
{
struct rt_entry *rt;
struct rthash *rh;
struct sockaddr_in *rtdst;
static struct rt_entry *rt_table = NULL;
int i;
int rt_compar();
if (rttable_changed) {
rttable_changed = 0;
if (rt_table != NULL)
free((char *) rt_table);
rt_table = (struct rt_entry *) calloc(n_routes, sizeof(struct rt_entry));
if (rt_table == NULL) {
syslog(LOG_ERR, "rt_lookupnext malloc failed");
return(NULL);
}
for (i = 0, rh = nethash; rh < &nethash[ROUTEHASHSIZ]; rh++) {
for (rt = rh->rt_forw; rt != (struct rt_entry *) rh; rt = rt->rt_forw) {
bcopy((char *) rt, (char *) &rt_table[i++], sizeof(*rt));
if (i > n_routes) {
syslog(LOG_ERR, "rt_lookupnext n_routes = %d is too small",
n_routes);
return(NULL);
}
}
}
if (i != n_routes) {
syslog(LOG_ERR, "rt_lookupnext n_routes = %d, i = %d",
n_routes, i);
return(NULL);
}
qsort((char *) rt_table, n_routes, sizeof(struct rt_entry), rt_compar);
}
for (i = 0; i < n_routes; i++) {
rtdst = (struct sockaddr_in *) &rt_table[i].rt_dst;
if (dst->sin_addr.s_addr < rtdst->sin_addr.s_addr) {
break;
}
}
/*
* Check End Of Table first
*/
if (i == n_routes)
return(NULL);
else
return(&rt_table[i]);
}
rt_compar(rt1, rt2)
struct rt_entry *rt1, *rt2;
{
struct sockaddr_in *rt_dst1 = (struct sockaddr_in *) &rt1->rt_dst;
struct sockaddr_in *rt_dst2 = (struct sockaddr_in *) &rt2->rt_dst;
if (rt_dst1->sin_addr.s_addr < rt_dst2->sin_addr.s_addr)
return(-1);
else
if (rt_dst1->sin_addr.s_addr > rt_dst2->sin_addr.s_addr)
return(1);
else {
if (rt1->rt_metric < rt2->rt_metric)
return(-1);
else
if (rt1->rt_metric > rt2->rt_metric)
return(1);
else {
if (rt1->rt_proto == RTPROTO_IGP)
return(-1);
else
return(1);
}
}
}
/*
* igp_sanity_chk() checks whether a particular IGP route is sane
*/
igp_sanity_chk(rt)
struct rt_entry *rt;
{
struct rt_entry *old_rt;
if (!find_es_pdu(rt)) {
old_rt = rt;
rt = rt->rt_back;
rt_delete(old_rt, KERNEL_INTR);
return(1);
}
else
return(0);
}
#endif NSS