|
|
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: 10435 (0x28c3)
Types: TextFile
Names: »rte.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦697af93db⟧ »EurOpenD3/network/snmp/mit-snmp.tar.Z«
└─⟦57bbcbe75⟧
└─⟦this⟧ »./bsd/rte.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦925ee6880⟧ »EurOpenD3/network/snmp/mit-snmp.900225.tar.Z«
└─⟦a4bfa469c⟧
└─⟦this⟧ »./bsd/rte.c«
/*
* $Header: rte.c,v 1.1 89/01/11 22:10:35 jrd Exp $
* Author: J. Davin
* Copyright 1988, 1989, Massachusetts Institute of Technology
* See permission and disclaimer notice in file "notice.h"
*/
#include <notice.h>
#include <sys/types.h>
#include <nlist.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define KERNEL
#include <net/route.h>
#undef KERNEL
#include <ctypes.h>
#include <error.h>
#include <debug.h>
#include <local.h>
#include <mix.h>
#include <mis.h>
#include <avl.h>
#include <asn.h>
#include <kmem.h>
#include <rte.h>
#define rteMaxNameSize (16)
typedef struct RteRecTag {
CUnslType rteRecAddr;
CByteType rteRecName [ rteMaxNameSize ];
CIntfType rteRecNameLen;
struct sockaddr rteRecDst;
} RteRecType;
typedef RteRecType *RteRecPtrType;
static AvlIdType rteTree;
static struct mbuf **rteNewTable;
static struct mbuf **rteHostTable;
CUnslType rteHostAddr;
static struct mbuf **rteNetTable;
CUnslType rteNetAddr;
static int rteHashSize;
static CIntfType rteDstToName (oid, n, dst)
CBytePtrType oid;
CIntfType n;
struct sockaddr *dst;
{
CBytePtrType bp;
CIntfType k;
CIntfType i;
/*
* Should support other domains someday
*/
bp = (CBytePtrType) & (((struct sockaddr_in *) dst)->sin_addr);
k = (CIntfType) 0;
for (i = sizeof (struct in_addr); (k < n) && (i != 0); i--) {
if ((*bp & (CByteType) 0x80) != (CByteType) 0) {
*oid++ = (CByteType) 129;
k++;
}
*oid++ = (*bp++ & (CByteType) 0x7F);
k++;
}
return ((k < n) ? k : (CIntfType) -1);
}
static AvlBalanceType rteCmpFn (info, name, namelen)
AvlInfoType info;
AvlNamePtrType name;
AvlLengthType namelen;
{
CUnsfType n;
CBytePtrType cp;
CIntfType r;
n = ((RteRecPtrType) info)->rteRecNameLen;
cp = ((RteRecPtrType) info)->rteRecName;
r = (CIntfType) 0;
if (namelen >= n) {
while ((n-- != 0) && ((r = (CIntfType) *name++ -
(CIntfType) *cp++) == 0));
}
else {
while ((namelen-- != 0) && ((r = (CIntfType) *name++ -
(CIntfType) *cp++) == 0));
if (r == 0) {
r = -1;
}
}
if (r == 0) {
return (avlDirBalanced);
}
else if (r < 0) {
return (avlDirLeft);
}
else {
return (avlDirRight);
}
}
static AsnIdType rteRetrieve (mix, info)
MixCookieType mix;
AvlInfoType info;
{
AsnIdType result;
struct rtentry *rp;
struct sockaddr_in *sin;
CIntlType value;
struct mbuf mbufBuf;
if (kmemRead ((CBytePtrType) & mbufBuf, (CIntfType) sizeof (mbufBuf),
((RteRecPtrType) info)->rteRecAddr) < (CIntfType) 0) {
result = (AsnIdType) 0;
}
else if (mbufBuf.m_type != MT_RTABLE) {
result = (AsnIdType) 0;
}
else if (bcmp ((char *)
& ((rp = mtod (& mbufBuf, struct rtentry *))->rt_dst),
(char *) & (((RteRecPtrType) info)->rteRecDst),
(int) sizeof (struct sockaddr)) != 0) {
result = (AsnIdType) 0;
}
else {
switch ((int) mix) {
case 0:
sin = (struct sockaddr_in *) & rp->rt_dst;
result = asnOctetString (asnClassApplication,
(AsnTagType) 0, (CBytePtrType) & sin->sin_addr,
(AsnLengthType) 4);
break;
case 6:
sin = (struct sockaddr_in *) & rp->rt_gateway;
result = asnOctetString (asnClassApplication,
(AsnTagType) 0, (CBytePtrType) & sin->sin_addr,
(AsnLengthType) 4);
break;
case 7:
if ((rp->rt_flags & RTF_UP) == 0) {
value = (CIntlType) 2;
}
else {
/*
* Should identify routes to
* directly connected networks
*/
value = (CIntlType) 4;
}
result = asnIntl (asnClassUniversal, (AsnTagType) 2,
value);
break;
case 8:
result = asnIntl (asnClassUniversal, (AsnTagType) 2,
(CIntlType) 2);
break;
case 1:
/*
* This should be the interface index.
* Fake it for now.
*/
result = asnIntl (asnClassUniversal, (AsnTagType) 2,
(CIntlType) 1);
break;
case 2:
case 3:
case 4:
case 5:
case 9:
result = asnIntl (asnClassUniversal, (AsnTagType) 2,
(CIntlType) 0);
break;
default:
result = (AsnIdType) 0;
break;
}
}
return (result);
}
static CUnslType rteRefreshEntry (location)
CUnslType location;
{
struct mbuf mbufBuf;
struct rtentry *rp;
CByteType name [ rteMaxNameSize ];
CIntfType namelen;
AvlInfoType info;
RteRecPtrType ri;
if (kmemRead ((CBytePtrType) & mbufBuf, (CIntfType) sizeof (mbufBuf),
location) != (CIntfType) sizeof (mbufBuf)) {
return ((CUnslType) 0);
}
rp = mtod (& mbufBuf, struct rtentry *);
namelen = rteDstToName (name, (CIntfType) sizeof (name), & rp->rt_dst);
info = avlFind (rteTree, (AvlNamePtrType) name,
(AvlLengthType) namelen);
if (info != (AvlInfoType) 0) {
((RteRecPtrType) info)->rteRecAddr = location;
return ((CUnslType) mbufBuf.m_next);
}
ri = (RteRecPtrType) malloc ((unsigned) sizeof (*ri));
if (ri != (RteRecPtrType) 0) {
(void) bcopy ((char *) & rp->rt_dst, (char *) & ri->rteRecDst,
(int) sizeof (ri->rteRecDst));
(void) bcopy ((char *) name, (char *) ri->rteRecName,
(int) namelen);
ri->rteRecNameLen = namelen;
ri->rteRecAddr = location;
(void) avlInsert (rteTree, (AvlNamePtrType) name,
(AvlLengthType) namelen, (AvlInfoType) ri);
}
return ((CUnslType) mbufBuf.m_next);
}
static CVoidType rteRefreshBucket (memAddr)
CUnslType memAddr;
{
while (memAddr != (CUnslType) 0) {
memAddr = rteRefreshEntry (memAddr);
}
}
static CVoidType rteRefreshTable (table, location)
struct mbuf **table;
CUnslType location;
{
CUnsfType i;
if (kmemRead ((CBytePtrType) rteNewTable,
(CIntfType) (rteHashSize * sizeof (struct mbuf *)),
location) == (CIntfType) (rteHashSize *
sizeof (struct mbuf *))) {
for (i = 0; i < (CUnsfType) rteHashSize; i++) {
if (*table != rteNewTable [ i ]) {
*table = rteNewTable [ i ];
rteRefreshBucket ((CUnslType)
rteNewTable [ i ]);
}
table++;
}
}
}
static CVoidType rteRefresh ()
{
rteRefreshTable (rteHostTable, rteHostAddr);
rteRefreshTable (rteNetTable, rteNetAddr);
}
static MixStatusType rteRelease (cookie)
MixCookieType cookie;
{
cookie = cookie;
return (smpErrorGeneric);
}
static MixStatusType rteCreate (cookie, name, namelen, asn)
MixCookieType cookie;
MixNamePtrType name;
MixLengthType namelen;
AsnIdType asn;
{
cookie = cookie;
name = name;
namelen = namelen;
asn = asn;
return (smpErrorGeneric);
}
static MixStatusType rteDestroy (cookie, name, namelen)
MixCookieType cookie;
MixNamePtrType name;
MixLengthType namelen;
{
cookie = cookie;
name = name;
namelen = namelen;
return (smpErrorGeneric);
}
static AsnIdType rteGet (cookie, name, namelen)
MixCookieType cookie;
MixNamePtrType name;
MixLengthType namelen;
{
AvlInfoType info;
rteRefresh ();
info = avlFind (rteTree, (AvlNamePtrType) name,
(AvlLengthType) namelen);
if (info == (AvlInfoType) 0) {
return ((AsnIdType) 0);
}
else {
return (rteRetrieve (cookie, info));
}
}
static MixStatusType rteSet (cookie, name, namelen, asn)
MixCookieType cookie;
MixNamePtrType name;
MixLengthType namelen;
AsnIdType asn;
{
cookie = cookie;
name = name;
namelen = namelen;
asn = asn;
return (smpErrorGeneric);
}
static AsnIdType rteNext (cookie, name, namelenp)
MixCookieType cookie;
MixNamePtrType name;
MixLengthPtrType namelenp;
{
AvlInfoType info;
AsnIdType result;
rteRefresh ();
do {
info = avlCessor (rteTree, (AvlNamePtrType) name,
(AvlLengthType) *namelenp);
if (info != (AvlInfoType) 0) {
(void) bcopy ((char *)
((RteRecPtrType) info)->rteRecName, (char *) name,
(int) ((RteRecPtrType) info)->rteRecNameLen);
*namelenp = (MixLengthType)
((RteRecPtrType) info)->rteRecNameLen;
result = rteRetrieve (cookie, info);
}
else {
result = (AsnIdType) 0;
}
} while ((info != (AvlInfoType) 0) && (result == (AsnIdType) 0));
return (result);
}
static MixOpsType rteOps = {
rteRelease,
rteCreate,
rteDestroy,
rteNext,
rteGet,
rteSet
};
CVoidType rteInit ()
{
CIntfType i;
struct nlist nl [ 4 ];
nl [ 0 ].n_name = "_rthost";
nl [ 1 ].n_name = "_rtnet";
nl [ 2 ].n_name = "_rthashsize";
nl [ 3 ].n_name = (char *) 0;
if (nlist ("/vmunix", nl) != 0) {
return;
}
rteHostAddr = (CUnslType) nl [ 0 ].n_value;
rteNetAddr = (CUnslType) nl [ 1 ].n_value;
if (kmemRead ((CBytePtrType) & rteHashSize,
(CIntfType) sizeof (rteHashSize), nl [ 2 ].n_value) !=
(CIntfType) sizeof (rteHashSize)) {
return;
}
DEBUG1 ("rteInit: rteHashSize %d\n", rteHashSize);
if ((rteNewTable = (struct mbuf **)
malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
(struct mbuf **) 0) {
return;
}
if ((rteNetTable = (struct mbuf **)
malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
(struct mbuf **) 0) {
return;
}
if ((rteHostTable = (struct mbuf **)
malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
(struct mbuf **) 0) {
return;
}
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\1",
(MixLengthType) 9, & rteOps, (MixCookieType) 0);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\2",
(MixLengthType) 9, & rteOps, (MixCookieType) 1);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\3",
(MixLengthType) 9, & rteOps, (MixCookieType) 2);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\4",
(MixLengthType) 9, & rteOps, (MixCookieType) 3);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\5",
(MixLengthType) 9, & rteOps, (MixCookieType) 4);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\6",
(MixLengthType) 9, & rteOps, (MixCookieType) 5);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\7",
(MixLengthType) 9, & rteOps, (MixCookieType) 6);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\10",
(MixLengthType) 9, & rteOps, (MixCookieType) 7);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\11",
(MixLengthType) 9, & rteOps, (MixCookieType) 8);
(void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\12",
(MixLengthType) 9, & rteOps, (MixCookieType) 9);
rteTree = avlNew (rteCmpFn, (AvlPrintFnType) 0);
for (i = rteHashSize - 1; i >= 0; i--) {
rteHostTable [ i ] = (struct mbuf *) 0;
rteNetTable [ i ] = (struct mbuf *) 0;
}
}