home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / internet / netlite2 / DCI / c / ARP next >
Encoding:
Text File  |  1993-04-27  |  10.5 KB  |  365 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "kernel.h"
  5. #include "swis.h"
  6. #include "global.h"
  7.  
  8. struct arp arplist[MAXARP];
  9.  
  10. void Receive_ARP(int bcast, int portno, struct mbuf *mbuf)
  11. {
  12.         char *data;
  13.  
  14.         data = mbuf->m_next->m_dat + mbuf->m_next->m_off - MMINOFF;
  15.  
  16.         if (get16(data + 0)  == HARDWARE_ETHER &&
  17.             get16(data + 2)  == FRAME_IP &&
  18.             get32(data + 24) == port[portno].ipaddr)
  19.         {
  20.                 switch (get16(data + 6))
  21.                 {
  22.                         case ARP_REQUEST:
  23.                                 Receive_ARP_Request(portno, bcast, data);
  24.                                 break;
  25.                         case ARP_RESPONSE:
  26.                                 Receive_ARP_Response(portno, bcast, data);
  27.                                 break;
  28.                         default:
  29.                                 break;
  30.                 }
  31.         }
  32.  
  33.         free_rx_mbuf(mbuf);
  34. }
  35.  
  36. void Create_ARP_Request(int ipaddr, struct packet *packet)
  37. {
  38.        register struct arp *arp;
  39.        register int i;
  40.  
  41.        for (i = 0; i < MAXARP; i++)
  42.        {
  43.               if (arplist[i].ipaddr == ipaddr &&
  44.                   arplist[i].port   == packet->port &&
  45.                   arplist[i].status == ARP_RESOLVING)
  46.               {
  47.                       free_tx_mbuf(packet->data);
  48.                       free_packet(packet);
  49.                       Transmit_ARP_Request(arplist + i);
  50.                       return;
  51.               }
  52.        }
  53.  
  54.        arp = Free_ARP_Slot();
  55.  
  56.        arp->ipaddr = ipaddr;
  57.        arp->port   = packet->port;
  58.        arp->ttl    = TIMEOUT_RESOLVING;
  59.        arp->status = ARP_RESOLVING;
  60.        arp->packet = packet;
  61.  
  62.        Transmit_ARP_Request(arp);
  63. }
  64.  
  65. void Transmit_ARP_Request(struct arp *arp)
  66. {
  67.        struct packet *packet;
  68.        struct mbuf *mbuf;
  69.        int portno = arp->port;
  70.  
  71.        if ((mbuf = alloc_tx_mbuf(1)) == NULLMBUF)
  72.               return;
  73.  
  74.        if ((packet = alloc_packet()) == NULLPACKET)
  75.        {
  76.               memout++;
  77.               free_tx_mbuf(mbuf);
  78.               return;
  79.        }
  80.  
  81.        port[portno].arpreqtx++;
  82.  
  83.        mbuf->m_next  = NULLMBUF;
  84.        mbuf->m_off   = MMINOFF;
  85.        mbuf->m_len   = 28;
  86.        mbuf->m_indir = FALSE;
  87.        mbuf->m_type  = MT_DATA;
  88.  
  89.        put16(mbuf->m_dat + 0, HARDWARE_ETHER);
  90.        put16(mbuf->m_dat + 2, FRAME_IP);
  91.        mbuf->m_dat[4] = 6;
  92.        mbuf->m_dat[5] = 4;
  93.        put16(mbuf->m_dat + 6, ARP_REQUEST);
  94.  
  95.        /* Sender */
  96.        mbuf->m_dat[8]  = port[portno].hwaddr[0];
  97.        mbuf->m_dat[9]  = port[portno].hwaddr[1];
  98.        mbuf->m_dat[10] = port[portno].hwaddr[2];
  99.        mbuf->m_dat[11] = port[portno].hwaddr[3];
  100.        mbuf->m_dat[12] = port[portno].hwaddr[4];
  101.        mbuf->m_dat[13] = port[portno].hwaddr[5];
  102.        put32(mbuf->m_dat + 14, port[portno].ipaddr);
  103.  
  104.        /* Target */
  105.        mbuf->m_dat[18] = 0x00;
  106.        mbuf->m_dat[19] = 0x00;
  107.        mbuf->m_dat[20] = 0x00;
  108.        mbuf->m_dat[21] = 0x00;
  109.        mbuf->m_dat[22] = 0x00;
  110.        mbuf->m_dat[23] = 0x00;
  111.        put32(mbuf->m_dat + 24, arp->ipaddr);
  112.  
  113.        packet->next      = NULLPACKET;
  114.        packet->hwaddr[0] = bcast_hwaddr[0];
  115.        packet->hwaddr[1] = bcast_hwaddr[1];
  116.        packet->hwaddr[2] = bcast_hwaddr[2];
  117.        packet->hwaddr[3] = bcast_hwaddr[3];
  118.        packet->hwaddr[4] = bcast_hwaddr[4];
  119.        packet->hwaddr[5] = bcast_hwaddr[5];
  120.        packet->port      = portno;
  121.        packet->type      = FRAME_ARP;
  122.        packet->data      = mbuf;
  123.  
  124.        Queue_Transmit_Packet(packet);
  125. }
  126.  
  127. void Receive_ARP_Request(int portno, int bcast, char *data)
  128. {
  129.        struct packet *packet;
  130.        struct arp *arp;
  131.        struct mbuf *mbuf;
  132.        int ipaddr;
  133.  
  134.        port[portno].arpreqrx++;
  135.  
  136.        if ((mbuf = alloc_tx_mbuf(1)) == NULLMBUF)
  137.               return;
  138.  
  139.        if ((packet = alloc_packet()) == NULLPACKET)
  140.        {
  141.               memout++;
  142.               free_tx_mbuf(mbuf);
  143.               return;
  144.        }
  145.  
  146.        port[portno].arprestx++;
  147.  
  148.        mbuf->m_next  = NULLMBUF;
  149.        mbuf->m_off   = MMINOFF;
  150.        mbuf->m_len   = 28;
  151.        mbuf->m_indir = FALSE;
  152.        mbuf->m_type  = MT_DATA;
  153.  
  154.        ipaddr = get32(data + 14);
  155.  
  156.        put16(mbuf->m_dat + 0, HARDWARE_ETHER);
  157.        put16(mbuf->m_dat + 2, FRAME_IP);
  158.        mbuf->m_dat[4] = 6;
  159.        mbuf->m_dat[5] = 4;
  160.        put16(mbuf->m_dat + 6, ARP_RESPONSE);
  161.  
  162.        /* Sender */
  163.        mbuf->m_dat[8]  = port[portno].hwaddr[0];
  164.        mbuf->m_dat[9]  = port[portno].hwaddr[1];
  165.        mbuf->m_dat[10] = port[portno].hwaddr[2];
  166.        mbuf->m_dat[11] = port[portno].hwaddr[3];
  167.        mbuf->m_dat[12] = port[portno].hwaddr[4];
  168.        mbuf->m_dat[13] = port[portno].hwaddr[5];
  169.        put32(mbuf->m_dat + 14, port[portno].ipaddr);
  170.  
  171.        /* Target */
  172.        mbuf->m_dat[18] = data[8];
  173.        mbuf->m_dat[19] = data[9];
  174.        mbuf->m_dat[20] = data[10];
  175.        mbuf->m_dat[21] = data[11];
  176.        mbuf->m_dat[22] = data[12];
  177.        mbuf->m_dat[23] = data[13];
  178.        put32(mbuf->m_dat + 24, ipaddr);
  179.  
  180.        packet->next      = NULLPACKET;
  181.        packet->hwaddr[0] = data[8];
  182.        packet->hwaddr[1] = data[9];
  183.        packet->hwaddr[2] = data[10];
  184.        packet->hwaddr[3] = data[11];
  185.        packet->hwaddr[4] = data[12];
  186.        packet->hwaddr[5] = data[13];
  187.        packet->port      = portno;
  188.        packet->type      = FRAME_ARP;
  189.        packet->data      = mbuf;
  190.  
  191.        Queue_Transmit_Packet(packet);
  192.  
  193.        if (Search_ARP_Cache(portno, ipaddr) == NULL)
  194.        {
  195.                arp = Free_ARP_Slot();
  196.  
  197.                arp->ipaddr    = ipaddr;
  198.                arp->hwaddr[0] = data[8];
  199.                arp->hwaddr[1] = data[9];
  200.                arp->hwaddr[2] = data[10];
  201.                arp->hwaddr[3] = data[11];
  202.                arp->hwaddr[4] = data[12];
  203.                arp->hwaddr[5] = data[13];
  204.                arp->port      = portno;
  205.                arp->ttl       = TIMEOUT_RESOLVED;
  206.                arp->status    = ARP_RESOLVED;
  207.                arp->packet    = NULLPACKET;
  208.        }
  209. }
  210.  
  211. void Receive_ARP_Response(int portno, int bcast, char *data)
  212. {
  213.        struct arp *arp;
  214.        register int i;
  215.        int ipaddr;
  216.  
  217.        port[portno].arpresrx++;
  218.  
  219.        ipaddr = get32(data + 14);
  220.  
  221.        for (i = 0; i < MAXARP; i++)
  222.        {
  223.               if (arplist[i].ipaddr == ipaddr &&
  224.                   arplist[i].port   == portno &&
  225.                   arplist[i].status != ARP_UNUSED)
  226.               {
  227.                       arplist[i].hwaddr[0] = data[8];
  228.                       arplist[i].hwaddr[1] = data[9];
  229.                       arplist[i].hwaddr[2] = data[10];
  230.                       arplist[i].hwaddr[3] = data[11];
  231.                       arplist[i].hwaddr[4] = data[12];
  232.                       arplist[i].hwaddr[5] = data[13];
  233.  
  234.                       arplist[i].status = ARP_RESOLVED;
  235.                       arplist[i].ttl    = TIMEOUT_RESOLVED;
  236.  
  237.                       if (arplist[i].packet != NULLPACKET)
  238.                       {
  239.                               arplist[i].packet->hwaddr[0] = data[8];
  240.                               arplist[i].packet->hwaddr[1] = data[9];
  241.                               arplist[i].packet->hwaddr[2] = data[10];
  242.                               arplist[i].packet->hwaddr[3] = data[11];
  243.                               arplist[i].packet->hwaddr[4] = data[12];
  244.                               arplist[i].packet->hwaddr[5] = data[13];
  245.  
  246.                               Queue_Transmit_Packet(arplist[i].packet);
  247.  
  248.                               arplist[i].packet = NULLPACKET;
  249.                       }
  250.  
  251.                       return;
  252.               }
  253.        }
  254.  
  255.        arp = Free_ARP_Slot();
  256.  
  257.        arp->ipaddr    = ipaddr;
  258.        arp->hwaddr[0] = data[8];
  259.        arp->hwaddr[1] = data[9];
  260.        arp->hwaddr[2] = data[10];
  261.        arp->hwaddr[3] = data[11];
  262.        arp->hwaddr[4] = data[12];
  263.        arp->hwaddr[5] = data[13];
  264.        arp->port      = portno;
  265.        arp->ttl       = TIMEOUT_RESOLVED;
  266.        arp->status    = ARP_RESOLVED;
  267.        arp->packet    = NULLPACKET;
  268. }
  269.  
  270. void Initialise_ARP_Cache(void)
  271. {
  272.        register int i;
  273.  
  274.        for (i = 0; i < MAXARP; i++)
  275.               arplist[i].status = ARP_UNUSED;
  276. }
  277.  
  278. void Timeout_ARP_Cache(void)
  279. {
  280.        register int i;
  281.  
  282.        for (i = 0; i < MAXARP; i++)
  283.        {
  284.                if (arplist[i].status != ARP_UNUSED)
  285.                {
  286.                         arplist[i].ttl--;
  287.  
  288.                         if (arplist[i].ttl == 0)
  289.                         {
  290.                                 arplist[i].status = ARP_UNUSED;
  291.  
  292.                                 if (arplist[i].packet != NULLPACKET)
  293.                                 {
  294.                                        free_tx_mbuf(arplist[i].packet->data);
  295.                                        free_packet(arplist[i].packet);
  296.                                 }
  297.                         }
  298.                }
  299.        }
  300. }
  301.  
  302. char *Search_ARP_Cache(int portno, int ipaddr)
  303. {
  304.        register int i;
  305.  
  306.        for (i = 0; i < MAXARP; i++)
  307.        {
  308.                if (arplist[i].ipaddr == ipaddr && arplist[i].port == portno)
  309.                {
  310.                         if (arplist[i].status == ARP_RESOLVED)
  311.                         {
  312.                                 arplist[i].ttl = TIMEOUT_RESOLVED;
  313.                                 return(arplist[i].hwaddr);
  314.                         }
  315.  
  316.                         if (arplist[i].status == ARP_RESOLVING)
  317.                                 return(NULL);
  318.                }
  319.        }
  320.  
  321.        return(NULL);
  322. }
  323.  
  324. struct arp *Free_ARP_Slot(void)
  325. {
  326.        register int i, oldest;
  327.  
  328.        for (oldest = 0, i = 0; i < MAXARP; i++)
  329.        {
  330.               if (arplist[i].status == ARP_UNUSED)
  331.                      return(arplist + i);
  332.  
  333.               if (arplist[i].status == ARP_RESOLVED)
  334.                      if (arplist[i].ttl < arplist[oldest].ttl)
  335.                              oldest = i;
  336.        }
  337.  
  338.        return(arplist + oldest);
  339. }
  340.  
  341. void ARP_Stats(void)
  342. {
  343.        register int i;
  344.        char addr[4];
  345.  
  346.        for (i = 0; i < MAXARP; i++)
  347.        {
  348.                if (arplist[i].status != ARP_UNUSED)
  349.                {
  350.                        put32(addr, arplist[i].ipaddr);
  351.  
  352.                        printf("Port:%d IP:%d.%d.%d.%d HW:%02X:%02X:%02X:%02X:%02X:%02X State:%s TTL:%d %s\n",
  353.                               arplist[i].port,
  354.                               addr[0], addr[1], addr[2], addr[3],
  355.                               arplist[i].hwaddr[0], arplist[i].hwaddr[1],
  356.                               arplist[i].hwaddr[2], arplist[i].hwaddr[3],
  357.                               arplist[i].hwaddr[4], arplist[i].hwaddr[5],
  358.                               (arplist[i].status == ARP_RESOLVED) ? "Resolved" : "Resolving",
  359.                               arplist[i].ttl / 100,
  360.                               (arplist[i].packet != NULLPACKET) ? "Packet" : "");
  361.  
  362.                }
  363.        }
  364. }
  365.