home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / misc / 9q920411 / arpcmd.c < prev    next >
C/C++ Source or Header  |  1991-03-08  |  5KB  |  235 lines

  1. /* ARP commands
  2.  * Copyright 1991, Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include <ctype.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "timer.h"
  9. #include "enet.h"
  10. #include "ax25.h"
  11. #include "arp.h"
  12. #include "netuser.h"
  13. #include "cmdparse.h"
  14. #include "commands.h"
  15.  
  16. static int doarpadd __ARGS((int argc,char *argv[],void *p));
  17. static int doarpdrop __ARGS((int argc,char *argv[],void *p));
  18. static int doarpflush __ARGS((int argc,char *argv[],void *p));
  19. static void dumparp __ARGS((void));
  20.  
  21. static struct cmds Arpcmds[] = {
  22.     "add", doarpadd, 0, 4,
  23.     "arp add <hostid> ether|ax25|netrom|arcnet <ether addr|callsign>",
  24.  
  25.     "drop", doarpdrop, 0, 3,
  26.     "arp drop <hostid> ether|ax25|netrom|arcnet",
  27.  
  28.     "flush", doarpflush, 0, 0,
  29.     NULLCHAR,
  30.  
  31.     "publish", doarpadd, 0, 4,
  32.     "arp publish <hostid> ether|ax25|netrom|arcnet <ether addr|callsign>",
  33.  
  34.     NULLCHAR,
  35. };
  36. char *Arptypes[] = {
  37.     "NET/ROM",
  38.     "10 Mb Ethernet",
  39.     "3 Mb Ethernet",
  40.     "AX.25",
  41.     "Pronet",
  42.     "Chaos",
  43.     "",
  44.     "Arcnet",
  45.     "Appletalk"
  46. };
  47.  
  48. int
  49. doarp(argc,argv,p)
  50. int argc;
  51. char *argv[];
  52. void *p;
  53. {
  54.     if(argc < 2){
  55.         dumparp();
  56.         return 0;
  57.     }
  58.     return subcmd(Arpcmds,argc,argv,p);
  59. }
  60. static
  61. doarpadd(argc,argv,p)
  62. int argc;
  63. char *argv[];
  64. void *p;
  65. {
  66.     int16 hardware;
  67.     int32 addr;
  68.     char *hwaddr;
  69.     struct arp_tab *ap;
  70.     struct arp_type *at;
  71.     int pub = 0;
  72.  
  73.     if(argv[0][0] == 'p')    /* Is this entry published? */
  74.         pub = 1;
  75.     if((addr = resolve(argv[1])) == 0){
  76.         tprintf(Badhost,argv[1]);
  77.         return 1;
  78.     }
  79.     /* This is a kludge. It really ought to be table driven */
  80.     switch(tolower(argv[2][0])){
  81.     case 'n':    /* Net/Rom pseudo-type */
  82.         hardware = ARP_NETROM;
  83.         break;
  84.     case 'e':    /* "ether" */
  85.         hardware = ARP_ETHER;
  86.         break;        
  87.     case 'a':    /* "ax25" */
  88.         switch(tolower(argv[2][1])) {
  89.         case 'x':
  90.             hardware = ARP_AX25;
  91.             break;
  92.         case 'r':
  93.             hardware = ARP_ARCNET;
  94.             break;
  95.         default:
  96.             tprintf("unknown hardware type \"%s\"\n",argv[2]);
  97.             return -1;
  98.         }
  99.         break;
  100.     case 'm':    /* "mac appletalk" */
  101.         hardware = ARP_APPLETALK;
  102.         break;
  103.     default:
  104.         tprintf("unknown hardware type \"%s\"\n",argv[2]);
  105.         return -1;
  106.     }
  107.     /* If an entry already exists, clear it */
  108.     if((ap = arp_lookup(hardware,addr)) != NULLARP)
  109.         arp_drop(ap);
  110.  
  111.     at = &Arp_type[hardware];
  112.     if(at->scan == NULLFP){
  113.         tprintf("Attach device first\n");
  114.         return 1;
  115.     }
  116.     /* Allocate buffer for hardware address and fill with remaining args */
  117.     hwaddr = mallocw(at->hwalen);
  118.     /* Destination address */
  119.     (*at->scan)(hwaddr,argv[3]);
  120.     ap = arp_add(addr,hardware,hwaddr,pub);    /* Put in table */
  121.     free(hwaddr);                /* Clean up */
  122.     stop_timer(&ap->timer);            /* Make entry permanent */
  123.     set_timer(&ap->timer,0L);
  124.     return 0;
  125. }
  126. /* Remove an ARP entry */
  127. static
  128. doarpdrop(argc,argv,p)
  129. int argc;
  130. char *argv[];
  131. void *p;
  132. {
  133.     int16 hardware;
  134.     int32 addr;
  135.     struct arp_tab *ap;
  136.  
  137.     if((addr = resolve(argv[1])) == 0){
  138.         tprintf(Badhost,argv[1]);
  139.         return 1;
  140.     }
  141.     /* This is a kludge. It really ought to be table driven */
  142.     switch(tolower(argv[2][0])){
  143.     case 'n':
  144.         hardware = ARP_NETROM;
  145.         break;
  146.     case 'e':    /* "ether" */
  147.         hardware = ARP_ETHER;
  148.         break;        
  149.     case 'a':    /* "ax25" */
  150.         switch(tolower(argv[2][1])) {
  151.         case 'x':
  152.             hardware = ARP_AX25;
  153.             break;
  154.         case 'r':
  155.             hardware = ARP_ARCNET;
  156.             break;
  157.         default:
  158.             hardware = 0;
  159.             break;
  160.         }
  161.         break;
  162.     case 'm':    /* "mac appletalk" */
  163.         hardware = ARP_APPLETALK;
  164.         break;
  165.     default:
  166.         hardware = 0;
  167.         break;
  168.     }
  169.     if((ap = arp_lookup(hardware,addr)) == NULLARP)
  170.         return -1;
  171.     arp_drop(ap);
  172.     return 0;    
  173. }
  174. /* Flush all automatic entries in the arp cache */
  175. static int
  176. doarpflush(argc,argv,p)
  177. int argc;
  178. char *argv[];
  179. void *p;
  180. {
  181.     register struct arp_tab *ap;
  182.     struct arp_tab *aptmp;
  183.     int i;
  184.  
  185.     for(i=0;i<HASHMOD;i++){
  186.         for(ap = Arp_tab[i];ap != NULLARP;ap = aptmp){
  187.             aptmp = ap->next;
  188.             if(dur_timer(&ap->timer) != 0)
  189.                 arp_drop(ap);
  190.         }
  191.     }
  192.     return 0;
  193. }
  194.  
  195. /* Dump ARP table */
  196. static void
  197. dumparp()
  198. {
  199.     register int i;
  200.     register struct arp_tab *ap;
  201.     char e[128];
  202.  
  203.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  204.      Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq,
  205.      Arp_stat.replies,Arp_stat.outreq);
  206.  
  207.     tprintf("IP addr         Type           Time Q Addr\n");
  208.     for(i=0;i<HASHMOD;i++){
  209.         for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next){
  210.             tprintf("%-16s",inet_ntoa(ap->ip_addr));
  211.             tprintf("%-15s",smsg(Arptypes,NHWTYPES,ap->hardware));
  212.             tprintf("%-5ld",read_timer(&ap->timer)/1000L);
  213.             if(ap->state == ARP_PENDING)
  214.                 tprintf("%-2u",len_q(ap->pending));
  215.             else
  216.                 tprintf("  ");
  217.             if(ap->state == ARP_VALID){
  218.                 if(Arp_type[ap->hardware].format != NULL){
  219.                     (*Arp_type[ap->hardware].format)(e,ap->hw_addr);
  220.                 } else {
  221.                     e[0] = '\0';
  222.                 }
  223.                 tprintf("%s",e);
  224.             } else {
  225.                 tprintf("[unknown]");
  226.             }
  227.             if(ap->pub)
  228.                 tprintf(" (published)");
  229.             if(tprintf("\n") == EOF)
  230.                 return;
  231.         }
  232.     }
  233.     return;
  234. }
  235.