ARP.c

Go to the documentation of this file.
00001 // ////////////////////////////////////////////////////////////////////////////
00002 // ////////////////////////////////////////////////////////////////////////////
00032 // ////////////////////////////////////////////////////////////////////////////
00033 // ////////////////////////////////////////////////////////////////////////////
00093  /*
00094  * Author               Date    Comment
00095  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00096  * Nilesh Rajbharti     5/1/01  Original        (Rev 1.0)
00097  * Nilesh Rajbharti     2/9/02  Cleanup
00098  * Nilesh Rajbharti     5/22/02 Rev 2.0 (See version.log for detail)
00099  * Howard Schlunder     8/17/06 Combined ARP.c and ARPTsk.c into ARP.c; 
00100  *                              rewrote some of it to look more linear
00101  ********************************************************************/
00102 
00103 #define __ARP_C
00104 
00105 #include "TCPIP.h"
00106 
00107 
00108 /****************************************************************************
00109   Section:
00110     Constants and Variables
00111   ***************************************************************************/
00112 
00113 // ARP Operation codes.
00114 #define ARP_OPERATION_REQ       0x01u
00115 #define ARP_OPERATION_RESP      0x02u
00116 
00117 // ETHERNET packet type as defined by IEEE 802.3
00118 #define HW_ETHERNET             (0x0001u)
00119 #define ARP_IP                  (0x0800u)
00120 
00121 
00122 
00123 // This ARP task caches one ARP response.
00124 static NODE_INFO Cache;
00125 
00126 
00127 // ARP packet structure
00128 typedef struct __attribute__((aligned(2), packed))
00129 {
00130     WORD        HardwareType;
00131     WORD        Protocol;
00132     BYTE        MACAddrLen;
00133     BYTE        ProtocolLen;
00134     WORD        Operation;
00135     MAC_ADDR    SenderMACAddr;
00136     IP_ADDR     SenderIPAddr;
00137     MAC_ADDR    TargetMACAddr;
00138     IP_ADDR     TargetIPAddr;
00139 } ARP_PACKET;
00140 
00141 
00142 /****************************************************************************
00143   Section:
00144     Helper Function Prototypes
00145   ***************************************************************************/
00146 static void SwapARPPacket(ARP_PACKET *p);
00147 static BOOL ARPPut(ARP_PACKET *packet);
00148 
00149 
00150 
00151 /****************************************************************************
00152   Section:
00153     Function Implementations
00154   ***************************************************************************/
00155 
00156 /*****************************************************************************
00157   Function:
00158     static BOOL ARPPut(ARP_PACKET* packet)
00159 
00160   Description:
00161     Writes an ARP packet to the MAC.
00162 
00163   Precondition:
00164     None
00165 
00166   Parameters:
00167     packet - A pointer to an ARP_PACKET structure with correct operation
00168                 and target preconfigured.
00169 
00170   Return Values:
00171     TRUE - The ARP packet was generated properly
00172     FALSE - Not a possible return value
00173   ***************************************************************************/
00174 static BOOL ARPPut(ARP_PACKET *packet)
00175 {
00176     while(!MACIsTxReady());
00177     MACSetWritePtr(BASE_TX_ADDR);
00178     
00179 
00180     packet->HardwareType  = HW_ETHERNET;
00181     packet->Protocol      = ARP_IP;
00182     packet->MACAddrLen    = sizeof(MAC_ADDR);
00183     packet->ProtocolLen   = sizeof(IP_ADDR);
00184     
00185     // MODIFIX: Copy the MAC adress from a flash location instead from a RAM 
00186     // location.
00187     memcpypgm2ram(&packet->SenderMACAddr, ( ROM void * ) pu8MAC, sizeof(packet->SenderMACAddr));
00188     // MODIFIX: Take IP from eWicht specific sIPConfig-Structure:
00189     packet->SenderIPAddr  = sIPConfig.MyIPAddr; 
00190 
00191     SwapARPPacket(packet);
00192 
00193     MACPutHeader(&packet->TargetMACAddr, MAC_ARP, sizeof(*packet));
00194     MACPutArray((BYTE*)packet, sizeof(*packet));
00195     MACFlush();
00196     
00197     return TRUE;
00198 }
00199 
00200 
00201 /*****************************************************************************
00202   Function:
00203     void ARPInit(void)
00204 
00205   Summary:
00206     Initializes the ARP module.
00207     
00208   Description:
00209     Initializes the ARP module.  Call this function once at boot to 
00210     invalidate the cached lookup.
00211 
00212   Precondition:
00213     None
00214 
00215   Parameters:
00216     None
00217 
00218   Returns:
00219     None
00220   
00221   Remarks:
00222     None
00223   ***************************************************************************/
00224 
00225 void ARPInit(void)
00226 {
00227     Cache.MACAddr.v[0] = 0xff;
00228     Cache.MACAddr.v[1] = 0xff;
00229     Cache.MACAddr.v[2] = 0xff;
00230     Cache.MACAddr.v[3] = 0xff;
00231     Cache.MACAddr.v[4] = 0xff;
00232     Cache.MACAddr.v[5] = 0xff;
00233 
00234     Cache.IPAddr.Val = 0x0;
00235 }
00236 
00237 
00238 /*****************************************************************************
00239   Function:
00240     BOOL ARPProcess(void)
00241 
00242   Summary:
00243     Processes an incoming ARP packet.
00244     
00245   Description:
00246     Retrieves an ARP packet from the MAC buffer and determines if it is a
00247     response to our request (in which case the ARP is resolved) or if it
00248     is a request requiring our response (in which case we transmit one.)
00249 
00250   Precondition:
00251     ARP packet is ready in the MAC buffer.
00252 
00253   Parameters:
00254     None
00255 
00256   Return Values:
00257     TRUE - All processing of this ARP packet is complete.  Do not call 
00258             again until a new ARP packet is waiting in the RX buffer.
00259     FALSE - This function must be called again.  More time is needed to 
00260             send an ARP response.
00261   ***************************************************************************/
00262 
00263 BOOL ARPProcess(void)
00264 {
00265     ARP_PACKET packet;
00266     static NODE_INFO Target;
00267     static enum
00268     {
00269         SM_ARP_IDLE = 0,
00270         SM_ARP_REPLY
00271     } smARP = SM_ARP_IDLE;
00272 
00273     switch(smARP)
00274     {
00275         case SM_ARP_IDLE:
00276             // Obtain the incoming ARP packet
00277             MACGetArray((BYTE*)&packet, sizeof(packet));        
00278             MACDiscardRx();
00279             SwapARPPacket(&packet);
00280         
00281             // Validate the ARP packet
00282             if ( packet.HardwareType != HW_ETHERNET     ||
00283                  packet.MACAddrLen != sizeof(MAC_ADDR)  ||
00284                  packet.ProtocolLen != sizeof(IP_ADDR) )
00285             {
00286                  return TRUE;
00287             }
00288         
00289             // Handle incoming ARP responses
00290             if(packet.Operation == ARP_OPERATION_RESP)
00291             {
00292                 Cache.MACAddr = packet.SenderMACAddr;
00293                 Cache.IPAddr = packet.SenderIPAddr;
00294                 return TRUE;
00295             }
00296 
00297             // Handle incoming ARP requests for our MAC address
00298             if(packet.Operation == ARP_OPERATION_REQ)
00299             {
00300                 // MODIFIX: Changed from the Microchip AppConfig structure 
00301                 // to the more eWicht specific sIPConfig structure.
00302                 if( packet.TargetIPAddr.Val != sIPConfig.MyIPAddr.Val )
00303                 {
00304                     return TRUE;
00305                 }
00306                 Target.IPAddr = packet.SenderIPAddr;
00307                 Target.MACAddr = packet.SenderMACAddr;
00308 
00309                 smARP = SM_ARP_REPLY;
00310             }
00311             // Do not break.  If we get down here, we need to send a reply. 
00312 
00313         case SM_ARP_REPLY:
00314             packet.Operation        = ARP_OPERATION_RESP;
00315             packet.TargetMACAddr    = Target.MACAddr;
00316             packet.TargetIPAddr     = Target.IPAddr;
00317 
00318             // Send an ARP response to a previously received request
00319             if(!ARPPut(&packet))
00320             {
00321                return FALSE;
00322             }
00323 
00324             // Begin listening for ARP requests again
00325             smARP = SM_ARP_IDLE;
00326             break;
00327     }
00328 
00329     return TRUE;
00330 }
00331 
00332 
00333 /*****************************************************************************
00334   Function:
00335     void ARPResolve(IP_ADDR* IPAddr)
00336 
00337   Summary:
00338     Transmits an ARP request to resolve an IP address.
00339     
00340   Description:
00341     This function transmits and ARP request to determine the hardware
00342     address of a given IP address.
00343 
00344   Precondition:
00345     ARP packet is ready in the MAC buffer.
00346 
00347   Parameters:
00348     IPAddr - The IP address to be resolved
00349 
00350   Returns:
00351     None
00352 
00353   Remarks:
00354     None
00355   ***************************************************************************/
00356 
00357 void ARPResolve(IP_ADDR *IPAddr)
00358 {
00359     ARP_PACKET packet;
00360 
00361     packet.Operation            = ARP_OPERATION_REQ;
00362     packet.TargetMACAddr.v[0]   = 0xff;
00363     packet.TargetMACAddr.v[1]   = 0xff;
00364     packet.TargetMACAddr.v[2]   = 0xff;
00365     packet.TargetMACAddr.v[3]   = 0xff;
00366     packet.TargetMACAddr.v[4]   = 0xff;
00367     packet.TargetMACAddr.v[5]   = 0xff;
00368 
00369 
00370     // ARP query either the IP address directly (on our subnet), or do an ARP query for our Gateway if off of our subnet
00371     // MODIFIX: Changed from the Microchip AppConfig structure 
00372     // to the more eWicht specific sIPConfig structure.
00373     packet.TargetIPAddr         = ((sIPConfig.MyIPAddr.Val ^ IPAddr->Val) & sIPConfig.MyMask.Val) ? sIPConfig.MyGateway : *IPAddr;
00374 
00375     // MODIFIX: Only if TargetIPAddr is a valid address, put the ARP frame to
00376     // the ethernet.
00377     if (packet.TargetIPAddr.Val)
00378         ARPPut(&packet);
00379 }
00380 
00381 
00382 /*****************************************************************************
00383   Function:
00384     BOOL ARPIsResolved(IP_ADDR* IPAddr, MAC_ADDR* MACAddr)
00385 
00386   Summary:
00387     Determines if an ARP request has been resolved yet.
00388     
00389   Description:
00390     This function checks if an ARP request has been resolved yet, and if
00391     so, stores the resolved MAC address in the pointer provided.
00392 
00393   Precondition:
00394     ARP packet is ready in the MAC buffer.
00395 
00396   Parameters:
00397     IPAddr - The IP address to be resolved
00398     MACAddr - A buffer to store the corresponding MAC address
00399 
00400   Return Values:
00401     TRUE - The IP address has been resolved and MAC address indicates the
00402             response.
00403     FALSE - The IP address is not resolved.
00404 
00405   Remarks:
00406     None
00407   ***************************************************************************/
00408 
00409 BOOL ARPIsResolved(IP_ADDR *IPAddr, MAC_ADDR *MACAddr)
00410 {
00411     // MODIFIX: Changed from the Microchip AppConfig structure 
00412     // to the more eWicht specific sIPConfig structure.
00413     if((Cache.IPAddr.Val == IPAddr->Val) || 
00414       ((Cache.IPAddr.Val == sIPConfig.MyGateway.Val) && Cache.IPAddr.Val))
00415     {
00416         *MACAddr = Cache.MACAddr;
00417         return TRUE;
00418     }
00419     return FALSE;
00420 }
00421 
00422 
00423 /*****************************************************************************
00424   Function:
00425     static void SwapARPPacket(ARP_PACKET* p)
00426 
00427   Description:
00428     Swaps endian-ness of header information in an ARP packet.
00429 
00430   Precondition:
00431     None
00432 
00433   Parameters:
00434     p - The ARP packet to be swapped
00435 
00436   Returns:
00437     None
00438   ***************************************************************************/
00439 static void SwapARPPacket(ARP_PACKET *p)
00440 {
00441     p->HardwareType     = swaps(p->HardwareType);
00442     p->Protocol         = swaps(p->Protocol);
00443     p->Operation        = swaps(p->Operation);
00444 }
00445 
00446 /*****************************************************************************
00447 // MODIFIX: Added the function for flushing the ARP cache.
00448   ***************************************************************************/
00449 void ARPFlush(void)
00450 {
00451     ARPInit();
00452 }

Generated on Sun Nov 27 20:02:37 2011 for eWicht by  doxygen 1.5.5