home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / RSPFCMD.C < prev    next >
C/C++ Source or Header  |  1994-04-17  |  12KB  |  413 lines

  1. #include "global.h"
  2. #ifdef RSPF
  3. #include "mbuf.h"
  4. #include "timer.h"
  5. #include "iface.h"
  6. #include "cmdparse.h"
  7. #include "netuser.h"
  8. #include "socket.h"
  9. #include "rspf.h"
  10. #include "ip.h"
  11.   
  12. int Rspfownmode = -1;
  13. static int dointerface __ARGS((int argc,char *argv[],void *p));
  14. static int domessage __ARGS((int argc,char *argv[],void *p));
  15. static int domaxping __ARGS((int argc,char *argv[],void *p));
  16. static int domode __ARGS((int argc,char *argv[],void *p));
  17. static int dorrhtimer __ARGS((int argc,char *argv[],void *p));
  18. static int dotimer __ARGS((int argc,char *argv[],void *p));
  19. static int doroutes __ARGS((int argc,char *argv[],void *p));
  20. static int dostatus __ARGS((int argc,char *argv[],void *p));
  21. static int dosuspect __ARGS((int argc,char *argv[],void *p));
  22. static struct timer rrhtimer, rspftimer;
  23.   
  24. static struct cmds DFAR Rspfcmds[] = {
  25.     "interface",    dointerface,    0,      0,      NULLCHAR,
  26.     "message",      domessage,      0,      0,      NULLCHAR,
  27.     "maxping",      domaxping,      0,      0,      NULLCHAR,
  28.     "mode",         domode,         0,      0,      NULLCHAR,
  29.     "rrhtimer",     dorrhtimer,     0,      0,      NULLCHAR,
  30.     "routes",       doroutes,       0,      0,      NULLCHAR,
  31.     "status",       dostatus,       0,      0,      NULLCHAR,
  32.     "suspecttimer", dosuspect,      0,      0,      NULLCHAR,
  33.     "timer",        dotimer,        0,      0,      NULLCHAR,
  34.     NULLCHAR
  35. };
  36.   
  37. int
  38. dorspf(argc,argv,p)
  39. int argc;
  40. char *argv[];
  41. void *p;
  42. {
  43.     return subcmd(Rspfcmds,argc,argv,p);
  44. }
  45.   
  46. /* The suspect timer controls how often old links expire. When a link has
  47.  * expired, we try to renew its entry by various methods.
  48.  */
  49. static int
  50. dosuspect(argc,argv,p)
  51. int argc;
  52. char *argv[];
  53. void *p;
  54. {
  55.     if(Rspfifaces == NULLRIFACE){
  56.         tputs("RSPF is not active - define interface first.\n");
  57.         return 0;
  58.     }
  59.     if(argc < 2){
  60.         tprintf("Suspect timer: %lu/%lu seconds\n",
  61.         read_timer(&Susptimer)/1000,
  62.         dur_timer(&Susptimer)/1000);
  63.         return 0;
  64.     }
  65.     Susptimer.func = rspfsuspect; /* what to call on timeout */
  66.     Susptimer.arg = NULL;                   /* dummy value */
  67.     set_timer(&Susptimer,atol(argv[1])*1000L); /* set timer duration */
  68.     start_timer(&Susptimer);                /* and fire it up */
  69.     return 0;
  70. }
  71.   
  72. /* The RRH timer controls the interval between Router-To-Router Hello
  73.  * messages. These messages announce that your station is live and well
  74.  * and that you are willing to exchange RSPF routing updates.
  75.  */
  76. static int
  77. dorrhtimer(argc,argv,p)
  78. int argc;
  79. char *argv[];
  80. void *p;
  81. {
  82.     if(Rspfifaces == NULLRIFACE){
  83.         tputs("RSPF is not active - define interface first.\n");
  84.         return 0;
  85.     }
  86.     if(argc < 2){
  87.         tprintf("RRH timer: %lu/%lu seconds\n",
  88.         read_timer(&rrhtimer)/1000,
  89.         dur_timer(&rrhtimer)/1000);
  90.         return 0;
  91.     }
  92.     rrhtimer.func = rspfevent; /* what to call on timeout */
  93.     rrhtimer.arg = (void *) &rrhtimer;
  94.     set_timer(&rrhtimer,atol(argv[1])*1000L); /* set timer duration */
  95.     start_timer(&rrhtimer);         /* and fire it up */
  96.     return 0;
  97. }
  98.   
  99. /* This timer controls the interval between the RSPF routing updates. */
  100. static int
  101. dotimer(argc,argv,p)
  102. int argc;
  103. char *argv[];
  104. void *p;
  105. {
  106.     if(Rspfifaces == NULLRIFACE){
  107.         tputs("RSPF is not active - define interface first.\n");
  108.         return 0;
  109.     }
  110.     if(argc < 2){
  111.         tprintf("RSPF update timer: %lu/%lu seconds\n",
  112.         read_timer(&rspftimer)/1000,
  113.         dur_timer(&rspftimer)/1000);
  114.         return 0;
  115.     }
  116.     rspftimer.func = rspfevent; /* what to call on timeout */
  117.     rspftimer.arg = (void *) &rspftimer;
  118.     set_timer(&rspftimer,atol(argv[1])*1000L); /* set timer duration */
  119.     start_timer(&rspftimer);                /* and fire it up */
  120.     return 0;
  121. }
  122.   
  123. /* Called when either the RRH timer, the Update timer or the Suspect timer
  124.  * expires.
  125.  */
  126. void
  127. rspfevent(t)
  128. void *t;
  129. {
  130.     int cmd;
  131.     struct mbuf *bp;
  132.     struct rspfadj *adj = NULLADJ;
  133.     struct timer *tp;
  134.     tp = (struct timer *) t;
  135.     if(tp == &rrhtimer) {
  136.         cmd = RSPFE_RRH;
  137.         start_timer(tp);
  138.     }
  139.     else if(tp == &rspftimer) {
  140.         cmd = RSPFE_UPDATE;
  141.         start_timer(tp);
  142.     }
  143.     else {
  144.         for(adj = Adjs; adj != NULLADJ; adj = adj->next)
  145.             if(&adj->timer == tp)
  146.                 break;
  147.         if(adj == NULLADJ)
  148.             return;
  149.         cmd = RSPFE_CHECK;
  150.     }
  151.     bp = ambufw(1+sizeof(int32));
  152.     *bp->data = cmd;
  153.     memcpy(bp->data + 1,&adj,sizeof(adj));
  154.     bp->cnt = bp->size;
  155.     enqueue(&Rspfinq,bp);
  156. }
  157.   
  158. static int
  159. domessage(argc,argv,p)
  160. int argc;
  161. char *argv[];
  162. void *p;
  163. {
  164.     if(argc > 2) {
  165.         tputs("Usage: rspf message \"<your message>\"\n");
  166.         return 0;
  167.     }
  168.   
  169.     if(argc < 2) {
  170.         if(Rrh_message != NULLCHAR)
  171.             tputs(Rrh_message);
  172.     }
  173.     else {
  174.         if(Rrh_message != NULLCHAR){
  175.             free(Rrh_message);
  176.             Rrh_message = NULLCHAR; /* reset the pointer */
  177.         }
  178.         if(!strlen(argv[1]))
  179.             return 0;               /* clearing the buffer */
  180.         Rrh_message = mallocw(strlen(argv[1])+5);/* allow for EOL */
  181.         strcpy(Rrh_message, argv[1]);
  182.         strcat(Rrh_message, INET_EOL);  /* add the EOL char */
  183.     }
  184.     return 0;
  185. }
  186.   
  187. static int
  188. domaxping(argc,argv,p)
  189. int argc;
  190. char *argv[];
  191. void *p;
  192. {
  193.     return setshort(&Rspfpingmax,"Max failed pings before deleting adjacency",
  194.     argc,argv);
  195. }
  196.   
  197. static int
  198. domode(argc,argv,p)
  199. int argc;
  200. char *argv[];
  201. void *p;
  202. {
  203.     if(argc < 2) {
  204.         tputs("RSPF preferred mode is ");
  205.         if(Rspfownmode == -1)
  206.             tputs("not set.\n");
  207.         else
  208.             tprintf("%s.\n",(Rspfownmode & CONNECT_MODE) ? "VC mode" :
  209.             "Datagram mode");
  210.         return 0;
  211.     }
  212.     switch(*argv[1]){
  213.         case 'v':
  214.         case 'c':
  215.         case 'V':
  216.         case 'C':
  217.             Rspfownmode = (int)CONNECT_MODE;
  218.             break;
  219.         case 'd':
  220.         case 'D':
  221.             Rspfownmode = (int)DATAGRAM_MODE;
  222.             break;
  223.         case 'n':
  224.         case 'N':
  225.             Rspfownmode = -1;
  226.             break;
  227.         default:
  228.             tputs("Usage: rspf mode [vc | datagram | none]\n");
  229.             return 1;
  230.     }
  231.     return 0;
  232. }
  233.   
  234. #ifdef AUTOROUTE
  235. int RspfActive = 0;
  236. extern int Ax25_autoroute;
  237. #endif
  238.   
  239. static int
  240. dointerface(argc,argv,p)
  241. int argc;
  242. char *argv[];
  243. void *p;
  244. {
  245.     struct rspfiface *riface;
  246.     struct iface *iface;
  247.     struct mbuf *bp;
  248.     int h,q;
  249.     if(argc < 2){
  250.         tputs("Iface    Quality    Horizon\n");
  251.         for(riface = Rspfifaces; riface != NULLRIFACE; riface = riface->next)
  252.             tprintf("%-9s%-11d%-11d\n",riface->iface->name,riface->quality,
  253.             riface->horizon);
  254.         return 0;
  255.     }
  256.     if(argc != 4){
  257.         tputs("Usage: rspf interface <name> <quality> <horizon>\n");
  258.         return 1;
  259.     }
  260.     if((iface = if_lookup(argv[1])) == NULLIF){
  261.         tputs("No such interface.\n");
  262.         return 1;
  263.     }
  264.     if(iface->broadcast == 0){
  265.         tprintf("Broadcast address for interface %s not set\n",argv[1]);
  266.         return 1;
  267.     }
  268.     q = atoi(argv[2]);
  269.     if(q < 1 || q > 127){
  270.         tputs("Quality must be between 1 and 127\n");
  271.         return 1;
  272.     }
  273.     h = atoi(argv[3]);
  274.     if(h < 1 || h > 255){
  275.         tputs("Horizon must be between 1 and 255\n");
  276.         return 1;
  277.     }
  278.     riface = (struct rspfiface *)callocw(1,sizeof(struct rspfiface));
  279.     riface->iface = iface;
  280.     riface->quality = q;
  281.     riface->horizon = h;
  282.     riface->next = Rspfifaces;
  283.     if(Rspfifaces == NULLRIFACE) {
  284. #ifdef AUTOROUTE
  285.         RspfActive = 1;        /* Make sure ARP autorouting is off ! - WG7J */
  286.         Ax25_autoroute = 0;
  287. #endif
  288.         newproc("RSPF",2048,rspfmain,0,NULL,NULL,0);
  289.     }
  290.     Rspfifaces = riface;
  291.     bp = ambufw(1+sizeof(int32));
  292.     *bp->data = RSPFE_RRH;              /* Send an RRH immediately */
  293.     memcpy(bp->data + 1,&riface,sizeof(riface));
  294.     bp->cnt = bp->size;
  295.     enqueue(&Rspfinq,bp);
  296.     return 0;
  297. }
  298.   
  299. /* Display accumulated routing updates */
  300. static int
  301. doroutes(argc,argv,p)
  302. int argc;
  303. char *argv[];
  304. void *p;
  305. {
  306.     struct mbuf *bp;
  307.     struct rspfrouter *rr;
  308.     if(Rspfifaces == NULLRIFACE){
  309.         tputs("RSPF is not active - define interface first.\n");
  310.         return 0;
  311.     }
  312.     bp = makeownupdate(INADDR_ANY,0);
  313.     if(bp == NULLBUF && Rspfrouters == NULLRROUTER) {
  314.         tputs("No routing information is available.\n");
  315.         return 0;
  316.     }
  317.     if(bp != NULLBUF) {
  318.         tputs("      Local routing update:\n");
  319.         rspfnodedump(NULLFILE,&bp,0);
  320.         tputc('\n');
  321.     }
  322.     for(rr = Rspfrouters; rr != NULLRROUTER; rr = rr->next) {
  323.         tprintf("      Time since receipt: %s",tformat(secclock() - rr->time));
  324.         if(rr->subseq != 0)
  325.             tprintf("  Last subseq: %u",uchar(rr->subseq));
  326.         if(rr->sent)
  327.             tputs("  Propagated");
  328.         tputc('\n');
  329.         if(rr->data != NULLBUF) {
  330.             dup_p(&bp,rr->data,0,len_p(rr->data));
  331.             rspfnodedump(NULLFILE,&bp,0);
  332.             tputc('\n');
  333.         }
  334.     }
  335.     return 0;
  336. }
  337.   
  338. static int
  339. dostatus(argc,argv,p)
  340. int argc;
  341. char *argv[];
  342. void *p;
  343. {
  344.     struct rspfreasm *re;
  345.     struct rspfadj *adj;
  346.     struct mbuf *bp;
  347.     union rspf rspf;
  348.     if(Rspfifaces == NULLRIFACE){
  349.         tputs("RSPF is not active - define interface first.\n");
  350.         return 0;
  351.     }
  352.     tprintf("Bad checksum %u  Bad version %u  Not RSPF interface %u\n",
  353.     Rspf_stat.badcsum,Rspf_stat.badvers,Rspf_stat.norspfiface);
  354.     tprintf("RRH in %u  RRH out %u  Update in %u  Update out %u\n",
  355.     Rspf_stat.rrhin,Rspf_stat.rrhout,Rspf_stat.updatein,
  356.     Rspf_stat.updateout);
  357.     tprintf("Non-adjacency update %u  Old node report %u  Polls sent %u\n",
  358.     Rspf_stat.noadjupdate,Rspf_stat.oldreport,Rspf_stat.outpolls);
  359.     if(Adjs == NULLADJ)
  360.         return 0;
  361.     tputs("Addr            Cost    Seq    Heard    Timer     TOS    State\n");
  362.     for(adj = Adjs; adj != NULLADJ; adj = adj->next) {
  363.         tprintf("%-15s %4u  %5u   %6lu ", inet_ntoa(adj->addr),
  364.         uchar(adj->cost),adj->seq,adj->heard);
  365.         if(run_timer(&adj->timer))
  366.             tprintf("%5lu/%-5lu",
  367.             read_timer(&adj->timer)/1000L ,dur_timer(&adj->timer)/1000L);
  368.         else
  369.             tprintf("%11s","");
  370.         tprintf("  %3u    ", uchar(adj->tos));
  371.         switch(adj->state) {
  372.             case RSPF_TENTATIVE:
  373.                 tputs("Tentative");
  374.                 break;
  375.             case RSPF_OK:
  376.                 tputs("OK");
  377.                 break;
  378.             case RSPF_SUSPECT:
  379.                 tputs("Suspect");
  380.                 break;
  381.             case RSPF_BAD:
  382.                 tputs("Bad");
  383.                 break;
  384.             default:
  385.                 tputs("Unknown");
  386.                 break;
  387.         }
  388.         tputc('\n');
  389.     }
  390.     if(run_timer(&Rspfreasmt)) {
  391.         tprintf("Reassembly timer running: %lu/%lu seconds\n",
  392.         read_timer(&Rspfreasmt)/1000L, dur_timer(&Rspfreasmt)/1000L);
  393.     }
  394.     if(Rspfreasmq != NULLRREASM)
  395.         tputs("Reassembly fragments:\n");
  396.     for(re = Rspfreasmq; re != NULLRREASM; re = re->next) {
  397.         tprintf("src %s time since last frag %s",inet_ntoa(re->addr),
  398.         tformat((secclock() - re->time)));
  399.         if(dup_p(&bp,re->data,0,RSPFPKTLEN) == RSPFPKTLEN &&
  400.             ntohrspf(&rspf,&bp) != -1)
  401.             tprintf(" frag count %u/%u\n",len_q(re->data),
  402.             rspf.pkthdr.fragtot);
  403.         else {
  404.             tputc('\n');
  405.             free_p(bp);
  406.             continue;
  407.         }
  408.     }
  409.     return 0;
  410. }
  411. #endif /* RSPF */
  412.   
  413.