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

  1. /* ARP commands
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  *
  6.  * Mods by SM6RPZ
  7.  * 1992-05-28 - Added interface to "arp add ..."-command.
  8.  * 1992-07-26 - Small cosmetic changes here and there.
  9.  */
  10. #include <ctype.h>
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "timer.h"
  14. #include "internet.h"
  15. #include "ip.h"
  16. #include "enet.h"
  17. #include "ax25.h"
  18. #include "arp.h"
  19. #include "netuser.h"
  20. #include "cmdparse.h"
  21. #include "commands.h"
  22. #include "iface.h"
  23. #include "rspf.h"
  24. #include "socket.h"
  25. #include "domain.h"
  26. #include "session.h"
  27.   
  28. int Arp_Sort=1;  /* set Initial sort mode */
  29.   
  30. static int doarpsort __ARGS((int argc,char *argv[],void *p));
  31. static void make_arp_string __ARGS((struct arp_tab *ap,char *buf));
  32. static int doarpadd __ARGS((int argc,char *argv[],void *p));
  33. static int doarpdrop __ARGS((int argc,char *argv[],void *p));
  34. static int doarpflush __ARGS((int argc,char *argv[],void *p));
  35. static int doarppoll __ARGS((int argc,char *argv[],void *p));
  36. static int doarpeaves __ARGS((int argc,char *argv[],void *p));
  37. static int doarpqueue __ARGS((int argc,char *argv[],void *p));
  38. static void dumparp __ARGS((void));
  39.   
  40. static struct cmds DFAR Arpcmds[] = {
  41.     "add", doarpadd, 0, 4,
  42.     "arp add <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  43.   
  44.     "drop", doarpdrop, 0, 3,
  45.     "arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>",
  46.   
  47.     "eaves", doarpeaves, 0, 0, NULLCHAR,
  48.   
  49.     "flush", doarpflush, 0, 0,
  50.     NULLCHAR,
  51.   
  52.     "maxq", doarpqueue, 0, 0, NULLCHAR,
  53.   
  54.     "poll", doarppoll, 0, 0, NULLCHAR,
  55.   
  56.     "publish", doarpadd, 0, 4,
  57.     "arp publish <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>",
  58.   
  59.     "sort",    doarpsort, 0, 0,
  60.     NULLCHAR,
  61.   
  62.     NULLCHAR,
  63. };
  64.   
  65. char *Arptypes[] = {
  66.     "NET/ROM",
  67.     "10 Mb Ethernet",
  68.     "3 Mb Ethernet",
  69.     "AX.25",
  70.     "Pronet",
  71.     "Chaos",
  72.     "",
  73.     "Arcnet",
  74.     "Appletalk"
  75. };
  76.   
  77. int
  78. doarp(argc,argv,p)
  79. int argc;
  80. char *argv[];
  81. void *p;
  82. {
  83.     if(argc < 2){
  84.         dumparp();
  85.         return 0;
  86.     }
  87.     return subcmd(Arpcmds,argc,argv,p);
  88. }
  89.   
  90. static int
  91. doarpadd(argc,argv,p)
  92. int argc;
  93. char *argv[];
  94. void *p;
  95. {
  96.     int16 hardware;
  97.     int32 addr;
  98.     char *hwaddr;
  99.     struct arp_tab *ap;
  100.     struct arp_type *at;
  101.     int pub = 0;
  102.     struct iface *iface;
  103.   
  104.     if(argv[0][0] == 'p')   /* Is this entry published? */
  105.         pub = 1;
  106.     if((addr = resolve(argv[1])) == 0){
  107.         tprintf(Badhost,argv[1]);
  108.         return 1;
  109.     }
  110.     if(argc == 4 && tolower(argv[2][0]) != 'n') {
  111.         tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  112.         pub ? "publish" : "add");
  113.         return -1;
  114.     }
  115.     /* This is a kludge. It really ought to be table driven */
  116.     switch(tolower(argv[2][0])){
  117.         case 'n':       /* Net/Rom pseudo-type */
  118.             argc = 5;
  119.             argv[4] = "netrom";     /* Force use of netrom interface */
  120.             hardware = ARP_NETROM;
  121.             break;
  122.         case 'e':       /* "ether" */
  123.             hardware = ARP_ETHER;
  124.             break;
  125.         case 'a':       /* "ax25" */
  126.         switch(tolower(argv[2][1])) {
  127.             case 'x':
  128.                 hardware = ARP_AX25;
  129.                 break;
  130.             case 'r':
  131.                 hardware = ARP_ARCNET;
  132.                 break;
  133.             default:
  134.                 tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  135.                 pub ? "publish" : "add");
  136.                 return -1;
  137.         }
  138.             break;
  139.         case 'm':       /* "mac appletalk" */
  140.             hardware = ARP_APPLETALK;
  141.             break;
  142.         default:
  143.             tprintf("Usage: arp %s <hostid> ether|ax25|netrom|arcnet|mac <hardware addr> <iface>\n",
  144.             pub ? "publish" : "add");
  145.             return -1;
  146.     }
  147.     if((iface = if_lookup(argv[4])) == NULLIF) {
  148.         tprintf("No such interface %s\n", argv[4]);
  149.         return 1;
  150.     }
  151.     /* If an entry already exists, clear it */
  152.     if((ap = arp_lookup(hardware,addr,iface)) != NULLARP)
  153.         arp_drop(ap);
  154.   
  155.     at = &Arp_type[hardware];
  156.     if(at->scan == NULLFP){
  157.         tputs("Attach device first\n");
  158.         return 1;
  159.     }
  160.     /* Allocate buffer for hardware address and fill with remaining args */
  161.     hwaddr = mallocw(at->hwalen);
  162.     /* Destination address */
  163.     (*at->scan)(hwaddr,argv[3]);
  164.     ap = arp_add(addr,hardware,hwaddr,pub,iface);   /* Put in table */
  165.     free(hwaddr);                                   /* Clean up */
  166.     stop_timer(&ap->timer);                     /* Make entry permanent */
  167.     set_timer(&ap->timer,0L);
  168. #ifdef  RSPF
  169.     rspfarpupcall(addr,hardware,NULLIF);  /* Do a RSPF upcall */
  170. #endif  /* RSPF */
  171.     return 0;
  172. }
  173.   
  174. static int
  175. doarpeaves(argc,argv,p)
  176. int argc ;
  177. char *argv[] ;
  178. void *p;
  179. {
  180.     return setflag(argc,argv[1],ARP_EAVESDROP,argv[2]);
  181. }
  182.   
  183. static int
  184. doarppoll(argc,argv,p)
  185. int argc ;
  186. char *argv[] ;
  187. void *p;
  188. {
  189.     return setflag(argc,argv[1],ARP_KEEPALIVE,argv[2]);
  190. }
  191.   
  192. int Maxarpq = 5;
  193.   
  194. static int
  195. doarpqueue(argc,argv,p)
  196. int argc ;
  197. char *argv[] ;
  198. void *p;
  199. {
  200.     return setint(&Maxarpq,"Max queue",argc,argv);
  201. }
  202.   
  203.   
  204. /* Remove an ARP entry */
  205. static int
  206. doarpdrop(argc,argv,p)
  207. int argc;
  208. char *argv[];
  209. void *p;
  210. {
  211.     int16 hardware;
  212.     int32 addr;
  213.     struct arp_tab *ap;
  214.     struct iface *iface;
  215.   
  216.     if((addr = resolve(argv[1])) == 0){
  217.         tprintf(Badhost,argv[1]);
  218.         return 1;
  219.     }
  220.     if(argc == 3 && tolower(argv[2][0]) != 'n') {
  221.         tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  222.         return -1;
  223.     }
  224.     /* This is a kludge. It really ought to be table driven */
  225.     switch(tolower(argv[2][0])){
  226.         case 'n':
  227.             argc = 4;
  228.             argv[3] = "netrom";     /* Force use of netrom interface */
  229.             hardware = ARP_NETROM;
  230.             break;
  231.         case 'e':       /* "ether" */
  232.             hardware = ARP_ETHER;
  233.             break;
  234.         case 'a':       /* "ax25" */
  235.         switch(tolower(argv[2][1])) {
  236.             case 'x':
  237.                 hardware = ARP_AX25;
  238.                 break;
  239.             case 'r':
  240.                 hardware = ARP_ARCNET;
  241.                 break;
  242.             default:
  243.                 tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  244.                 return -1;
  245.         }
  246.             break;
  247.         case 'm':       /* "mac appletalk" */
  248.             hardware = ARP_APPLETALK;
  249.             break;
  250.         default:
  251.             tputs("Usage: arp drop <hostid> ether|ax25|netrom|arcnet|mac <iface>\n");
  252.             return -1;
  253.     }
  254.     if((iface = if_lookup(argv[3])) == NULLIF) {
  255.         tprintf("No such interface %s\n", argv[3]);
  256.         return 1;
  257.     }
  258.     if((ap = arp_lookup(hardware,addr,iface)) == NULLARP)
  259.         return -1;
  260.     arp_drop(ap);
  261.     return 0;
  262. }
  263.   
  264. /* Flush all automatic entries in the arp cache */
  265. static int
  266. doarpflush(argc,argv,p)
  267. int argc;
  268. char *argv[];
  269. void *p;
  270. {
  271.     register struct arp_tab *ap;
  272.     struct arp_tab *aptmp;
  273.     int i;
  274.   
  275.     for(i=0;i<HASHMOD;i++){
  276.         for(ap = Arp_tab[i];ap != NULLARP;ap = aptmp){
  277.             aptmp = ap->next;
  278.             if(dur_timer(&ap->timer) != 0)
  279.                 arp_drop(ap);
  280.         }
  281.     }
  282.     return 0;
  283. }
  284.   
  285. /* Dump ARP table */
  286. static void
  287. dumparp()
  288. {
  289.     register int i,j,k,flow_tmp;
  290.     register struct arp_tab *ap;
  291.     char *temp;
  292.   
  293.     flow_tmp=Current->flowmode;
  294.     Current->flowmode=1;
  295.   
  296.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  297.     Arp_stat.recv,Arp_stat.badtype,Arp_stat.badaddr,Arp_stat.inreq,
  298.     Arp_stat.replies,Arp_stat.outreq);
  299.   
  300.     for(i=0,j=0;i<HASHMOD;i++)
  301.         for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,j++);
  302.   
  303.     if (j) {
  304.   
  305.         tputs("IP addr         Type           Time Q Address           Interface\n");
  306.   
  307.         temp=mallocw(j*80);
  308.   
  309.         for(i=0,k=0;i<HASHMOD;i++) {
  310.             for(ap = Arp_tab[i];ap != (struct arp_tab *)NULL;ap = ap->next,k+=80)
  311.                 make_arp_string(ap,&temp[k]);
  312.         }
  313.   
  314. #ifdef LINUX
  315.         if (Arp_Sort) qsort(temp,(size_t)j,80,(int (*)__ARGS((void*,void*))) strcmp);
  316. #else
  317.         if (Arp_Sort) qsort(temp,(size_t)j,80,(int (*) ()) strcmp);
  318. #endif
  319.   
  320.         for(i=0,k=4;i<j;i++,k+=80) {
  321.             tputs(&temp[k]);
  322.             if(tputc('\n') == EOF)  break;
  323.         }
  324.         free(temp);
  325.     }
  326.   
  327.     Current->flowmode=flow_tmp;
  328. }
  329.   
  330. void
  331. make_arp_string(ap,buf)
  332. register struct arp_tab *ap;
  333. char *buf;
  334. {
  335.     char e[128];
  336.     unsigned a=0;
  337.     char *name;
  338.   
  339.     if(DTranslate && (name = resolve_a(ap->ip_addr,!DVerbose)) != NULLCHAR) {
  340.         strcpy(buf, name);
  341.         a+=4;
  342.         free(name);
  343.     } else {
  344.         a=sprintf(buf,"%4.4s",inet_ntobos(ap->ip_addr));
  345.     }
  346.   
  347.     a+=sprintf(&buf[a],"%-15.15s ",inet_ntoa(ap->ip_addr));
  348.     a+=sprintf(&buf[a],"%-14.14s ",smsg(Arptypes,NHWTYPES,ap->hardware));
  349.     a+=sprintf(&buf[a],"%4ld ",read_timer(&ap->timer)/1000L);
  350.   
  351.     if(ap->state == ARP_PENDING)
  352.         a+=sprintf(&buf[a],"%1.1u ",len_q(ap->pending));
  353.     else
  354.         a+=sprintf(&buf[a],"  ");
  355.   
  356.     if(ap->state == ARP_VALID){
  357.         if(Arp_type[ap->hardware].format != NULL){
  358.             (*Arp_type[ap->hardware].format)(e,ap->hw_addr);
  359.         } else {
  360.             e[0]='\0';
  361.         }
  362.         a+=sprintf(&buf[a],"%-17.17s ",e);
  363.     } else {
  364.         a+=sprintf(&buf[a],"[unknown]         ");
  365.     }
  366.   
  367.     if (ap->iface)
  368.         a+=sprintf(&buf[a],"%-6.6s ",ap->iface->name);
  369.   
  370.     if(ap->pub)
  371.         a+=sprintf(&buf[a],"(published)");
  372.   
  373.     return;
  374. }
  375.   
  376. /* Sort ARP dump */
  377. static int
  378. doarpsort(argc,argv,p)
  379. int argc ;
  380. char *argv[] ;
  381. void *p;
  382. {
  383.     extern int Arp_Sort;
  384.   
  385.     return setbool(&Arp_Sort,"ARP Sort flag",argc,argv);
  386. }
  387.   
  388.