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

  1. /* Reverse Address Resolution Protocol (ARP) functions. Sits between IP and
  2.  * Level 2, mapping Level 2 addresses to IP.
  3.  */
  4. #include "global.h"
  5. #ifdef RARP
  6. #include "mbuf.h"
  7. #include "proc.h"
  8. #include "timer.h"
  9. #include "iface.h"
  10. #include "socket.h"
  11. #include "ax25.h"
  12. #include "arp.h"
  13. #include "netuser.h"
  14. #include "cmdparse.h"
  15. #include "pktdrvr.h"
  16.   
  17. struct arp_stat Rarp_stat;
  18. static int Rwaiting = 0;        /* Semaphore used when waiting for a reply */
  19. /* static void arp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target)); */
  20. static int dorarpquery __ARGS((int argc,char *argv[],void *p));
  21. static void rarpstat __ARGS((void));
  22. static void rarp_output __ARGS((struct iface *iface,int16 hardware,char *hwaddr,char *target));
  23.   
  24. static struct cmds Rarpcmds[] = {
  25.     "query", dorarpquery, 0, 3,
  26. #ifdef fixed
  27.     "rarp query <interface> <ether addr|callsign> [<ether addr|callsign>]",
  28. #else
  29.     "rarp query <interface> <callsign> [<callsign>]",
  30. #endif
  31.     NULLCHAR
  32. };
  33.   
  34. int
  35. dorarp(argc,argv,p)
  36. int argc;
  37. char *argv[];
  38. void *p;
  39. {
  40.     if(argc < 2){
  41.         rarpstat();
  42.         return 0;
  43.     }
  44.     return subcmd(Rarpcmds,argc,argv,p);
  45. }
  46.   
  47. static int
  48. dorarpquery(argc,argv,p)
  49. int argc;
  50. char *argv[];
  51. void *p;
  52. {
  53.     struct iface *ifp;
  54.     char hwaddr[MAXHWALEN], qhwaddr[MAXHWALEN];
  55.     int16 hardware, t;
  56.     static char *errmsg = "Illegal hardware address\n";
  57.     if((ifp = if_lookup(argv[1])) == NULLIF){
  58.         tprintf(Badinterface,argv[1]);
  59.         return -1;
  60.     }
  61.     switch(ifp->iftype->type) {
  62.         case CL_AX25:
  63.             hardware = ARP_AX25;
  64.             break;
  65. #ifdef fixed
  66.         case CL_ETHERNET:
  67.             hardware = ARP_ETHER;
  68.             break;
  69.         default:
  70.             tputs("Only Ethernet and AX25 interfaces allowed\n");
  71. #else
  72.         default:
  73.             tputs("Only AX25 interfaces allowed\n");
  74. #endif
  75.             return -1;
  76.     }
  77.     if((*ifp->iftype->scan)(hwaddr,argv[2]) == -1) {
  78.         tputs(errmsg);
  79.         return -1;
  80.     }
  81.     if(argc > 3 && (*ifp->iftype->scan)(qhwaddr,argv[3]) == -1) {
  82.         tputs(errmsg);
  83.         return -1;
  84.     }
  85.     if(argc == 3)
  86.         memcpy(qhwaddr,hwaddr,ifp->iftype->hwalen);
  87.     rarp_output(ifp,hardware,hwaddr,qhwaddr);
  88.   
  89.     t = Arp_type[hardware].pendtime;
  90.     ++Rwaiting;
  91.     tprintf("Trying...   %2d",t);
  92.     while(t--) {
  93.         alarm(1000L);
  94.         if(pwait(&Rwaiting) != EALARM) {
  95.             alarm(0);
  96.             --Rwaiting;
  97.             return 0;
  98.         }
  99.         tprintf("\b\b%2d",t);
  100.     }
  101.     tputs("\b\bTimeout.\n");
  102.     --Rwaiting;
  103.     return 0;
  104. }
  105.   
  106. /* Handle incoming RARP packets according to RFC 903.
  107.  */
  108. void
  109. rarp_input(iface,bp)
  110. struct iface *iface;
  111. struct mbuf *bp;
  112. {
  113.     struct arp rarp;
  114.     struct arp_type *at;
  115.     char shwaddr[MAXHWALEN];
  116.   
  117.     Rarp_stat.recv++;
  118.     if(ntoharp(&rarp,&bp) == -1)    /* Convert into host format */
  119.         return;
  120.     if(rarp.hardware >= NHWTYPES){
  121.         /* Unknown hardware type, ignore */
  122.         Rarp_stat.badtype++;
  123.         return;
  124.     }
  125.     at = &Arp_type[rarp.hardware];
  126.     if(rarp.protocol != at->iptype){
  127.         /* Unsupported protocol type, ignore */
  128.         Rarp_stat.badtype++;
  129.         return;
  130.     }
  131.     if((int16)uchar(rarp.hwalen) > MAXHWALEN || uchar(rarp.pralen) != sizeof(int32)){
  132.         /* Incorrect protocol addr length (different hw addr lengths
  133.          * are OK since AX.25 addresses can be of variable length)
  134.          */
  135.         Rarp_stat.badlen++;
  136.         return;
  137.     }
  138.     if(memcmp(rarp.shwaddr,at->bdcst,at->hwalen) == 0){
  139.         /* This guy is trying to say he's got the broadcast address! */
  140.         Rarp_stat.badaddr++;
  141.         return;
  142.     }
  143.     if(rarp.opcode == REVARP_REQUEST) {
  144.         /* We are not a server, so we can only answer requests for a
  145.          * hardware address that is our own. But would be possible to
  146.          * use the ARP table to answer requests for someone elses
  147.          * IP address.
  148.          */
  149.         if(memcmp(rarp.thwaddr,iface->hwaddr,at->hwalen) == 0) {
  150.             memcpy(shwaddr,rarp.shwaddr,at->hwalen);
  151.             /* Mark the end of the sender's AX.25 address
  152.              * in case he didn't
  153.              */
  154.             if(rarp.hardware == ARP_AX25)
  155.                 rarp.thwaddr[uchar(rarp.hwalen)-1] |= E;
  156.             memcpy(rarp.shwaddr,iface->hwaddr,at->hwalen);
  157.             rarp.sprotaddr = iface->addr;
  158.             rarp.tprotaddr = iface->addr;
  159.             rarp.opcode = REVARP_REPLY;
  160.   
  161.             if((bp = htonarp(&rarp)) == NULLBUF)
  162.                 return;
  163.   
  164.             if(iface->forw != NULLIF)
  165.                 (*iface->forw->output)(iface->forw,shwaddr,
  166.                 iface->forw->hwaddr,at->rarptype,bp);
  167.             else
  168.                 (*iface->output)(iface,shwaddr,
  169.                 iface->hwaddr,at->rarptype,bp);
  170.             Rarp_stat.inreq++;
  171.         }
  172.     } else {
  173.         Rarp_stat.replies++;
  174.         if(Rwaiting) {
  175.             psignal(&Rwaiting,1);
  176.             tprintf("\nRARP Reply: %s %s\n",
  177.             (*at->format)(shwaddr,rarp.thwaddr),
  178.             inet_ntoa(rarp.tprotaddr));
  179.         }
  180.     }
  181. }
  182.   
  183. /* Send a RARP request to target to resolve hardware address hwaddr */
  184. static void
  185. rarp_output(iface,hardware,hwaddr,target)
  186. struct iface *iface;
  187. int16 hardware;
  188. char *hwaddr;
  189. char *target;
  190. {
  191.     struct arp rarp;
  192.     struct mbuf *bp;
  193.     struct arp_type *at;
  194.   
  195.     at = &Arp_type[hardware];
  196.     if(iface->output == NULLFP)
  197.         return;
  198.   
  199.     rarp.hardware = hardware;
  200.     rarp.protocol = at->iptype;
  201.     rarp.hwalen = at->hwalen;
  202.     rarp.pralen = sizeof(int32);
  203.     rarp.opcode = REVARP_REQUEST;
  204.     memcpy(rarp.shwaddr,iface->hwaddr,at->hwalen);
  205.     rarp.sprotaddr = 0;
  206.     memcpy(rarp.thwaddr,hwaddr,at->hwalen);
  207.     rarp.tprotaddr = 0;
  208.     if((bp = htonarp(&rarp)) == NULLBUF)
  209.         return;
  210.     (*iface->output)(iface,target,
  211.     iface->hwaddr,at->rarptype,bp);
  212.     Rarp_stat.outreq++;
  213. }
  214.   
  215. static void
  216. rarpstat()
  217. {
  218.     tprintf("received %u badtype %u bogus addr %u reqst in %u replies %u reqst out %u\n",
  219.     Rarp_stat.recv,Rarp_stat.badtype,Rarp_stat.badaddr,Rarp_stat.inreq,
  220.     Rarp_stat.replies,Rarp_stat.outreq);
  221. }
  222. #endif /* RARP */
  223.   
  224.