+ // Wait for a reply
+ for(;;)
+ {
+ while(lastID == giARP_LastUpdateID) Threads_Yield();
+ lastID = giARP_LastUpdateID;
+
+ LOCK( &glARP_Cache4 );
+ for( i = 0; i < giARP_Cache4Space; i++ )
+ {
+ if(gaARP_Cache4[i].IP.L != Address.L) continue;
+
+ RELEASE( &glARP_Cache4 );
+ return gaARP_Cache4[i].MAC;
+ }
+ RELEASE( &glARP_Cache4 );
+ }
+}
+
+/**
+ * \brief Updates the ARP Cache entry for an IPv4 Address
+ */
+void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr)
+{
+ int i;
+ int free = -1;
+ int oldest = 0;
+
+ // Find an entry for the IP address in the cache
+ LOCK(&glARP_Cache4);
+ for( i = giARP_Cache4Space; i--; )
+ {
+ if(gaARP_Cache4[oldest].LastUpdate > gaARP_Cache4[i].LastUpdate) {
+ oldest = i;
+ }
+ if( gaARP_Cache4[i].IP.L == SWAddr.L ) break;
+ if( gaARP_Cache4[i].LastUpdate == 0 && free == -1 ) free = i;
+ }
+ // If there was no match, we need to make one
+ if(i == -1) {
+ if(free != -1)
+ i = free;
+ else
+ i = oldest;
+ gaARP_Cache4[i].IP = SWAddr;
+ }
+
+ Log("[ARP ] Caching %i.%i.%i.%i (%02x:%02x:%02x:%02x:%02x:%02x) in %i",
+ SWAddr.B[0], SWAddr.B[1], SWAddr.B[2], SWAddr.B[3],
+ HWAddr.B[0], HWAddr.B[1], HWAddr.B[2], HWAddr.B[3], HWAddr.B[4], HWAddr.B[5],
+ i
+ );
+
+ gaARP_Cache4[i].MAC = HWAddr;
+ gaARP_Cache4[i].LastUpdate = now();
+ giARP_LastUpdateID ++;
+ RELEASE(&glARP_Cache4);
+}
+
+/**
+ * \brief Updates the ARP Cache entry for an IPv6 Address
+ */
+void ARP_UpdateCache6(tIPv6 SWAddr, tMacAddr HWAddr)
+{
+ int i;
+ int free = -1;
+ int oldest = 0;
+
+ // Find an entry for the MAC address in the cache
+ LOCK(&glARP_Cache6);
+ for( i = giARP_Cache6Space; i--; )
+ {
+ if(gaARP_Cache6[oldest].LastUpdate > gaARP_Cache6[i].LastUpdate) {
+ oldest = i;
+ }
+ if( MAC_EQU(gaARP_Cache6[i].MAC, HWAddr) ) break;
+ if( gaARP_Cache6[i].LastUpdate == 0 && free == -1 ) free = i;
+ }
+ // If there was no match, we need to make one
+ if(i == -1) {
+ if(free != -1)
+ i = free;
+ else
+ i = oldest;
+ gaARP_Cache6[i].MAC = HWAddr;
+ }
+
+ gaARP_Cache6[i].IP = SWAddr;
+ gaARP_Cache6[i].LastUpdate = now();
+ giARP_LastUpdateID ++;
+ RELEASE(&glARP_Cache6);