X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=KernelLand%2FModules%2FIPStack%2Farp.c;h=2957eeeac487c6efbf5fec35b8121ca1627459b0;hb=2a49f5a6be4fd478ae4249115ff2a3bf0e34d7e5;hp=abaea27584599a4e7d662503e64a5da903637054;hpb=48743e39650eb1ef988380e9d95f27fd40d3a9ce;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/IPStack/arp.c b/KernelLand/Modules/IPStack/arp.c index abaea275..2957eeea 100644 --- a/KernelLand/Modules/IPStack/arp.c +++ b/KernelLand/Modules/IPStack/arp.c @@ -7,9 +7,13 @@ #include "ipstack.h" #include "arp.h" #include "link.h" +#include "ipv4.h" // For IPv4_Netmask +#include "include/adapters_int.h" // for MAC addr +#include +#include #define ARPv6 0 -#define ARP_CACHE_SIZE 64 +#define ARP_CACHE_SIZE 128 #define ARP_MAX_AGE (60*60*1000) // 1Hr // === IMPORTS === @@ -32,6 +36,8 @@ struct sARP_Cache4 { } *gaARP_Cache4; int giARP_Cache4Space; tMutex glARP_Cache4; +tSemaphore gARP_Cache4Semaphore; + int giARP_WaitingThreads; #if ARPv6 struct sARP_Cache6 { tIPv6 IP; @@ -42,7 +48,6 @@ struct sARP_Cache6 { int giARP_Cache6Space; tMutex glARP_Cache6; #endif -volatile int giARP_LastUpdateID = 0; // === CODE === /** @@ -62,6 +67,7 @@ int ARP_Initialise() #endif Link_RegisterType(0x0806, ARP_int_GetPacket); + Semaphore_Init(&gARP_Cache4Semaphore, 0, 0, "ARP4", "Cache Changes"); return 1; } @@ -70,10 +76,8 @@ int ARP_Initialise() */ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) { - int lastID; int i; struct sArpRequest4 req; - Sint64 timeout; ENTER("pInterface xAddress", Interface, Address); @@ -131,10 +135,9 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) LEAVE('-'); return gaARP_Cache4[i].MAC; } + giARP_WaitingThreads ++; Mutex_Release( &glARP_Cache4 ); - lastID = giARP_LastUpdateID; - // Create request Log_Log("ARP4", "Asking for address %i.%i.%i.%i", Address.B[0], Address.B[1], Address.B[2], Address.B[3] @@ -144,35 +147,39 @@ tMacAddr ARP_Resolve4(tInterface *Interface, tIPv4 Address) req.HWSize = 6; req.SWSize = 4; req.Request = htons(1); - req.SourceMac = Interface->Adapter->MacAddr; + memcpy(&req.SourceMac, Interface->Adapter->HWAddr, 6); // TODO: Remove hard size req.SourceIP = *(tIPv4*)Interface->Address; req.DestMac = cMAC_BROADCAST; req.DestIP = Address; - + + // Assumes only a header and footer at link layer + tIPStackBuffer *buffer = IPStack_Buffer_CreateBuffer(3); + IPStack_Buffer_AppendSubBuffer(buffer, sizeof(struct sArpRequest4), 0, &req, NULL, NULL); + // Send Request - Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, sizeof(struct sArpRequest4), &req); - - timeout = now() + Interface->TimeoutDelay; + Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, buffer); + + // Clean up + IPStack_Buffer_DestroyBuffer(buffer); // Wait for a reply + Time_ScheduleTimer(NULL, Interface->TimeoutDelay); for(;;) { - while(lastID == giARP_LastUpdateID && now() < timeout) { - Threads_Yield(); - } - - if( now() >= timeout ) { + if( Semaphore_Wait(&gARP_Cache4Semaphore, 1) != 1 ) + { + giARP_WaitingThreads --; Log_Log("ARP4", "Timeout"); - break; // Timeout + break; } - - lastID = giARP_LastUpdateID; + Log_Debug("ARP4", "Cache change"); Mutex_Acquire( &glARP_Cache4 ); for( i = 0; i < giARP_Cache4Space; i++ ) { if(gaARP_Cache4[i].IP.L != Address.L) continue; + giARP_WaitingThreads --; Mutex_Release( &glARP_Cache4 ); Log_Debug("ARP4", "Return %02x:%02x:%02x:%02x:%02x:%02x", gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1], @@ -214,17 +221,20 @@ void ARP_UpdateCache4(tIPv4 SWAddr, tMacAddr HWAddr) else i = oldest; } - - Log_Log("ARP4", "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 - ); + + if( memcmp(&gaARP_Cache4[i].MAC, &HWAddr, sizeof(HWAddr)) != 0 ) + { + Log_Log("ARP4", "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].IP = SWAddr; - gaARP_Cache4[i].MAC = HWAddr; - gaARP_Cache4[i].LastUpdate = now(); - giARP_LastUpdateID ++; + gaARP_Cache4[i].IP = SWAddr; + gaARP_Cache4[i].MAC = HWAddr; + gaARP_Cache4[i].LastUpdate = now(); + Semaphore_Signal(&gARP_Cache4Semaphore, giARP_WaitingThreads); + } Mutex_Release(&glARP_Cache4); } @@ -326,13 +336,18 @@ void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffe req4->DestIP = req4->SourceIP; req4->DestMac = req4->SourceMac; req4->SourceIP = *(tIPv4*)iface->Address;; - req4->SourceMac = Adapter->MacAddr; + memcpy(&req4->SourceMac, Adapter->HWAddr, 6); // TODO: Remove hard size req4->Request = htons(2); Log_Debug("ARP", "Sending back us (%02x:%02x:%02x:%02x:%02x:%02x)", req4->SourceMac.B[0], req4->SourceMac.B[1], req4->SourceMac.B[2], req4->SourceMac.B[3], req4->SourceMac.B[4], req4->SourceMac.B[5]); - Link_SendPacket(Adapter, 0x0806, req4->DestMac, sizeof(tArpRequest4), req4); + + // Assumes only a header and footer at link layer + tIPStackBuffer *buffer = IPStack_Buffer_CreateBuffer(3); + IPStack_Buffer_AppendSubBuffer(buffer, sizeof(struct sArpRequest4), 0, req4, NULL, NULL); + Link_SendPacket(Adapter, 0x0806, req4->DestMac, buffer); + IPStack_Buffer_DestroyBuffer(buffer); } break; #if ARPv6