home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / manage / snmp / mit / bsd / rte.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-17  |  10.3 KB  |  482 lines

  1.  
  2. /*
  3.  *    $Header: rte.c,v 3.0 91/05/17 16:14:15 jrd Rel $
  4.  *    Author: J. Davin
  5.  *    Copyright 1988, 1989, Massachusetts Institute of Technology
  6.  *    See permission and disclaimer notice in file "notice.h"
  7.  */
  8.  
  9. #include    <notice.h>
  10.  
  11. #include    <sys/types.h>
  12. #include    <nlist.h>
  13. #include    <sys/mbuf.h>
  14. #include    <sys/socket.h>
  15. #include    <netinet/in.h>
  16. #define        KERNEL
  17. #include    <net/route.h>
  18. #undef        KERNEL
  19.  
  20. #include    <ctypes.h>
  21. #include    <error.h>
  22. #include    <debug.h>
  23. #include    <local.h>
  24. #include    <mix.h>
  25. #include    <mis.h>
  26. #include    <avl.h>
  27. #include    <asn.h>
  28.  
  29. #include    <kmem.h>
  30. #include    <rte.h>
  31.  
  32. #define        rteMaxNameSize        (16)
  33.  
  34. typedef        struct            RteRecTag {
  35.  
  36.         CUnslType        rteRecAddr;
  37.         CByteType        rteRecName [ rteMaxNameSize ];
  38.         CIntfType        rteRecNameLen;
  39.         struct    sockaddr    rteRecDst;
  40.  
  41.         }            RteRecType;
  42.  
  43. typedef        RteRecType        *RteRecPtrType;
  44.  
  45. static    AvlIdType    rteTree;
  46.  
  47. static    struct    mbuf    **rteNewTable;
  48.  
  49. static    struct mbuf    **rteHostTable;
  50. CUnslType        rteHostAddr;
  51.  
  52. static    struct mbuf    **rteNetTable;
  53. CUnslType        rteNetAddr;
  54.  
  55. static    int        rteHashSize;
  56.  
  57. static    CIntfType    rteDstToName (oid, n, dst)
  58.  
  59. CBytePtrType        oid;
  60. CIntfType        n;
  61. struct    sockaddr    *dst;
  62.  
  63. {
  64.     CBytePtrType            bp;
  65.     CIntfType            k;
  66.     CIntfType            i;
  67.  
  68.     /*
  69.      *    Should support other domains someday
  70.      */
  71.     bp = (CBytePtrType) & (((struct sockaddr_in *) dst)->sin_addr);
  72.     k = (CIntfType) 0;
  73.     for (i = sizeof (struct in_addr); (k < n) && (i != 0); i--) {
  74.         if ((*bp & (CByteType) 0x80) != (CByteType) 0) {
  75.             *oid++ = (CByteType) 129;
  76.             k++;
  77.         }
  78.         *oid++ = (*bp++ & (CByteType) 0x7F);
  79.         k++;
  80.     }
  81.  
  82.     return ((k < n) ? k : (CIntfType) -1);
  83. }
  84.  
  85. static    AvlBalanceType    rteCmpFn (info, name, namelen)
  86.  
  87. AvlInfoType        info;
  88. AvlNamePtrType        name;
  89. AvlLengthType        namelen;
  90.  
  91. {
  92.         CUnsfType               n;
  93.         CBytePtrType        cp;
  94.         CIntfType               r;
  95.  
  96.         n = ((RteRecPtrType) info)->rteRecNameLen;
  97.         cp = ((RteRecPtrType) info)->rteRecName;
  98.         r = (CIntfType) 0;
  99.         if (namelen >= n) {
  100.                 while ((n-- != 0) && ((r = (CIntfType) *name++ -
  101.                         (CIntfType) *cp++) == 0));
  102.         }
  103.         else {
  104.                 while ((namelen-- != 0) && ((r = (CIntfType) *name++ -
  105.                         (CIntfType) *cp++) == 0));
  106.                 if (r == 0) {
  107.                         r = -1;
  108.                 }
  109.         }
  110.  
  111.         if (r == 0) {
  112.                 return (avlDirBalanced);
  113.         }
  114.         else if (r < 0) {
  115.                 return (avlDirLeft);
  116.         }
  117.         else {
  118.                 return (avlDirRight);
  119.         }
  120. }
  121.  
  122. static    AsnIdType    rteRetrieve (mix, info)
  123.  
  124. MixCookieType        mix;
  125. AvlInfoType        info;
  126.  
  127. {
  128.     AsnIdType        result;
  129.     struct    rtentry        *rp;
  130.     struct    sockaddr_in    *sin;
  131.     CIntlType        value;
  132.     struct    mbuf        mbufBuf;
  133.  
  134.     if (kmemRead ((CBytePtrType) & mbufBuf, (CIntfType) sizeof (mbufBuf),
  135.         ((RteRecPtrType) info)->rteRecAddr) < (CIntfType) 0) {
  136.         result = (AsnIdType) 0;
  137.     }
  138.     else if (mbufBuf.m_type != MT_RTABLE) {
  139.         result = (AsnIdType) 0;
  140.     }
  141.     else if (bcmp ((char *)
  142.         & ((rp = mtod (& mbufBuf, struct rtentry *))->rt_dst),
  143.         (char *) & (((RteRecPtrType) info)->rteRecDst),
  144.         (int) sizeof (struct sockaddr)) != 0) {
  145.         result = (AsnIdType) 0;
  146.     }
  147.     else {
  148.         switch ((int) mix) {
  149.  
  150.         case 0:
  151.             sin = (struct sockaddr_in *) & rp->rt_dst;
  152.             result = asnOctetString (asnClassApplication,
  153.                 (AsnTagType) 0, (CBytePtrType) & sin->sin_addr,
  154.                 (AsnLengthType) 4);
  155.             break;
  156.  
  157.         case 6:
  158.             sin = (struct sockaddr_in *) & rp->rt_gateway;
  159.             result = asnOctetString (asnClassApplication,
  160.                 (AsnTagType) 0, (CBytePtrType) & sin->sin_addr,
  161.                 (AsnLengthType) 4);
  162.             break;
  163.  
  164.         case 7:
  165.             if ((rp->rt_flags & RTF_UP) == 0) {
  166.                 value = (CIntlType) 2;
  167.             }
  168.             else {
  169.                 /*
  170.                  *    Should identify routes to
  171.                  *    directly connected networks
  172.                  */
  173.                 value = (CIntlType) 4;
  174.             }
  175.             result = asnIntl (asnClassUniversal, (AsnTagType) 2,
  176.                 value);
  177.             break;
  178.  
  179.         case 8:
  180.             result = asnIntl (asnClassUniversal, (AsnTagType) 2,
  181.                 (CIntlType) 2);
  182.             break;
  183.  
  184.         case 1:
  185.             /*
  186.              *    This should be the interface index.
  187.              *    Fake it for now.
  188.              */
  189.             result = asnIntl (asnClassUniversal, (AsnTagType) 2,
  190.                 (CIntlType) 1);
  191.             break;
  192.  
  193.         case 2:
  194.         case 3:
  195.         case 4:
  196.         case 5:
  197.         case 9:
  198.             result = asnIntl (asnClassUniversal, (AsnTagType) 2,
  199.                 (CIntlType) 0);
  200.             break;
  201.  
  202.         default:
  203.             result = (AsnIdType) 0;
  204.             break;
  205.         }
  206.     }
  207.  
  208.     return (result);
  209. }
  210.  
  211. static    CUnslType    rteRefreshEntry (location)
  212.  
  213. CUnslType        location;
  214.  
  215. {
  216.     struct        mbuf    mbufBuf;
  217.     struct        rtentry    *rp;
  218.     CByteType        name [ rteMaxNameSize ];
  219.     CIntfType        namelen;
  220.     AvlInfoType        info;
  221.     RteRecPtrType        ri;
  222.  
  223.     if (kmemRead ((CBytePtrType) & mbufBuf, (CIntfType) sizeof (mbufBuf),
  224.         location) != (CIntfType) sizeof (mbufBuf)) {
  225.         return ((CUnslType) 0);
  226.     }
  227.  
  228.     if (mbufBuf.m_type != MT_RTABLE) {
  229.         return ((CUnslType) 0);
  230.     }
  231.  
  232.     rp = mtod (& mbufBuf, struct rtentry *);
  233.     namelen = rteDstToName (name, (CIntfType) sizeof (name), & rp->rt_dst);
  234.  
  235.     info = avlFind (rteTree, (AvlNamePtrType) name,
  236.         (AvlLengthType) namelen);
  237.     if (info != (AvlInfoType) 0) {
  238.         ((RteRecPtrType) info)->rteRecAddr = location;
  239.         return ((CUnslType) mbufBuf.m_next);
  240.     }
  241.  
  242.     ri = (RteRecPtrType) malloc ((unsigned) sizeof (*ri));
  243.     if (ri != (RteRecPtrType) 0) {
  244.         (void) bcopy ((char *) & rp->rt_dst, (char *) & ri->rteRecDst,
  245.             (int) sizeof (ri->rteRecDst));
  246.         (void) bcopy ((char *) name, (char *) ri->rteRecName,
  247.             (int) namelen);
  248.         ri->rteRecNameLen = namelen;
  249.         ri->rteRecAddr = location;
  250.         (void) avlInsert (rteTree, (AvlNamePtrType) name,
  251.             (AvlLengthType) namelen, (AvlInfoType) ri);
  252.     }
  253.  
  254.     return ((CUnslType) mbufBuf.m_next);
  255. }
  256.  
  257. static    CVoidType    rteRefreshBucket (memAddr)
  258.  
  259. CUnslType        memAddr;
  260.  
  261. {
  262.     while (memAddr != (CUnslType) 0) {
  263.         memAddr = rteRefreshEntry (memAddr);
  264.     }
  265. }
  266.  
  267. static    CVoidType    rteRefreshTable (table, location)
  268.  
  269. struct        mbuf    **table;
  270. CUnslType        location;
  271.  
  272. {
  273.     CUnsfType        i;
  274.  
  275.     if (kmemRead ((CBytePtrType) rteNewTable,
  276.         (CIntfType) (rteHashSize * sizeof (struct mbuf *)),
  277.         location) == (CIntfType) (rteHashSize *
  278.         sizeof (struct mbuf *))) {
  279.         for (i = 0; i < (CUnsfType) rteHashSize; i++) {
  280.             if (*table != rteNewTable [ i ]) {
  281.                 *table = rteNewTable [ i ];
  282.                 rteRefreshBucket ((CUnslType)
  283.                     rteNewTable [ i ]);
  284.             }
  285.             table++;
  286.         }
  287.     }
  288. }
  289.  
  290. static    CVoidType    rteRefresh ()
  291.  
  292. {
  293.     rteRefreshTable (rteHostTable, rteHostAddr);
  294.     rteRefreshTable (rteNetTable, rteNetAddr);
  295. }
  296.  
  297. static    MixStatusType    rteRelease (cookie)
  298.  
  299. MixCookieType        cookie;
  300.  
  301. {
  302.     cookie = cookie;
  303.     return (smpErrorGeneric);
  304. }
  305.  
  306. static    MixStatusType    rteCreate (cookie, name, namelen, asn)
  307.  
  308. MixCookieType        cookie;
  309. MixNamePtrType        name;
  310. MixLengthType        namelen;
  311. AsnIdType        asn;
  312.  
  313. {
  314.     cookie = cookie;
  315.     name = name;
  316.     namelen = namelen;
  317.     asn = asn;
  318.     return (smpErrorGeneric);
  319. }
  320.  
  321. static    MixStatusType    rteDestroy (cookie, name, namelen)
  322.  
  323. MixCookieType        cookie;
  324. MixNamePtrType        name;
  325. MixLengthType        namelen;
  326.  
  327. {
  328.     cookie = cookie;
  329.     name = name;
  330.     namelen = namelen;
  331.     return (smpErrorGeneric);
  332. }
  333.  
  334. static    AsnIdType    rteGet (cookie, name, namelen)
  335.  
  336. MixCookieType        cookie;
  337. MixNamePtrType        name;
  338. MixLengthType        namelen;
  339.  
  340. {
  341.     AvlInfoType        info;
  342.  
  343.     rteRefresh ();
  344.     info = avlFind (rteTree, (AvlNamePtrType) name,
  345.         (AvlLengthType) namelen);
  346.     if (info == (AvlInfoType) 0) {
  347.         return ((AsnIdType) 0);
  348.     }
  349.     else {
  350.         return (rteRetrieve (cookie, info));
  351.     }
  352. }
  353.  
  354. static    MixStatusType    rteSet (cookie, name, namelen, asn)
  355.  
  356. MixCookieType        cookie;
  357. MixNamePtrType        name;
  358. MixLengthType        namelen;
  359. AsnIdType        asn;
  360.  
  361. {
  362.     cookie = cookie;
  363.     name = name;
  364.     namelen = namelen;
  365.     asn = asn;
  366.     return (smpErrorGeneric);
  367. }
  368.  
  369. static    AsnIdType    rteNext (cookie, name, namelenp)
  370.  
  371. MixCookieType        cookie;
  372. MixNamePtrType        name;
  373. MixLengthPtrType    namelenp;
  374.  
  375. {
  376.     AvlInfoType        info;
  377.     AsnIdType        result;
  378.  
  379.     rteRefresh ();
  380.     do {
  381.  
  382.         info = avlCessor (rteTree, (AvlNamePtrType) name,
  383.             (AvlLengthType) *namelenp);
  384.         if (info != (AvlInfoType) 0) {
  385.             (void) bcopy ((char *)
  386.             ((RteRecPtrType) info)->rteRecName, (char *) name,
  387.             (int) ((RteRecPtrType) info)->rteRecNameLen);
  388.             *namelenp = (MixLengthType)
  389.                 ((RteRecPtrType) info)->rteRecNameLen;
  390.             result = rteRetrieve (cookie, info);
  391.         }
  392.         else {
  393.             result = (AsnIdType) 0;
  394.         }
  395.  
  396.     } while ((info != (AvlInfoType) 0) && (result == (AsnIdType) 0));
  397.  
  398.     return (result);
  399. }
  400.  
  401. static    MixOpsType    rteOps = {
  402.  
  403.             rteRelease,
  404.             rteCreate,
  405.             rteDestroy,
  406.             rteNext,
  407.             rteGet,
  408.             rteSet
  409.  
  410.             };
  411.  
  412. CVoidType        rteInit ()
  413.  
  414. {
  415.     CIntfType            i;
  416.     struct        nlist        nl [ 4 ];
  417.  
  418.     nl [ 0 ].n_name = "_rthost";
  419.     nl [ 1 ].n_name = "_rtnet";
  420.     nl [ 2 ].n_name = "_rthashsize";
  421.     nl [ 3 ].n_name = (char *) 0;
  422.     if (nlist ("/vmunix", nl) != 0) {
  423.         return;
  424.     }
  425.     rteHostAddr = (CUnslType) nl [ 0 ].n_value;
  426.     rteNetAddr = (CUnslType) nl [ 1 ].n_value;
  427.  
  428.     if (kmemRead ((CBytePtrType) & rteHashSize,
  429.         (CIntfType) sizeof (rteHashSize), nl [ 2 ].n_value) !=
  430.         (CIntfType) sizeof (rteHashSize)) {
  431.         return;
  432.     }
  433.  
  434.     DEBUG1 ("rteInit: rteHashSize %d\n", rteHashSize);
  435.     if ((rteNewTable = (struct mbuf **)
  436.         malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
  437.         (struct mbuf **) 0) {
  438.         return;
  439.     }
  440.  
  441.     if ((rteNetTable = (struct mbuf **)
  442.         malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
  443.         (struct mbuf **) 0) {
  444.         return;
  445.     }
  446.  
  447.     if ((rteHostTable = (struct mbuf **)
  448.         malloc ((unsigned) (rteHashSize * sizeof (struct mbuf *)))) ==
  449.         (struct mbuf **) 0) {
  450.         return;
  451.     }
  452.  
  453.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\1",
  454.         (MixLengthType) 9, & rteOps, (MixCookieType) 0);
  455.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\2",
  456.         (MixLengthType) 9, & rteOps, (MixCookieType) 1);
  457.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\3",
  458.         (MixLengthType) 9, & rteOps, (MixCookieType) 2);
  459.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\4",
  460.         (MixLengthType) 9, & rteOps, (MixCookieType) 3);
  461.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\5",
  462.         (MixLengthType) 9, & rteOps, (MixCookieType) 4);
  463.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\6",
  464.         (MixLengthType) 9, & rteOps, (MixCookieType) 5);
  465.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\7",
  466.         (MixLengthType) 9, & rteOps, (MixCookieType) 6);
  467.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\10",
  468.         (MixLengthType) 9, & rteOps, (MixCookieType) 7);
  469.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\11",
  470.         (MixLengthType) 9, & rteOps, (MixCookieType) 8);
  471.     (void) misExport ((MixNamePtrType) "\53\6\1\2\1\4\25\1\12",
  472.         (MixLengthType) 9, & rteOps, (MixCookieType) 9);
  473.  
  474.     rteTree = avlNew (rteCmpFn, (AvlPrintFnType) 0);
  475.  
  476.     for (i = rteHashSize - 1; i >= 0; i--) {
  477.         rteHostTable [ i ] = (struct mbuf *) 0;
  478.         rteNetTable [ i ] = (struct mbuf *) 0;
  479.     }
  480. }
  481.  
  482.