home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / packet / n17jsrc / ipcmd.c < prev    next >
C/C++ Source or Header  |  1991-08-08  |  8KB  |  362 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. static int doadd __ARGS((int argc,char *argv[],void *p));
  21. static int dodrop __ARGS((int argc,char *argv[],void *p));
  22. static int doflush __ARGS((int argc,char *argv[],void *p));
  23. static int doipaddr __ARGS((int argc,char *argv[],void *p));
  24. static int doipstat __ARGS((int argc,char *argv[],void *p));
  25. static int dolook __ARGS((int argc,char *argv[],void *p));
  26. static int dortimer __ARGS((int argc,char *argv[],void *p));
  27. static int dottl __ARGS((int argc,char *argv[],void *p));
  28. static int dumproute __ARGS((struct route *rp));
  29.  
  30. static struct cmds Ipcmds[] = {
  31.     "address",    doipaddr,    0,    0, NULLCHAR,
  32.     "rtimer",    dortimer,    0,    0, NULLCHAR,
  33.     "status",    doipstat,    0,    0, NULLCHAR,
  34.     "ttl",        dottl,        0,    0, NULLCHAR,
  35.     NULLCHAR,
  36. };
  37. /* "route" subcommands */
  38. static struct cmds Rtcmds[] = {
  39.     "add",        doadd,        0,    3,
  40.     "route add <dest addr>[/<bits>] <if name> [<gateway> | direct [metric]]",
  41.  
  42.     "addprivate",    doadd,        0,    3,
  43.     "route addprivate <dest addr>[/<bits>] <if name> [<gateway> | direct [metric]]",
  44.  
  45.     "drop",        dodrop,        0,    2,
  46.     "route drop <dest addr>[/<bits>]",
  47.  
  48.     "flush",    doflush,    0,    0,
  49.     NULLCHAR,
  50.  
  51.     "lookup",    dolook,        0,    2,
  52.     "route lookup <dest addr>",
  53.  
  54.     NULLCHAR,
  55. };
  56.  
  57. int
  58. doip(argc,argv,p)
  59. int argc;
  60. char *argv[];
  61. void *p;
  62. {
  63.     return subcmd(Ipcmds,argc,argv,p);
  64. }
  65. static int
  66. doipaddr(argc,argv,p)
  67. int argc;
  68. char *argv[];
  69. void *p;
  70. {
  71.     int32 n;
  72.  
  73.     if(argc < 2) {
  74.         tprintf("%s\n",inet_ntoa(Ip_addr));
  75.     } else if((n = resolve(argv[1])) == 0){
  76.         tprintf(Badhost,argv[1]);
  77.         return 1;
  78.     } else
  79.         Ip_addr = n;
  80.     return 0;
  81. }
  82. static int
  83. dortimer(argc,argv,p)
  84. int argc;
  85. char *argv[];
  86. void *p;
  87. {
  88.     return setlong(&ipReasmTimeout,"IP reasm timeout (sec)",argc,argv);
  89. }
  90. static int
  91. dottl(argc,argv,p)
  92. int argc;
  93. char *argv[];
  94. void *p;
  95. {
  96.     return setlong(&ipDefaultTTL,"IP Time-to-live",argc,argv);
  97. }
  98.  
  99.  
  100. /* Display and/or manipulate routing table */
  101. int
  102. doroute(argc,argv,p)
  103. int argc;
  104. char *argv[];
  105. void *p;
  106. {
  107.     register int i,bits;
  108.     register struct route *rp;
  109.  
  110.     if(argc >= 2)
  111.         return subcmd(Rtcmds,argc,argv,p);
  112.  
  113.     /* Dump IP routing table
  114.      * Dest            Len Interface    Gateway          Use
  115.      * 192.001.002.003 32  sl0          192.002.003.004  0
  116.      */
  117.     Current->flowmode = 1;        /* start *more* processing */
  118.     tprintf(
  119. "Dest            Len Interface    Gateway          Metric  P Timer  Use\n");
  120.  
  121.     for(bits=31;bits>=0;bits--){
  122.         for(i=0;i<HASHMOD;i++){
  123.             for(rp = Routes[bits][i];rp != NULLROUTE;rp = rp->next){
  124.                 if(dumproute(rp) == EOF){
  125.                     Current->flowmode = 0;
  126.                     return 0;
  127.                 }
  128.             }
  129.         }
  130.     }
  131.     if(R_default.iface != NULLIF)
  132.         dumproute(&R_default);
  133.     Current->flowmode = 0;
  134.  
  135.     return 0;
  136. }
  137. /* Add an entry to the routing table
  138.  * E.g., "add 1.2.3.4 ax0 5.6.7.8 3"
  139.  */
  140. static int
  141. doadd(argc,argv,p)
  142. int argc;
  143. char *argv[];
  144. void *p;
  145. {
  146.     struct iface *ifp;
  147.     int32 dest,gateway;
  148.     unsigned bits;
  149.     char *bitp;
  150.     int32 metric;
  151.     char private;
  152.  
  153.     if(strncmp(argv[0],"addp",4) == 0)
  154.         private = 1;
  155.     else
  156.         private = 0;
  157.     if(strcmp(argv[1],"default") == 0){
  158.         dest = 0L;
  159.         bits = 0;
  160.     } else {
  161.         /* If IP address is followed by an optional slash and
  162.          * a length field, (e.g., 128.96/16) get it;
  163.          * otherwise assume a full 32-bit address
  164.          */
  165.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  166.             /* Terminate address token for resolve() call */
  167.             *bitp++ = '\0';
  168.             bits = atoi(bitp);
  169.         } else
  170.             bits = 32;
  171.  
  172.         if((dest = resolve(argv[1])) == 0){
  173.             tprintf(Badhost,argv[1]);
  174.             return 1;
  175.         }
  176.     }
  177.     if((ifp = if_lookup(argv[2])) == NULLIF){
  178.         tprintf("Interface \"%s\" unknown\n",argv[2]);
  179.         return 1;
  180.     }
  181.  
  182.     metric = 1;
  183.  
  184.     if(argc > 3){
  185.         /* Next "trick is needed to set the metric on subnets
  186.          * higher as the default 1 for rspf.
  187.          * route add subnet/bits iface default 10  
  188.          */
  189.         if(strcmp(argv[3],"direct") == 0){    /* N1BEE */
  190.              gateway = 0;
  191.         /* calculate a nice metric based on subnet mask size */
  192.             if(bits != 0 && bits < 32)
  193.                 metric = (39 - bits) * 5 / 17;
  194.         } else {
  195.             if((gateway = resolve(argv[3])) == 0){
  196.                 tprintf(Badhost,argv[3]);
  197.                 return 1;
  198.             }
  199.         }
  200.     } else {
  201.         gateway = 0;
  202.     }
  203.     if (argc > 4)
  204.         metric = atol(argv[4]);
  205.  
  206.     if(rt_add(dest,bits,gateway,ifp,metric,0,private) == NULLROUTE)
  207.         tprintf("Can't add route\n");
  208. #ifdef    RSPF
  209.     if(!private)
  210.         rspfrouteupcall(dest,bits,gateway);    /* Do an RSPF upcall */
  211. #endif    /* RSPF */
  212.     return 0;
  213. }
  214. /* Drop an entry from the routing table
  215.  * E.g., "drop 128.96/16
  216.  */
  217. static int
  218. dodrop(argc,argv,p)
  219. int argc;
  220. char *argv[];
  221. void *p;
  222. {
  223.     char *bitp;
  224.     unsigned bits;
  225.     int32 n;
  226.  
  227.     if(strcmp(argv[1],"default") == 0){
  228.         n = 0L;
  229.         bits = 0;
  230.     } else {
  231.         /* If IP address is followed by an optional slash and length field,
  232.          * (e.g., 128.96/16) get it; otherwise assume a full 32-bit address
  233.          */
  234.         if((bitp = strchr(argv[1],'/')) != NULLCHAR){
  235.             /* Terminate address token for resolve() call */
  236.             *bitp++ = '\0';
  237.             bits = atoi(bitp);
  238.         } else
  239.             bits = 32;
  240.  
  241.         if((n = resolve(argv[1])) == 0){
  242.             tprintf(Badhost,argv[1]);
  243.             return 1;
  244.         }
  245.     }
  246.     return rt_drop(n,bits);
  247. }
  248. /* Force a timeout on all temporary routes */
  249. static int
  250. doflush(argc,argv,p)
  251. int argc;
  252. char *argv[];
  253. void *p;
  254. {
  255.     register struct route *rp;
  256.     struct route *rptmp;
  257.     int i,j;
  258.     
  259.     if(R_default.timer.state == TIMER_RUN){
  260.         rt_drop(0,0);    /* Drop default route */
  261.     }
  262.     for(i=0;i<HASHMOD;i++){
  263.         for(j=0;j<32;j++){
  264.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  265.                 rptmp = rp->next;
  266.                 if(rp->timer.state == TIMER_RUN){
  267.                     rt_drop(rp->target,rp->bits);
  268.                 }
  269.             }
  270.         }
  271.     }
  272.     return 0;
  273. }
  274. /* Dump a routing table entry */
  275. static int
  276. dumproute(rp)
  277. register struct route *rp;
  278. {
  279.     char *cp;
  280.  
  281.     if(rp->target != 0)
  282.         cp = inet_ntoa(rp->target);
  283.     else
  284.         cp = "default";
  285.     tprintf("%-16s",cp);
  286.     tprintf("%-4u",rp->bits);
  287.     tprintf("%-13s",rp->iface->name);
  288.     if(rp->gateway != 0)
  289.         cp = inet_ntoa(rp->gateway);
  290.     else
  291.         cp = "";
  292.     tprintf("%-17s",cp);
  293.     tprintf("%-8lu",rp->metric);
  294.     tprintf("%c ",(rp->flags & RTPRIVATE) ? 'P' : ' ');
  295.     if(rp->timer.state == TIMER_STOP){
  296.         if(rp->timer.duration == 1)tprintf("rspf   ");
  297.         else tprintf("man    ");
  298.     } else tprintf("%-7lu",read_timer(&rp->timer) / 1000L);
  299.     return tprintf("%lu\n",rp->uses);
  300. }
  301.  
  302. static int
  303. dolook(argc,argv,p)
  304. int argc;
  305. char *argv[];
  306. void *p;
  307. {
  308.     struct route *rp;
  309.     int32 addr;
  310.  
  311.     addr = resolve(argv[1]);
  312.     if(addr == 0){
  313.         tprintf("Host %s unknown\n",argv[1]);
  314.         return 1;
  315.     }
  316.     if((rp = rt_lookup(addr)) == NULLROUTE){
  317.         tprintf("Host %s (%s) unreachable\n",argv[1],inet_ntoa(addr));
  318.         return 1;
  319.     }
  320.     dumproute(rp);
  321.     return 0;
  322. }
  323.  
  324. static int
  325. doipstat(argc,argv,p)
  326. int argc;
  327. char *argv[];
  328. void *p;
  329. {
  330.     register struct reasm *rp;
  331.     register struct frag *fp;
  332.     int i;
  333.  
  334.     for(i=1;i<=NUMIPMIB;i++){
  335.         tprintf("(%2u)%-20s%10lu",i,
  336.          Ip_mib[i].name,Ip_mib[i].value.integer);
  337.         if(i % 2)
  338.             tprintf("     ");
  339.         else
  340.             tprintf("\n");
  341.     }
  342.     if((i % 2) == 0)
  343.         tprintf("\n");
  344.  
  345.     if(Reasmq != NULLREASM)
  346.         tprintf("Reassembly fragments:\n");
  347.     for(rp = Reasmq;rp != NULLREASM;rp = rp->next){
  348.         tprintf("src %s",inet_ntoa(rp->source));
  349.         tprintf(" dest %s",inet_ntoa(rp->dest));
  350.         if(tprintf(" id %u pctl %u time %lu len %u\n",
  351.          rp->id,uchar(rp->protocol),read_timer(&rp->timer),
  352.          rp->length) == EOF)
  353.             break;
  354.         for(fp = rp->fraglist;fp != NULLFRAG;fp = fp->next){
  355.             if(tprintf(" offset %u last %u\n",fp->offset,
  356.             fp->last) == EOF)
  357.                 break;
  358.         }
  359.     }
  360.     return 0;
  361. }
  362.