⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arp.lst

📁 单片机控制RTL8019AS的程序,C语言编写,仿真通过.
💻 LST
字号:
C51 COMPILER V7.06   ARP                                                                   10/09/2006 21:51:54 PAGE 1   


C51 COMPILER V7.06, COMPILATION OF MODULE ARP
OBJECT MODULE PLACED IN arp.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE arp.c BROWSE DEBUG OBJECTEXTEND

stmt level    source

   1          //-----------------------------------------------------------------------------
   2          // Net ARP.C
   3          //
   4          // This module handles ARP messages and ARP resolution and manages
   5          // the ARP cache. Refer to RFC 826 and RFC 1122
   6          //-----------------------------------------------------------------------------
   7          #include <general.h>
   8          
   9          
  10          
  11          extern UCHAR code broadcast_hwaddr[]; 
  12          extern WAIT xdata wait;
  13          extern UCHAR code my_hwaddr[];
  14          extern ULONG code my_ipaddr;
  15          extern ULONG code my_subnet;
  16          extern ULONG code gateway_ipaddr;
  17          ARP_CACHE xdata arp_cache[CACHESIZE];
  18          UCHAR waiting_for_arp;
  19          
  20          
  21          
  22          void init_arp(void)
  23          {
  24   1              memset(arp_cache, 0, sizeof(arp_cache)); 
  25   1              memset(&wait, 0, sizeof(wait));
  26   1              waiting_for_arp = FALSE;
  27   1      }
  28          
  29          
  30          
  31          
  32          //------------------------------------------------------------------------
  33          //      This is called every 60 seconds to age the ARP cache
  34          // If an entry times out then it is deleted from the cache
  35          // See "TCP/IP Illustrated, Volume 1" Sect 4.3
  36          //------------------------------------------------------------------------
  37          void age_arp_cache(void)
  38          {
  39   1              UCHAR i;
  40   1              
  41   1         for (i=0; i < CACHESIZE; i++)
  42   1         {
  43   2            if ((arp_cache[i].ipaddr != 0) && (arp_cache[i].timer))
  44   2            {
  45   3               arp_cache[i].timer--;
  46   3                              if (arp_cache[i].timer == 0)
  47   3               {
  48   4                                      // Timed out so clear out cache entry
  49   4                                      // Do not need to zero hwaddr
  50   4                                      arp_cache[i].ipaddr = 0;
  51   4                  
  52   4                              }
  53   3                      }
  54   2         }
  55   1      }
C51 COMPILER V7.06   ARP                                                                   10/09/2006 21:51:54 PAGE 2   

  56          
  57          
  58          
  59          
  60          //------------------------------------------------------------------------
  61          // This allocates memory for the entire outgoing message,
  62          // including eth and ip headers, then builds an outgoing
  63          // ARP response message
  64          // See "TCP/IP Illustrated, Volume 1" Sect 4.4
  65          //------------------------------------------------------------------------
  66          void arp_send(UCHAR * hwaddr, ULONG ipaddr, UCHAR msg_type)
  67          {
  68   1              UCHAR xdata * outbuf;
  69   1              ARP_HEADER xdata * arp;
  70   1               
  71   1         
  72   1         // Allocate memory for entire outgoing message including
  73   1         // eth header. Always 42 bytes
  74   1         outbuf = (UCHAR xdata *)malloc(42);
  75   1         if (outbuf == NULL)
  76   1         {
  77   2            
  78   2            return;
  79   2         }      
  80   1           
  81   1         // Allow 14 bytes for the ethernet header
  82   1         arp = (ARP_HEADER xdata *)(outbuf + 14);
  83   1              
  84   1              arp->hardware_type = DIX_ETHERNET; 
  85   1         arp->protocol_type = IP_PACKET;
  86   1         arp->hwaddr_len = 6;
  87   1              arp->ipaddr_len = 4;               
  88   1         arp->message_type = (UINT)msg_type;
  89   1         
  90   1         // My hardware address and IP addresses 
  91   1         memcpy(arp->source_hwaddr, my_hwaddr, 6);
  92   1         arp->source_ipaddr = my_ipaddr;
  93   1      
  94   1         // Destination hwaddr and dest IP addr
  95   1         if (msg_type == ARP_REQUEST) memset(arp->dest_hwaddr, 0, 6);
  96   1         else memcpy(arp->dest_hwaddr, hwaddr, 6);
  97   1         
  98   1         arp->dest_ipaddr = ipaddr;
  99   1            
 100   1         // If request then the message is a brodcast, if a response then
 101   1         // send to specified hwaddr
 102   1         // ARP payload size is always 28 bytes
 103   1              if (msg_type == ARP_REQUEST) eth_send(outbuf, broadcast_hwaddr, ARP_PACKET, 28);
 104   1         else eth_send(outbuf, hwaddr, ARP_PACKET, 28);
 105   1      }
 106          
 107          
 108          
 109          //------------------------------------------------------------------------
 110          // This re-sends an ARP request if there was no response to
 111          // the first one.        It is called every 0.5 seconds.  If there
 112          // is no response after 2 re-tries, the datagram that IP was 
 113          // trying to send is deleted
 114          //-----------------------------------------------------------------------
 115          void arp_retransmit(void)
 116          {
 117   1              static UCHAR idata retries = 0; 
C51 COMPILER V7.06   ARP                                                                   10/09/2006 21:51:54 PAGE 3   

 118   1              
 119   1              if ((waiting_for_arp) && (wait.timer))
 120   1              {
 121   2                      wait.timer--;
 122   2                      if (wait.timer == 0)
 123   2                      {
 124   3                              retries++;
 125   3                              if (retries <= 2)
 126   3                              {
 127   4      
 128   4                                      arp_send(NULL, wait.ipaddr, ARP_REQUEST);
 129   4                                      wait.timer = ARP_TIMEOUT;
 130   4                              }
 131   3                              else
 132   3                              {       
 133   4                                      
 134   4                                      wait.timer = 0;
 135   4                                      waiting_for_arp = 0;
 136   4                                      free(wait.buf);
 137   4                              }
 138   3                      }
 139   2              }
 140   1      }
 141          
 142          
 143          
 144          
 145          //------------------------------------------------------------------------
 146          // Find the ethernet hardware address for the given ip address
 147          // If destination IP is on my subnet then we want the eth
 148          // address      of destination, otherwise we want eth addr of gateway. 
 149          // Look in ARP cache first.  If not found there, send ARP request.
 150          // Return pointer to the hardware address or NULL if not found
 151          // See "TCP/IP Illustrated, Volume 1" Sect 4.5
 152          //------------------------------------------------------------------------
 153          UCHAR xdata * arp_resolve(ULONG dest_ipaddr)
 154          {
 155   1         UCHAR i;
 156   1            
 157   1         // If destination IP is not on my subnet then we really want eth addr
 158   1              // of gateway, not destination IP
 159   1              if ((dest_ipaddr ^ my_ipaddr) & my_subnet)
 160   1              {
 161   2                      if (gateway_ipaddr == 0)
 162   2                      {
 163   3                              return (NULL);  
 164   3                      }
 165   2                      else dest_ipaddr = gateway_ipaddr;
 166   2              }
 167   1              
 168   1                 
 169   1         // See if IP addr of interest is in ARP cache
 170   1         for (i=0; i < CACHESIZE; i++)
 171   1         {
 172   2            if (arp_cache[i].ipaddr == dest_ipaddr)
 173   2               return (&arp_cache[i].hwaddr[0]);
 174   2         }
 175   1      
 176   1              // Not in cache so broadcast ARP request
 177   1              arp_send(NULL, dest_ipaddr, ARP_REQUEST);
 178   1                 
 179   1         // Set a flag to indicate that an IP datagram is waiting
C51 COMPILER V7.06   ARP                                                                   10/09/2006 21:51:54 PAGE 4   

 180   1         // to be sent
 181   1         waiting_for_arp = TRUE;
 182   1                                            
 183   1         // Null means that we have sent an ARP request
 184   1         return (NULL); 
 185   1      }
 186          
 187          
 188          
 189          
 190          
 191          //------------------------------------------------------------------------
 192          // This handles incoming ARP messages
 193          // See "TCP/IP Illustrated, Volume 1" Sect 4.4
 194          // Todo:  Resolve problem of trying to add to a full cache
 195          //------------------------------------------------------------------------
 196          void arp_rcve(UCHAR xdata * inbuf)
 197          {
 198   1         UCHAR idata i, cached, oldest;
 199   1         UINT idata minimum;
 200   1         ARP_HEADER xdata * arp;
 201   1            
 202   1         arp = (ARP_HEADER xdata *)(inbuf + 14);
 203   1         cached = FALSE;
 204   1         
 205   1               
 206   1         // Validate incoming frame
 207   1         if ((arp->hardware_type != DIX_ETHERNET) ||
 208   1             (arp->protocol_type != IP_PACKET)) return;
 209   1      
 210   1         // Search ARP cache for senders IP address
 211   1         // If found, update entry and restart timer
 212   1         for (i=0; i < CACHESIZE; i++)
 213   1         {
 214   2            if (arp_cache[i].ipaddr == arp->source_ipaddr)
 215   2            {
 216   3               memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
 217   3               arp_cache[i].timer = CACHETIME;                
 218   3      
 219   3                        
 220   3               break;  
 221   3            }
 222   2         }
 223   1         
 224   1         if (arp->dest_ipaddr != my_ipaddr) return;
 225   1         
 226   1         // At this point we know the the frame is addressed to me
 227   1         // If not already in cache then add entry and start timer
 228   1         if (cached == FALSE)
 229   1         {
 230   2            // Find first blank space and add entry
 231   2                      // Blank entries are indicated by ip addr = 0
 232   2            for (i=0; i < CACHESIZE; i++)
 233   2            {
 234   3               if (arp_cache[i].ipaddr == 0) 
 235   3               {
 236   4                  arp_cache[i].ipaddr = arp->source_ipaddr;
 237   4                  memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);   
 238   4                  arp_cache[i].timer = CACHETIME;
 239   4                      break;
 240   4               }
 241   3            }
C51 COMPILER V7.06   ARP                                                                   10/09/2006 21:51:54 PAGE 5   

 242   2      
 243   2                      // If no blank entries in arp cache     then sort cache
 244   2                      // to find oldest entry and replace it
 245   2                      if (i == CACHESIZE)
 246   2                      {
 247   3                              // Oldest entry is the one with lowest timer value                      
 248   3                              minimum = 0xFFFF;
 249   3                              for (i=0; i < CACHESIZE; i++)
 250   3              {
 251   4                                      if (arp_cache[i].timer < minimum) 
 252   4                                      {
 253   5                                              minimum = arp_cache[i].timer;
 254   5                                              oldest = i;
 255   5                                      }
 256   4                              }
 257   3              
 258   3                              // "oldest" is now index of oldest entry, so replace it
 259   3                              arp_cache[oldest].ipaddr = arp->source_ipaddr;
 260   3               memcpy(&arp_cache[oldest].hwaddr[0], &arp->source_hwaddr[0], 6);   
 261   3               arp_cache[oldest].timer = CACHETIME;
 262   3      
 263   3              }
 264   2              }
 265   1      
 266   1         
 267   1         // If we are waiting for an arp response and the arp response
 268   1              // that just came in is addressed to me and is from the host
 269   1              // we are waiting for, then send        the message-in-waiting
 270   1         if (arp->message_type == ARP_RESPONSE)
 271   1         {
 272   2              if ((waiting_for_arp) && (wait.ipaddr == arp->source_ipaddr))
 273   2              {
 274   3                      waiting_for_arp = FALSE;
 275   3                              ip_send(wait.buf, wait.ipaddr, wait.proto_id, wait.len);
 276   3                      }
 277   2              }
 278   1              else if (arp->message_type == ARP_REQUEST)
 279   1         {
 280   2              // Send ARP response 
 281   2              arp_send(arp->source_hwaddr, arp->source_ipaddr, ARP_RESPONSE);
 282   2              }
 283   1      }
 284          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   1442    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =    110    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =      1      20
   IDATA SIZE       =      1       5
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -