home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / KA9Q / MSWIN / RTSORT.ZIP / IPCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-08  |  12.7 KB  |  558 lines

  1. /* IP-related user commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4.  /* Mods by PA0GRI */
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "config.h"
  8. #include "mbuf.h"
  9. #include "internet.h"
  10. #include "timer.h"
  11. #include "netuser.h"
  12. #include "iface.h"
  13. #include "session.h"
  14. #include "ip.h"
  15. #include "cmdparse.h"
  16. #include "commands.h"
  17. #include "rip.h"
  18. #include "rspf.h"
  19.  
  20. int32 Ip_addr;
  21.  
  22. int Route_Sort=1;
  23.  
  24. static int doadd __ARGS((int argc,char *argv[],void *p));
  25. #ifdef  IPACCESS
  26. static int doaccess __ARGS((int argc,char *argv[],void *p));
  27. #endif
  28. static int dodrop __ARGS((int argc,char *argv[],void *p));
  29. static int doflush __ARGS((int argc,char *argv[],void *p));
  30. static int doipaddr __ARGS((int argc,char *argv[],void *p));
  31. static int doipstat __ARGS((int argc,char *argv[],void *p));
  32. static int dolook __ARGS((int argc,char *argv[],void *p));
  33. static int dortimer __ARGS((int argc,char *argv[],void *p));
  34. static int dottl __ARGS((int argc,char *argv[],void *p));
  35. static void dumproute __ARGS((struct route *rp,char *p));
  36. static int doroutesort __ARGS((int argc,char *argv[],void *p));
  37.  
  38. static struct cmds Ipcmds[] = {
  39. #ifdef  IPACCESS
  40.     "access",       doaccess,       0,      0, NULLCHAR,
  41. #endif
  42.     "address",      doipaddr,       0,      0, NULLCHAR,
  43.     "rtimer",       dortimer,       0,      0, NULLCHAR,
  44.     "status",       doipstat,       0,      0, NULLCHAR,
  45.     "ttl",          dottl,          0,      0, NULLCHAR,
  46.     NULLCHAR,
  47. };
  48. /* "route" subcommands */
  49. static struct cmds Rtcmds[] = {
  50.     "add",          doadd,          0,      3,
  51.     "route add <dest addr>[/<bits>] <if name> [<gateway> | direct [metric]]",
  52.  
  53.     "addprivate",   doadd,          0,      3,
  54.     "route addprivate <dest addr>[/<bits>] <if name> [<gateway> | direct [metric]]",
  55.  
  56.     "drop",         dodrop,         0,      2,
  57.     "route drop <dest addr>[/<bits>]",
  58.  
  59.     "flush",        doflush,        0,      0,
  60.     NULLCHAR,
  61.  
  62.     "lookup",       dolook,         0,      2,
  63.     "route lookup <dest addr>",
  64.  
  65.     "sort",         doroutesort,    0,      0,
  66.     NULLCHAR,
  67.  
  68.     NULLCHAR,
  69. };
  70.  
  71. int
  72. doip(argc,argv,p)
  73. int argc;
  74. char *argv[];
  75. void *p;
  76. {
  77.     return subcmd(Ipcmds,argc,argv,p);
  78. }
  79. #ifdef  IPACCESS
  80. static int
  81. doaccess(argc,argv,p)
  82. int argc;
  83. char *argv[];
  84. void *p;
  85. {
  86.     struct iface *ifp;
  87.     int32 target;
  88.     unsigned bits;
  89.     char *bitp;
  90.     int16 lport,hport,state;
  91.     char *cp; /* for printing the table */
  92.     struct rtaccess *tpacc;
  93.     struct rtaccess *btacc;
  94.     struct rtaccess *bfacc;
  95.     struct rtaccess *head;
  96.  
  97.     if(argc == 1){ /* print out the table */
  98.         tprintf("IP Address      Mask Interface     Low Port High Port State\n");
  99.         for(tpacc = IPaccess;tpacc != NULLACCESS;tpacc = tpacc->nxtiface){
  100.             for(btacc = tpacc;btacc != NULLACCESS;btacc = btacc->nxtbits){
  101.                 if(btacc->target != 0)
  102.                     cp = inet_ntoa(btacc->target);
  103.                 else
  104.                     cp = "all";
  105.                 tprintf("%-16s",cp);
  106.                 tprintf("%4u ",btacc->bits);
  107.                 tprintf("%-13s",btacc->iface->name);
  108.                 tprintf("%9u",btacc->lowport);
  109.                 tprintf("%10u ",btacc->highport);
  110.                 if(btacc->status)
  111.                     cp = "deny";
  112.                 else
  113.                     cp = "permit";
  114.                 tprintf("%-6s\n",cp);
  115.             }
  116.         }
  117.         return 0;
  118.     }
  119.  
  120.     if(strcmp(argv[1],"permit") == 0){
  121.         state = 0;
  122.     } else {
  123.         if((strcmp(argv[1],"deny") == 0)
  124.         || (strcmp(argv[1],"delete") == 0)){
  125.             state = -1;
  126.         } else {
  127.             tprintf(" Format: ip access <permit|deny|delete> <dest addr>[/<bits>] <if name> [lowport [highport]]\n");
  128.             return 1;
  129.         }
  130.     }
  131.     if(strcmp(argv[2],"all") == 0){
  132.         target = 0;
  133.         bits = 0;
  134.     } else {
  135.         /* If IP address is followed by an optional slash and
  136.          * a length field, (e.g., 128.96/16) get it;
  137.          * otherwise assume a full 32-bit address
  138.          */
  139.         if((bitp = strchr(argv[2],'/')) != NULLCHAR){
  140.             /* Terminate address token for resolve() call */
  141.             *bitp++ = '\0';
  142.             bits = atoi(bitp);
  143.         } else
  144.             bits = 32;
  145.  
  146.         if((target = resolve(argv[2])) == 0){
  147.             tprintf(Badhost,argv[2]);
  148.             return 1;
  149.         }
  150.     }
  151.  
  152.     if((ifp = if_lookup(argv[3])) == NULLIF){
  153.         tprintf("Interface \"%s\" unknown\n",argv[3]);
  154.         return 1;
  155.     }
  156.     if(argc > 4){
  157.         if(strcmp(argv[4],"all") == 0){
  158.             lport = 1;
  159.             hport = 65534;
  160.         } else {
  161.             lport = atoi(argv[4]);
  162.             hport = lport;
  163.         }
  164.     } else {
  165.         lport = 0;
  166.         hport = 0;
  167.     }
  168.     if(argc > 5)
  169.         hport = atoi(argv[5]);
  170.  
  171.     if(strcmp(argv[1],"delete") == 0){
  172.         head = IPaccess;
  173.         for(tpacc = IPaccess;tpacc != NULLACCESS;head = tpacc,tpacc = tpacc->nxtiface){
  174.             if(tpacc->iface == ifp){
  175.                 for(btacc = tpacc;btacc != NULLACCESS;
  176.                      head = btacc,btacc = btacc->nxtbits){
  177.                     if((btacc->target == target) &&
  178.                        (btacc->bits == bits)     &&
  179.                        (btacc->lowport == lport) &&
  180.                        (btacc->highport == hport)) { /*match*/
  181.                         bfacc = btacc; /* save to unalloc */
  182.                 /*now delete. watch for special cases*/
  183.                         if(btacc != tpacc){ /* not at head of list */
  184.                          head->nxtbits = btacc->nxtbits;
  185.                             free(bfacc);
  186.                             return 0;
  187.                         }
  188.                         if(btacc == IPaccess){ /* real special case */
  189.                         if(IPaccess->nxtbits == NULLACCESS)
  190.                             IPaccess = btacc->nxtiface;
  191.                         else {
  192.                             IPaccess = btacc->nxtbits;
  193.                             (btacc->nxtbits)->nxtiface = btacc->nxtiface;
  194.                         }
  195.                         } else { /* we know tpacc=btacc <> IPaccess */
  196.                         if(btacc->nxtbits == NULLACCESS)
  197.                             head->nxtiface = btacc->nxtiface;
  198.                         else {
  199.                             head->nxtiface = btacc->nxtbits;
  200.                             (btacc->nxtbits)->nxtiface = btacc->nxtiface;
  201.                         }
  202.                         }
  203.                     free(bfacc);
  204.                     return 0;
  205.                     }
  206.                 }
  207.             }
  208.         }
  209.         tprintf("Not found.\n");
  210.         return 1;
  211.     }
  212.     /* add the access */
  213.     addaccess(target,bits,ifp,lport,hport,state);
  214.     return 0;
  215. }
  216. #endif
  217. static int
  218. doipaddr(argc,argv,p)
  219. int argc;
  220. char *argv[];
  221. void *p;
  222. {
  223.     int32 n;
  224.  
  225.     if(argc < 2) {
  226.         tprintf("%s\n",inet_ntoa(Ip_addr));
  227.     } else if((n = resolve(argv[1])) == 0){
  228.         tprintf(Badhost,argv[1]);
  229.         return 1;
  230.     } else
  231.         Ip_addr = n;
  232.     return 0;
  233. }
  234. static int
  235. dortimer(argc,argv,p)
  236. int argc;
  237. char *argv[];
  238. void *p;
  239. {
  240.     return setlong(&ipReasmTimeout,"IP reasm timeout (sec)",argc,argv);
  241. }
  242. static int
  243. dottl(argc,argv,p)
  244. int argc;
  245. char *argv[];
  246. void *p;
  247. {
  248.     return setlong(&ipDefaultTTL,"IP Time-to-live",argc,argv);
  249. }
  250.  
  251.  
  252. /* Display and/or manipulate routing table */
  253. int
  254. doroute(argc,argv,p)
  255. int argc;
  256. char *argv[];
  257. void *p;
  258. {
  259.     register int i,j,k,l,m,bits,numflg;
  260.     register struct route *rp;
  261.     char *temp,temp2[80];
  262.  
  263.     if(argc >= 2)
  264.         return subcmd(Rtcmds,argc,argv,p);
  265.  
  266.     /* Dump IP routing table
  267.      * Dest            Len Interface    Gateway          Use
  268.      * 192.001.002.003 32  sl0          192.002.003.004  0
  269.      * modified for Sorted output - D. Crompton 2.92
  270.      */
  271.  
  272.     Current->flowmode = 1;          /* start *more* processing */
  273.     tprintf(
  274. "  Destination    Len Interface    Gateway          Metric  P Timer  Use\n");
  275.  
  276.  
  277.     for(j=0,bits=31;bits>=0;bits--)
  278.        for(i=0;i<HASHMOD;i++)
  279.           for(rp = Routes[bits][i];rp != NULLROUTE;j++,rp = rp->next);
  280.  
  281.     if (j){
  282.     
  283.       temp=mallocw(j*80);
  284.  
  285.       for(bits=31,k=0;bits>=0;bits--)
  286.         for(i=0;i<HASHMOD;i++)
  287.             for(rp = Routes[bits][i];rp != NULLROUTE;rp = rp->next,k+=80)
  288.                 dumproute(rp,&temp[k]);
  289.       
  290.       if (Route_Sort) qsort(temp,(size_t)j,80,strcmp);              
  291.     
  292.       for (i=0,k=4;i<j;i++,k+=80) {
  293.           tprintf("%s",&temp[k]);
  294.           if (tprintf("\n") == EOF)
  295.              {
  296.               Current->flowmode=0;
  297.               free(temp);
  298.               return 0;
  299.              }
  300.       }
  301.       if(R_default.iface != NULLIF){
  302.         dumproute(&R_default,temp);
  303.         tprintf("%s\n",temp);
  304.       }
  305.     }
  306.     Current->flowmode = 0;
  307.     free(temp);
  308.     return 0;
  309. }
  310. /* Add an entry to the routing table
  311.  * E.g., "add 1.2.3.4 ax0 5.6.7.8 3"
  312.  */
  313. static int
  314. doadd(argc,argv,p)
  315. int argc;
  316. char *argv[];
  317. void *p;
  318. {
  319.     struct iface *ifp;
  320.     int32 dest,gateway;
  321.     unsigned bits;
  322.     char *bitp;
  323.     int32 metric;
  324.     char private;
  325.  
  326.     if(strncmp(argv[0],"addp",4) == 0)
  327.         private = 1;
  328.     else
  329.         private = 0;
  330.     if(strcmp(argv[1],"default") == 0){
  331.         dest = 0L;
  332.         bits = 0;
  333.     } else {
  334.         /* If IP address is followed by an optional slash and
  335.          * a length field, (e.g., 128.96/16) get it;
  336.          * otherwise assume a full 32-bit address
  337.          */
  338.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  339.             /* Terminate address token for resolve() call */
  340.             *bitp++ = '\0';
  341.             bits = atoi(bitp);
  342.         } else
  343.             bits = 32;
  344.  
  345.         if((dest = resolve(argv[1])) == 0){
  346.             tprintf(Badhost,argv[1]);
  347.             return 1;
  348.         }
  349.     }
  350.     if((ifp = if_lookup(argv[2])) == NULLIF){
  351.         tprintf("Interface \"%s\" unknown\n",argv[2]);
  352.         return 1;
  353.     }
  354.  
  355.     metric = 1;
  356.  
  357.     if(argc > 3){
  358.         /* Next "trick is needed to set the metric on subnets
  359.          * higher as the default 1 for rspf.
  360.          * route add subnet/bits iface default 10  
  361.          */
  362.         if(strcmp(argv[3],"direct") == 0){      /* N1BEE */
  363.             gateway = 0;
  364.         /* calculate a nice metric based on subnet mask size */
  365.             if(bits != 0 && bits < 32)
  366.                 metric = (39 - bits) * 5 / 17;
  367.         } else {
  368.             if((gateway = resolve(argv[3])) == 0){
  369.                 tprintf(Badhost,argv[3]);
  370.                 return 1;
  371.             }
  372.         }
  373.     } else {
  374.         gateway = 0;
  375.     }
  376.     if (argc > 4)
  377.         metric = atol(argv[4]);
  378.  
  379.     if(rt_add(dest,bits,gateway,ifp,metric,0,private) == NULLROUTE)
  380.         tprintf("Can't add route\n");
  381. #ifdef  RSPF
  382.     if(!private)
  383.         rspfrouteupcall(dest,bits,gateway);     /* Do an RSPF upcall */
  384. #endif  /* RSPF */
  385.     return 0;
  386. }
  387. /* Drop an entry from the routing table
  388.  * E.g., "drop 128.96/16
  389.  */
  390. static int
  391. dodrop(argc,argv,p)
  392. int argc;
  393. char *argv[];
  394. void *p;
  395. {
  396.     char *bitp;
  397.     unsigned bits;
  398.     int32 n;
  399.  
  400.     if(strcmp(argv[1],"default") == 0){
  401.         n = 0L;
  402.         bits = 0;
  403.     } else {
  404.         /* If IP address is followed by an optional slash and length field,
  405.          * (e.g., 128.96/16) get it; otherwise assume a full 32-bit address
  406.          */
  407.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  408.             /* Terminate address token for resolve() call */
  409.             *bitp++ = '\0';
  410.             bits = atoi(bitp);
  411.         } else
  412.             bits = 32;
  413.  
  414.         if((n = resolve(argv[1])) == 0){
  415.             tprintf(Badhost,argv[1]);
  416.             return 1;
  417.         }
  418.     }
  419.     return rt_drop(n,bits);
  420. }
  421. /* Force a timeout on all temporary routes */
  422. static int
  423. doflush(argc,argv,p)
  424. int argc;
  425. char *argv[];
  426. void *p;
  427. {
  428.     register struct route *rp;
  429.     struct route *rptmp;
  430.     int i,j;
  431.     
  432.     if(R_default.timer.state == TIMER_RUN){
  433.         rt_drop(0,0);   /* Drop default route */
  434.     }
  435.     for(i=0;i<HASHMOD;i++){
  436.         for(j=0;j<32;j++){
  437.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  438.                 rptmp = rp->next;
  439.                 if(rp->timer.state == TIMER_RUN){
  440.                     rt_drop(rp->target,rp->bits);
  441.                 }
  442.             }
  443.         }
  444.     }
  445.     return 0;
  446. }
  447. /* Dump a routing table entry */
  448. static void
  449. dumproute(rp,temp)
  450. register struct route *rp;
  451. char *temp;
  452. {
  453.     char *cp;
  454.     unsigned a=0;        
  455.                   
  456.  
  457.     if(rp->target != 0) {
  458.         cp = inet_ntobos(rp->target);
  459.         a=sprintf(temp,"%4s",cp);
  460.         cp = inet_ntoa(rp->target);
  461.     
  462.     } else {
  463.         cp = "default";
  464.     }
  465.     a+=sprintf(&temp[a],"%-17s",cp);
  466.     a+=sprintf(&temp[a],"%-4u",rp->bits);
  467.     a+=sprintf(&temp[a],"%-13s",rp->iface->name);
  468.     if(rp->gateway != 0)
  469.         cp = inet_ntoa(rp->gateway);
  470.     else
  471.         cp = "";
  472.     a+=sprintf(&temp[a],"%-17s",cp);
  473.     a+=sprintf(&temp[a],"%-8lu",rp->metric);
  474.     a+=sprintf(&temp[a],"%c ",(rp->flags & RTPRIVATE) ? 'P' : ' ');
  475.     if(rp->timer.state == TIMER_STOP){
  476.         if(rp->timer.duration == 1) a+=sprintf(&temp[a],"rspf   ");
  477.         else a+=sprintf(&temp[a],"man    ");
  478.     } else {
  479.         a+=sprintf(&temp[a],"%-7lu",read_timer(&rp->timer) / 1000L);
  480.     }
  481.     sprintf(&temp[a],"%lu",rp->uses);
  482. }
  483.  
  484. static int
  485. dolook(argc,argv,p)
  486. int argc;
  487. char *argv[];
  488. void *p;
  489. {
  490.     struct route *rp;
  491.     int32 addr;
  492.     char temp[80];
  493.  
  494.     addr = resolve(argv[1]);
  495.     if(addr == 0){
  496.         tprintf("Host %s unknown\n",argv[1]);
  497.         return 1;
  498.     }
  499.     if((rp = rt_lookup(addr)) == NULLROUTE){
  500.         tprintf("Host %s (%s) unreachable\n",argv[1],inet_ntoa(addr));
  501.         return 1;
  502.     }
  503.     dumproute(rp,temp);
  504.     tprintf("%s\n",temp);
  505.     return 0;
  506. }
  507.  
  508. static int
  509. doipstat(argc,argv,p)
  510. int argc;
  511. char *argv[];
  512. void *p;
  513. {
  514.     register struct reasm *rp;
  515.     register struct frag *fp;
  516.     int i;
  517.  
  518.     for(i=1;i<=NUMIPMIB;i++){
  519.         tprintf("(%2u)%-20s%10lu",i,
  520.          Ip_mib[i].name,Ip_mib[i].value.integer);
  521.         if(i % 2)
  522.             tprintf("     ");
  523.         else
  524.             tprintf("\n");
  525.     }
  526.     if((i % 2) == 0)
  527.         tprintf("\n");
  528.  
  529.     if(Reasmq != NULLREASM)
  530.         tprintf("Reassembly fragments:\n");
  531.     for(rp = Reasmq;rp != NULLREASM;rp = rp->next){
  532.         tprintf("src %s",inet_ntoa(rp->source));
  533.         tprintf(" dest %s",inet_ntoa(rp->dest));
  534.         if(tprintf(" id %u pctl %u time %lu len %u\n",
  535.          rp->id,uchar(rp->protocol),read_timer(&rp->timer),
  536.          rp->length) == EOF)
  537.             break;
  538.         for(fp = rp->fraglist;fp != NULLFRAG;fp = fp->next){
  539.             if(tprintf(" offset %u last %u\n",fp->offset,
  540.             fp->last) == EOF)
  541.                 break;
  542.         }
  543.     }
  544.     return 0;
  545. }
  546.  
  547. /* Sort Route dump */
  548. static int
  549. doroutesort(argc,argv,p)
  550. int argc ;
  551. char *argv[] ;
  552. void *p;
  553. {
  554.     extern int Route_Sort;
  555.  
  556.     return setbool(&Route_Sort,"Route Sort flag",argc,argv);
  557. }
  558.