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 }
1.5.5