- Sint64 timeout;
-
- ENTER("pInterface xAddress", Interface, Address);
-
- // Check for broadcast
- if( Address.L == -1 )
- {
- LOG("Broadcast");
- LEAVE('-');
- return cMAC_BROADCAST;
- }
-
- // Check routing tables if not on this subnet
- if( IPStack_CompareAddress(4, &Address, Interface->Address, Interface->SubnetBits) == 0 )
- {
- tRoute *route = IPStack_FindRoute(4, Interface, &Address);
- // If the next hop is defined, use it
- // - 0.0.0.0 as the next hop means "no next hop / direct"
- if( route && ((tIPv4*)route->NextHop)->L != 0 )
- {
- // Recursion: see /Recursion/
- LOG("Recursing with %s", IPStack_PrintAddress(4, route->NextHop));
- LEAVE('-');
- return ARP_Resolve4(Interface, *(tIPv4*)route->NextHop);
- }
- // No route, fall though
- }
- else
- {
- Uint32 netmask;
- // Check for broadcast
- netmask = IPv4_Netmask(Interface->SubnetBits);
- if( (Address.L & ~netmask) == (0xFFFFFFFF & ~netmask) )
- {
- LOG("Local Broadcast");
- LEAVE('-');
- return cMAC_BROADCAST;
- }
- }
-
- // Check ARP Cache
- Mutex_Acquire( &glARP_Cache4 );
- for( i = 0; i < giARP_Cache4Space; i++ )
- {
- if(gaARP_Cache4[i].IP.L != Address.L) continue;
-
- // Check if the entry needs to be refreshed
- if( now() - gaARP_Cache4[i].LastUpdate > ARP_MAX_AGE ) break;
-
- Mutex_Release( &glARP_Cache4 );
- LOG("Return %x:%x:%x:%x:%x:%x",
- gaARP_Cache4[i].MAC.B[0], gaARP_Cache4[i].MAC.B[1],
- gaARP_Cache4[i].MAC.B[2], gaARP_Cache4[i].MAC.B[3],
- gaARP_Cache4[i].MAC.B[4], gaARP_Cache4[i].MAC.B[5]
- );
- LEAVE('-');
- return gaARP_Cache4[i].MAC;
- }
- Mutex_Release( &glARP_Cache4 );
-
- lastID = giARP_LastUpdateID;
-