home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * $Header: rte.c,v 3.0 91/05/17 16:14:15 jrd Rel $
- * 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);
- }
-
- if (mbufBuf.m_type != MT_RTABLE) {
- 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;
- }
- }
-
-