home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / stg_v4.lzh / sroute.c < prev    next >
C/C++ Source or Header  |  1994-11-11  |  11KB  |  585 lines

  1. /*
  2.  * sroute - list/change network routing tables
  3.  *
  4.  * 93/04/24 StG initial version
  5.  *
  6. */
  7.  
  8. /* maximum # of nodes that can net with me */
  9. #define MAX_ONEHOP 64
  10.  
  11. /* maximum number of hops to get to any other node */
  12. #define MAX_HOPS 64
  13.  
  14. #include "stgnet.h"
  15. #include "db9.h"
  16.  
  17. #include "nodes.h"
  18.  
  19. char buf[256];
  20.  
  21. char hostname[32];
  22.  
  23. int iAuto=0;
  24. int iDisplay=0;
  25. int iNetList=0;
  26. int iRemove=0;
  27.  
  28. struct sNode sNode;
  29. int hNet;
  30.  
  31. struct sNode sScan;
  32. int hScan;
  33.  
  34. struct sRoute
  35. {
  36.     char acName[28];
  37.     long lSpeed;
  38.     int iHops;
  39. };
  40.  
  41. struct sRoute asRoute[MAX_ONEHOP];
  42. int iRoutes=0;
  43.  
  44. struct sRoute asHop[MAX_HOPS];
  45. int iHops=0;
  46.  
  47. InRoute(s)
  48. char *s;
  49. {
  50.     int r;
  51.  
  52.     r=0;
  53.     while (r<iRoutes)
  54.     {
  55.         if (!stricmp(s,asRoute[r].acName))
  56.             break;
  57.         r++;
  58.     }
  59.     if (r==iRoutes)
  60.         return(0);
  61.     return(1);
  62. }
  63.  
  64. void
  65. AddRoute(s)
  66. char *s;
  67. {
  68.     int r;
  69.  
  70.     if (!*s)
  71.         return;
  72.  
  73.     r=0;
  74.     while (r<iRoutes)
  75.     {
  76.         if (!stricmp(s,asRoute[r].acName))
  77.             break;
  78.         r++;
  79.     }
  80.  
  81.  
  82.     if (r==iRoutes)
  83.     {
  84.         if (iDisplay>1 && !iRoutes)
  85.             writeln(1,"One Hop list:\n",80);
  86.  
  87.         if (++iRoutes==MAX_ONEHOP)
  88.             exit(syserr("maximum one hop array exceeded"));
  89.  
  90.         strcpy(asRoute[r].acName,s);
  91.         if (iDisplay>1)
  92.         {
  93.             stringf(b,"%s\n",s);
  94.             writeln(1,b,80);
  95.         }
  96.     }
  97. }
  98.  
  99. Used(name)
  100. char *name;
  101. {
  102.     int i;
  103.  
  104.     i=0;
  105.     while (i<iRoutes)
  106.         if (!stricmp(name,asRoute[i++].acName))
  107.             return(1);
  108.  
  109.     i=0;
  110.     while (i<iHops)
  111.         if (!stricmp(name,asHop[i++].acName))
  112.             return(1);
  113.     return(0);
  114. }
  115.  
  116. Search(name)
  117. char *name;
  118. {
  119.     int n;
  120.     char *pc;
  121.     int first=1;
  122.  
  123.     *sScan.acN_Name=0;
  124.     iHops-=1;
  125. search:
  126.     if (iHops<0)
  127.         return(0);
  128.  
  129.     if (stricmp(asHop[iHops].acName,sScan.acN_Name))
  130.     {
  131.         pc=asHop[iHops].acName;
  132.         n=_db9(DB_SEEK,hScan,pc,strlen(pc)+1);
  133.         if (n==ERR)
  134.             exit(syserr("DB9 seek %s: %m",pc));
  135.         if (!n)
  136.         {
  137.             /* not found, go back */
  138.             iHops--;
  139.             goto search;
  140.         }
  141.         if (_db9(DB_READ,hScan,&sScan,sizeof(sScan))==ERR)
  142.             exit(syserr("DB9 read scan: %m"));
  143.  
  144.         asHop[iHops].lSpeed=sScan.wN_Speed;
  145.  
  146.     }
  147.     if (!asHop[iHops].iHops && !first)
  148.     {
  149.         if (!stricmp(asHop[iHops].acName,name))
  150.         {
  151.             iHops++;    
  152.             return(1);
  153.         }
  154.     }
  155.     first=0;
  156.     while (asHop[iHops].iHops<4)
  157.     {
  158.         n=asHop[iHops].iHops++;
  159.         pc=sScan.asNode2[n].acN2_Name;
  160.         if (!*pc || Used(pc))
  161.             continue;
  162.         iHops++;
  163.         if (iHops==MAX_HOPS)
  164.             exit(syserr("maximum route depth exceeded"));
  165.         strcpy(asHop[iHops].acName,pc);
  166.         asHop[iHops].iHops=0;
  167.         goto search;
  168.     }
  169.     if (asHop[iHops].iHops<5)
  170.     {
  171.         if (iHops+1==MAX_HOPS)
  172.             exit(syserr("maximum route depth exceeded"));
  173.  
  174.         n=_db9(DB_SEEK,hScan,0,0);
  175.         if (n==ERR)
  176.             exit(syserr("DB9 seek 0: %m"));
  177.         asHop[iHops].iHops++;
  178.     }
  179.     else
  180.     {
  181.         pc=asHop[iHops+1].acName;
  182.         n=_db9(DB_SEEK,hScan,pc,strlen(pc)+1);
  183.         if (n==ERR)
  184.             exit(syserr("DB9 seek %s: %m",pc));
  185.         if (!n)
  186.             exit(syserr("bug: node %s not refound",pc));
  187.     }
  188.     while (n=_db9(DB_NEXT,hScan,&sScan,sizeof(sScan)))
  189.     {
  190.         n=0;
  191.         while (n<4)
  192.         {
  193.             if (!stricmp(asHop[iHops].acName,sScan.asNode2[n].acN2_Name))
  194.             {
  195.                 iHops++;
  196.                 strcpy(asHop[iHops].acName,sScan.acN_Name);
  197.                 asHop[iHops].iHops=0;
  198.                 goto search;
  199.             }
  200.             n++;
  201.         }
  202.     }
  203.     iHops--;
  204.     goto search;
  205. }
  206.  
  207. void
  208. Auto()
  209. {
  210.     char acNew[32];
  211.     long lSpeed;
  212.     int r,h,best,d;
  213.     int iNewHops;
  214.  
  215.     /* don't bother with dead, down, or local */
  216.     if (sNode.bN_Status==NS_DEAD)
  217.         return;
  218.     if (sNode.bN_Status==NS_DOWN)    
  219.         return;
  220.     if (!stricmp(hostname,sNode.acN_Name))
  221.         return;
  222.  
  223.     /* preset new with current setting */
  224.     strcpy(acNew,sNode.sRoute.acN2_Name);
  225.  
  226.     if (iDisplay>1)
  227.     {
  228.         stringf(b,"Auto-selecting route for node %s (currently '%s'):\n",
  229.             sNode.acN_Name,acNew);
  230.         writeln(1,b,80);
  231.     }
  232.  
  233.     /* if no route settings, cancel */
  234.     if (!iRoutes)
  235.     {
  236.         *acNew=0;
  237.         iNewHops=0;
  238.         goto change;
  239.     }
  240.  
  241.     /* scan route table for single hop */
  242.     r=0;
  243.     while (r<iRoutes)
  244.     {
  245.         if (!stricmp(sNode.acN_Name,asRoute[r].acName))
  246.             break;
  247.         asRoute[r].lSpeed=0;
  248.         asRoute[r].iHops=0;
  249.         r++;
  250.     }
  251.     if (r<iRoutes)
  252.     {
  253.         strcpy(acNew,asRoute[r].acName);
  254.         iNewHops=1;
  255.         if (iDisplay>1)
  256.         {
  257.             stringf(b,"%s -> %s (one hop)\n",hostname,acNew);
  258.             writeln(1,b,80);
  259.         }
  260.         goto change;
  261.     }
  262.  
  263.     /* search deeper through each 1st hop to find sNode.acN_Name */
  264.     r=0;
  265.     while (r<iRoutes)
  266.     {
  267.         /* preset first hop and search deeper */
  268.         iHops=0;
  269.         asHop[iHops].iHops=0;
  270.         strcpy(asHop[iHops++].acName,asRoute[r].acName);
  271.         while (Search(sNode.acN_Name))
  272.         {
  273.             /* route found, tally speed and build display */
  274.             if (iDisplay>1)
  275.                 writeln(1,hostname,strlen(hostname));
  276.  
  277.             lSpeed=0;
  278.             h=0;
  279.             while (h<iHops)
  280.             {
  281.                 if (iDisplay>1)
  282.                 {
  283.                     writeln(1," -> ",4);
  284.                     writeln(1,asHop[h].acName,strlen(asHop[h].acName));
  285.                 }
  286.                 lSpeed+=asHop[h++].lSpeed;
  287.             }
  288.             if (iDisplay>1)
  289.             {
  290.                 sprintf(b,": %d00 avg baud\n",(int)(lSpeed/iHops));
  291.                 writeln(1,b,strlen(b));
  292.             }
  293.             
  294.             /* if best, save route */
  295.             if (!asRoute[r].iHops || iHops<asRoute[r].iHops)
  296.             {
  297.                 asRoute[r].iHops=iHops;
  298.                 asRoute[r].lSpeed=lSpeed;
  299.             }
  300.             if (iHops==asRoute[r].iHops && lSpeed>asRoute[r].lSpeed)
  301.             {
  302.                 asRoute[r].lSpeed=lSpeed;
  303.             }
  304.         }
  305.         r++;
  306.     }
  307.  
  308.     /* search route table for best route */
  309.     best=-1;
  310.     r=0;
  311.     d=-1;
  312.     lSpeed=0;
  313.     iHops=MAX_HOPS;
  314.     while (r<iRoutes)
  315.     {
  316.         if (!stricmp(sNode.sRoute.acN2_Name,asRoute[r].acName))
  317.             d=r;
  318.         if (best==-1 || asRoute[r].iHops<=iHops)
  319.         {
  320.             if (asRoute[r].iHops!=iHops)
  321.                 lSpeed=0;
  322.             if (asRoute[r].iHops && asRoute[r].lSpeed>lSpeed)
  323.             {
  324.                 best=r;
  325.                 iHops=asRoute[r].iHops;
  326.                 lSpeed=asRoute[r].lSpeed;
  327.             }
  328.         }
  329.         r++;
  330.     }
  331.     /* no route to sNode.acN_Name? */
  332.     if (best<0)
  333.     {
  334.         *acNew=0;
  335.         iNewHops=0;
  336.         goto change;
  337.     }
  338.  
  339.     /* current default not in route table? */
  340.     if (d<0 || !asRoute[d].iHops)
  341.     {
  342.         strcpy(acNew,asRoute[best].acName);
  343.         iNewHops=asRoute[best].iHops;
  344.         goto change;
  345.     }
  346.  
  347.     /* check default against best */
  348.     if (asRoute[best].iHops<asRoute[d].iHops)
  349.     {
  350.         strcpy(acNew,asRoute[best].acName);
  351.         iNewHops=asRoute[best].iHops;
  352.     }
  353.  
  354.     if (asRoute[best].iHops==asRoute[d].iHops)
  355.     {
  356.         if (asRoute[best].lSpeed>asRoute[d].lSpeed)
  357.         {
  358.             strcpy(acNew,asRoute[best].acName);
  359.             iNewHops=asRoute[best].iHops;
  360.         }
  361.     }
  362.  
  363. change:
  364.     if (stricmp(sNode.sRoute.acN2_Name,acNew))
  365.     {
  366.         sNode.sRoute.bN2_Hops=iNewHops;
  367.  
  368.         if (iDisplay)
  369.             Display(acNew);
  370.  
  371.         strcpy(sNode.sRoute.acN2_Name,acNew);
  372.  
  373.         if (_db9(DB_WRITE,hNet,&sNode,sizeof(sNode))==ERR)
  374.             exit(syserr("DB9 write nodes: %m"));
  375.     }
  376. }
  377.  
  378. Display(new)
  379. char *new;
  380. {
  381.     if (sNode.bN_Status==NS_DEAD)
  382.         strcpy(buf,"(DEAD)");
  383.     else
  384.     if (sNode.bN_Status==NS_DOWN)
  385.         strcpy(buf,"(down)");
  386.     else
  387.     if (!stricmp(hostname,sNode.acN_Name))
  388.         strcpy(buf,"(local)");
  389.     else
  390.         strcpy(buf,sNode.sRoute.acN2_Name);
  391.  
  392.     if (!*buf)
  393.         strcpy(buf,"(no route)");
  394.  
  395.     if (new)
  396.     {
  397.         if (!*new)
  398.             new="(no route)";
  399.         stringf(b,"Route to node %s was %s, changed to %s (%d hops)\n",
  400.             sNode.acN_Name,buf,new,sNode.sRoute.bN2_Hops);
  401.     }
  402.     else
  403.         stringf(b,"%-15.15s %-15.15s (%d hops)\n",
  404.             sNode.acN_Name,buf,sNode.sRoute.bN2_Hops);
  405.  
  406.     writeln(1,b,strlen(b));
  407. }
  408.  
  409. main(argc,argv)
  410. char **argv;
  411. {
  412.     int n;
  413.  
  414.     openerr(*argv,0,LOG_STGNET);
  415.  
  416.     gethostname(hostname,32);
  417.     if (!*hostname)
  418.         exit(syserr("network not configured"));
  419.  
  420.     dash(argv)
  421.     {
  422.     case '#':
  423.         wstringf(2,"sroute: %s\n",STG_VER);
  424.         exit(0);
  425.  
  426.     case '?':
  427.         writeln(2,"sroute {-adn} {node} {route} - list/change routing\n",80);
  428.         writeln(2,"  -a        - figure best routes automatically\n",80);
  429.         writeln(2,"  -d        - display automatic mode decisions\n",80);
  430.         writeln(2,"  -n        - display list of nodes netting with this one\n",80);
  431.         writeln(2,"  node      - list/change specified node\n",80);
  432.         writeln(2,"  route     - change routing for node\n",80);
  433.         STGVER;
  434.         exit(0);
  435.  
  436.     case 'a':
  437.         iAuto++;
  438.         break;
  439.  
  440.     case 'd':
  441.         iDisplay++;
  442.         break;
  443.  
  444.     case 'n':
  445.         iNetList++;
  446.         break;
  447.  
  448.     case 'r':
  449.         iRemove++;
  450.         break;
  451.  
  452.     default:
  453.         exit(syserr("invalid option: %s",--*argv));
  454.     }
  455.  
  456.     if (getuid()>=16 && (iAuto || iRemove || iDisplay ||*argv))
  457.         exit(syserr("no permission"));
  458.  
  459.     setuid(0);
  460.  
  461.     hNet=open(STG_FILE,O_RDWR|O_BINARY);
  462.     if (hNet==ERR)
  463.         exit(syserr("open %s: %m",STG_FILE));
  464.  
  465.     if (_db9(DB_OPEN,hNet,"nodes",6)==ERR)
  466.         exit(syserr("DB9 open nodes: %m"));
  467.  
  468.     /* select case insensitive seek */
  469.     if (_db9(DB_MATCH,hNet,-1,0)==ERR)
  470.         exit(syserr("DB9 match c-i: %m"));
  471.  
  472.     hScan=open(STG_FILE,O_RDONLY|O_BINARY);
  473.     if (hScan==ERR)
  474.         exit(syserr("open %s: %m",STG_FILE));
  475.  
  476.     if (_db9(DB_OPEN,hScan,"nodes",6)==ERR)
  477.         exit(syserr("DB9 open nodes: %m"));
  478.  
  479.     /* select case insensitive seek */
  480.     if (_db9(DB_MATCH,hScan,-1,0)==ERR)
  481.         exit(syserr("DB9 match c-i: %m"));
  482.  
  483.     /* build route choice list */
  484.     while (n=_db9(DB_NEXT,hScan,&sScan,sizeof(sScan)))
  485.     {
  486.         if (n==ERR)
  487.             exit(syserr("DB9 next: %m"));
  488.  
  489.         /* if this is me, put all my routes on list */
  490.         if (!stricmp(sScan.acN_Name,hostname))
  491.         {
  492.             n=0;
  493.             while (n<4)
  494.                 AddRoute(sScan.asNode2[n++].acN2_Name);
  495.             continue;
  496.         }
  497.  
  498.         /* else if this node contacts me, put it on list */
  499.         n=0;
  500.         while (n<4)
  501.         {
  502.             if (!stricmp(hostname,sScan.asNode2[n++].acN2_Name))
  503.             {
  504.                 AddRoute(sScan.acN_Name);
  505.                 continue;
  506.             }
  507.         }
  508.     }
  509.  
  510.     if (iNetList)
  511.     {
  512.         n=0;
  513.         while (n<iRoutes)
  514.         {
  515.             stringf(b,"%s\n",asRoute[n++].acName);
  516.             writeln(1,b,strlen(b));
  517.         }
  518.         exit(0);
  519.     }
  520.  
  521.     if (*argv)
  522.     {
  523.         n=_db9(DB_SEEK,hNet,*argv,strlen(*argv)+1);
  524.         if (n==ERR)
  525.             exit(syserr("DB9 seek %s: %m",*argv));
  526.  
  527.         if (!n)
  528.             exit(syserr("node %s not found",*argv));
  529.  
  530.         if (_db9(DB_READ,hNet,&sNode,sizeof(sNode))==ERR)
  531.             exit(syserr("DB9 read nodes: %m"));
  532.  
  533.         if (*++argv)
  534.         {
  535.             if (!InRoute(*argv))
  536.                 exit(syserr("node %s not in net list",*argv));
  537.  
  538.             Display(*argv);
  539.             strcpy(sNode.sRoute.acN2_Name,*argv);
  540.  
  541.             if (_db9(DB_WRITE,hNet,&sNode,sizeof(sNode))==ERR)
  542.                 exit(syserr("DB9 write nodes: %m"));
  543.  
  544.             /* relock */
  545.             if (_db9(DB_READ,hNet,&sNode,sizeof(sNode))==ERR)
  546.                 exit(syserr("DB9 read nodes: %m"));
  547.  
  548.             /* allow automatic mode to override */
  549.             if (!iDisplay)
  550.                 iDisplay=1;
  551.             Auto();
  552.         }
  553.         else
  554.         {
  555.             if (iAuto)
  556.                 Auto();
  557.             else
  558.                 Display(0);
  559.         }
  560.  
  561.         close(hNet);
  562.         exit(0);
  563.     }
  564.  
  565.     while (n=_db9(DB_NEXT,hNet,&sNode,sizeof(sNode)))
  566.     {
  567.         if (n==ERR)
  568.             exit(syserr("DB9 next: %m"));
  569.  
  570.         if (iRemove)
  571.         {
  572.             sNode.sRoute.bN2_Hops=0;
  573.             *sNode.sRoute.acN2_Name=0;
  574.             if (_db9(DB_WRITE,hNet,&sNode,sizeof(sNode))==ERR)
  575.                 exit(syserr("DB9 write nodes: %m"));
  576.         }
  577.  
  578.         if (iAuto)
  579.             Auto();
  580.         else
  581.             Display(0);
  582.     }
  583.     close(hNet);
  584. }
  585.