home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / MSDOS / KA9Q / MSWIN / DSP2D_UP.ZIP / IPCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-20  |  12.7 KB  |  565 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. extern int Route_Sort=1;
  21.  
  22. int32 Ip_addr;
  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. /* Display and/or manipulate routing table */
  252. int
  253. doroute(argc,argv,p)
  254. int argc;
  255. char *argv[];
  256. void *p;
  257. {
  258.     register int i,j,k,l,m,bits,numflg,flow_tmp;
  259.     register struct route *rp;
  260.     char *temp,temp2[80];
  261.  
  262.     if(argc >= 2)
  263.         return subcmd(Rtcmds,argc,argv,p);
  264.  
  265.     /* Dump IP routing table
  266.      * Dest            Len Interface    Gateway          Use
  267.      * 192.001.002.003 32  sl0          192.002.003.004  0
  268.      * modified for Sorted output - D. Crompton 2.92
  269.      */
  270.       
  271.     flow_tmp=Current->flowmode;
  272.     Current->flowmode=1;
  273.     
  274.     tprintf(
  275. "  Destination    Len Interface    Gateway          Metric  P Timer  Use\n");
  276.  
  277.  
  278.     for(j=0,bits=31;bits>=0;bits--)
  279.        for(i=0;i<HASHMOD;i++)
  280.           for(rp = Routes[bits][i];rp != NULLROUTE;j++,rp = rp->next);
  281.  
  282.     if (j){
  283.     
  284.       temp=mallocw(j*80);
  285.  
  286.       for(bits=31,k=0;bits>=0;bits--)
  287.         for(i=0;i<HASHMOD;i++)
  288.             for(rp = Routes[bits][i];rp != NULLROUTE;rp = rp->next,k+=80)
  289.                 dumproute(rp,&temp[k]);
  290.       
  291.       if (Route_Sort) qsort(temp,(size_t)j,80,strcmp);              
  292.     
  293.       for (i=0,k=4;i<j;i++,k+=80) {
  294.           tprintf("%s",&temp[k]);
  295.           if (tprintf("\n") == EOF)
  296.              {
  297.               Current->flowmode=flow_tmp;
  298.               free(temp);
  299.               return 0;
  300.              }
  301.       }
  302.       if(R_default.iface != NULLIF){
  303.         dumproute(&R_default,temp);
  304.         tprintf("%s\n",temp);
  305.       }
  306.      free(temp);
  307.     }
  308.     Current->flowmode = flow_tmp;
  309.     return 0;
  310. }
  311.  
  312. /* Dump a routing table entry */
  313. static void
  314. dumproute(rp,temp)
  315. register struct route *rp;
  316. char *temp;
  317. {
  318.     char *cp;
  319.     unsigned a=0;        
  320.                   
  321.  
  322.     if(rp->target != 0) {
  323.         cp = inet_ntobos(rp->target);
  324.         a=sprintf(temp,"%4s",cp);
  325.         cp = inet_ntoa(rp->target);
  326.     
  327.     } else {
  328.         cp = "default";
  329.     }
  330.     a+=sprintf(&temp[a],"%-17s",cp);
  331.     a+=sprintf(&temp[a],"%-4u",rp->bits);
  332.     a+=sprintf(&temp[a],"%-13s",rp->iface->name);
  333.     if(rp->gateway != 0)
  334.         cp = inet_ntoa(rp->gateway);
  335.     else
  336.         cp = "";
  337.     a+=sprintf(&temp[a],"%-17s",cp);
  338.     a+=sprintf(&temp[a],"%-8lu",rp->metric);
  339.     a+=sprintf(&temp[a],"%c ",(rp->flags & RTPRIVATE) ? 'P' : ' ');
  340.     if(rp->timer.state == TIMER_STOP){
  341.         if(rp->timer.duration == 1) a+=sprintf(&temp[a],"rspf   ");
  342.         else a+=sprintf(&temp[a],"man    ");
  343.     } else {
  344.         a+=sprintf(&temp[a],"%-7lu",read_timer(&rp->timer) / 1000L);
  345.     }
  346.     sprintf(&temp[a],"%lu",rp->uses);
  347. }
  348.  
  349.  
  350. /* Sort Route dump */
  351. static int
  352. doroutesort(argc,argv,p)
  353. int argc ;
  354. char *argv[] ;
  355. void *p;
  356. {
  357.     extern int Route_Sort;
  358.  
  359.     return setbool(&Route_Sort,"Route Sort flag",argc,argv);
  360. }
  361.  
  362.  
  363. /* Add an entry to the routing table
  364.  * E.g., "add 1.2.3.4 ax0 5.6.7.8 3"
  365.  */
  366. static int
  367. doadd(argc,argv,p)
  368. int argc;
  369. char *argv[];
  370. void *p;
  371. {
  372.     struct iface *ifp;
  373.     int32 dest,gateway;
  374.     unsigned bits;
  375.     char *bitp;
  376.     int32 metric;
  377.     char private;
  378.  
  379.     if(strncmp(argv[0],"addp",4) == 0)
  380.         private = 1;
  381.     else
  382.         private = 0;
  383.     if(strcmp(argv[1],"default") == 0){
  384.         dest = 0L;
  385.         bits = 0;
  386.     } else {
  387.         /* If IP address is followed by an optional slash and
  388.          * a length field, (e.g., 128.96/16) get it;
  389.          * otherwise assume a full 32-bit address
  390.          */
  391.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  392.             /* Terminate address token for resolve() call */
  393.             *bitp++ = '\0';
  394.             bits = atoi(bitp);
  395.         } else
  396.             bits = 32;
  397.  
  398.         if((dest = resolve(argv[1])) == 0){
  399.             tprintf(Badhost,argv[1]);
  400.             return 1;
  401.         }
  402.     }
  403.     if((ifp = if_lookup(argv[2])) == NULLIF){
  404.         tprintf("Interface \"%s\" unknown\n",argv[2]);
  405.         return 1;
  406.     }
  407.  
  408.     metric = 1;
  409.  
  410.     if(argc > 3){
  411.         /* Next "trick is needed to set the metric on subnets
  412.          * higher as the default 1 for rspf.
  413.          * route add subnet/bits iface default 10  
  414.          */
  415.         if(strcmp(argv[3],"direct") == 0){      /* N1BEE */
  416.             gateway = 0;
  417.         /* calculate a nice metric based on subnet mask size */
  418.             if(bits != 0 && bits < 32)
  419.                 metric = (39 - bits) * 5 / 17;
  420.         } else {
  421.             if((gateway = resolve(argv[3])) == 0){
  422.                 tprintf(Badhost,argv[3]);
  423.                 return 1;
  424.             }
  425.         }
  426.     } else {
  427.         gateway = 0;
  428.     }
  429.     if (argc > 4)
  430.         metric = atol(argv[4]);
  431.  
  432.     if(rt_add(dest,bits,gateway,ifp,metric,0,private) == NULLROUTE)
  433.         tprintf("Can't add route\n");
  434. #ifdef  RSPF
  435.     if(!private)
  436.         rspfrouteupcall(dest,bits,gateway);     /* Do an RSPF upcall */
  437. #endif  /* RSPF */
  438.     return 0;
  439. }
  440. /* Drop an entry from the routing table
  441.  * E.g., "drop 128.96/16
  442.  */
  443. static int
  444. dodrop(argc,argv,p)
  445. int argc;
  446. char *argv[];
  447. void *p;
  448. {
  449.     char *bitp;
  450.     unsigned bits;
  451.     int32 n;
  452.  
  453.     if(strcmp(argv[1],"default") == 0){
  454.         n = 0L;
  455.         bits = 0;
  456.     } else {
  457.         /* If IP address is followed by an optional slash and length field,
  458.          * (e.g., 128.96/16) get it; otherwise assume a full 32-bit address
  459.          */
  460.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  461.             /* Terminate address token for resolve() call */
  462.             *bitp++ = '\0';
  463.             bits = atoi(bitp);
  464.         } else
  465.             bits = 32;
  466.  
  467.         if((n = resolve(argv[1])) == 0){
  468.             tprintf(Badhost,argv[1]);
  469.             return 1;
  470.         }
  471.     }
  472.     return rt_drop(n,bits);
  473. }
  474. /* Force a timeout on all temporary routes */
  475. static int
  476. doflush(argc,argv,p)
  477. int argc;
  478. char *argv[];
  479. void *p;
  480. {
  481.     register struct route *rp;
  482.     struct route *rptmp;
  483.     int i,j;
  484.     
  485.     if(R_default.timer.state == TIMER_RUN){
  486.         rt_drop(0,0);   /* Drop default route */
  487.     }
  488.     for(i=0;i<HASHMOD;i++){
  489.         for(j=0;j<32;j++){
  490.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  491.                 rptmp = rp->next;
  492.                 if(rp->timer.state == TIMER_RUN){
  493.                     rt_drop(rp->target,rp->bits);
  494.                 }
  495.             }
  496.         }
  497.     }
  498.     return 0;
  499. }
  500.  
  501. static int
  502. dolook(argc,argv,p)
  503. int argc;
  504. char *argv[];
  505. void *p;
  506. {
  507.     struct route *rp;
  508.     int32 addr;
  509.     char temp[80];
  510.  
  511.     addr = resolve(argv[1]);
  512.     if(addr == 0){
  513.         tprintf("Host %s unknown\n",argv[1]);
  514.         return 1;
  515.     }
  516.     if((rp = rt_lookup(addr)) == NULLROUTE){
  517.         tprintf("Host %s (%s) unreachable\n",argv[1],inet_ntoa(addr));
  518.         return 1;
  519.     }
  520.     
  521.     dumproute(rp,temp);
  522.     tprintf("%s\n",temp);
  523.     
  524.     return 0;
  525. }
  526.  
  527. static int
  528. doipstat(argc,argv,p)
  529. int argc;
  530. char *argv[];
  531. void *p;
  532. {
  533.     register struct reasm *rp;
  534.     register struct frag *fp;
  535.     int i;
  536.  
  537.     for(i=1;i<=NUMIPMIB;i++){
  538.         tprintf("(%2u)%-20s%10lu",i,
  539.          Ip_mib[i].name,Ip_mib[i].value.integer);
  540.         if(i % 2)
  541.             tprintf("     ");
  542.         else
  543.             tprintf("\n");
  544.     }
  545.     if((i % 2) == 0)
  546.         tprintf("\n");
  547.  
  548.     if(Reasmq != NULLREASM)
  549.         tprintf("Reassembly fragments:\n");
  550.     for(rp = Reasmq;rp != NULLREASM;rp = rp->next){
  551.         tprintf("src %s",inet_ntoa(rp->source));
  552.         tprintf(" dest %s",inet_ntoa(rp->dest));
  553.         if(tprintf(" id %u pctl %u time %lu len %u\n",
  554.          rp->id,uchar(rp->protocol),read_timer(&rp->timer),
  555.          rp->length) == EOF)
  556.             break;
  557.         for(fp = rp->fraglist;fp != NULLFRAG;fp = fp->next){
  558.             if(tprintf(" offset %u last %u\n",fp->offset,
  559.             fp->last) == EOF)
  560.                 break;
  561.         }
  562.     }
  563.     return 0;
  564. }
  565.