?? netarp.c
字號:
switch (arpEntries[traverse].state) {
case ARP_PENDING:
case ARP_RESOLVED:
if (arpEntries[traverse].expire < oldestAge) {
oldestAge = arpEntries[traverse].expire;
oldest = traverse;
}
break;
}
}
// **** IF we didn't find any oldest THEN RETURN NULL
if (oldest == -1) return NULL;
// Set traverse to oldest
traverse = oldest;
// ***** Remove oldest from ARP cache table
arpRemove(traverse);
// Free any queued packet (if any) (BUG FIX)
if (arpEntries[traverse].packet) nFreeChain(arpEntries[traverse].packet);
// We have a "free" arp entry, clear it
memset(&arpEntries[traverse], 0, sizeof(arpEntry));
// Update ARP allocated statistics
arpStats.alloc--;
}
// Update ARP allocated statistics
arpStats.alloc++;
// Update max. ARP allocated statistics
if (arpStats.alloc > arpStats.maxAlloc)
arpStats.maxAlloc = arpStats.alloc;
// **** Fill in new ARP entry
// Fill in new infos...
arpEntries[traverse].ip = ip;
// Allow an ARP request to be sent now
arpEntries[traverse].expire = time(NULL) + mySetup.arpExpire;
// Since this is a new entry, we assume this ip is to be resolved
arpEntries[traverse].state = ARP_PENDING;
// Just in case, no packet queued
arpEntries[traverse].packet = NULL;
// Get index
index = arpEntries[traverse].ip & (ARP_TABLE_SIZE - 1);
// **** Insert new entry in ARP cache table
arpEntries[traverse].next = arpTable[index];
arpTable[index] = &arpEntries[traverse];
// arpEntries[traverse].next = arpTable[arpEntries[traverse].ip & (ARP_TABLE_SIZE - 1)];
// arpTable[arpEntries[traverse].ip & (ARP_TABLE_SIZE - 1)] = &arpEntries[traverse];
TRACE("uCIP: ARP Alloc ADDED NEW IP %d.%d.%d.%d\n",
(ip >> 24) & 0xFF,
(ip >> 16) & 0xFF,
(ip >> 8) & 0xFF,
(ip) & 0xFF );
// **** RETURN ARP cache entry allocated
return &arpEntries[traverse];
}
////////////////////////////////////////////////////////////////////////////////
// Search the ARP cache for given IP, create if not found and specified.
//
static arpEntry *arpLookup(u_long ip, int create)
{
arpEntry *entry;
// **** Get first arpEntry
entry = arpTable[ip & (ARP_TABLE_SIZE - 1)];
// Traverse chain
while (entry) {
// Did we find the ip we wanted
if (entry->ip == ip)
// Yes, return it
return entry;
// **** Go to next entry in chain
entry = entry->next;
}
// We didn't find the ip
// **** IF we should create a new entry THEN
if (create)
// **** RETURN new entry created
return arpAlloc(ip);
// **** RETURN no entry found or allocated
return NULL;
}
int arpRequest(u_long ip)
{
NBuf* pNBuf;
int len;
arpPacket arp;
// **** Build arp request packet
// Fill ethernet header
memset(arp.ether.dst, 0xFF, sizeof(arp.ether.dst));
memcpy(arp.ether.src, mySetup.hardwareAddr, sizeof(arp.ether.src));
arp.ether.protocol = htons(ETHERTYPE_ARP);
// Fill arp header
arp.hwType = htons(1); // HW TYPE IS ETHER
arp.hwLength = 6; // 6 bytes long hardware address
arp.prType = htons(ETHERTYPE_IP); // TYPE IS IP
arp.prLength = 4; // 4 bytes IP adresses
arp.operation = htons(ARP_REQUEST); // ARP request
arp.senderIp = mySetup.localAddr; // TODO: check if this should be htonl()'d
memcpy(arp.senderHw, mySetup.hardwareAddr, sizeof(arp.senderHw));
arp.targetIp = htonl(ip);
// Create NBuf with ARP request
nGET(pNBuf);
// If not packet is allocated return FALSE
if (!pNBuf) {
// Update stat
arpStats.nbufError++;
return FALSE;
}
// Append prepared ARP Request
nAPPEND(pNBuf, (void*)&arp, sizeof(arp), len);
if (len != sizeof(arp)) {
nFree(pNBuf);
return FALSE;
}
// Send ARP request
etherSend(pNBuf);
// **** RETURN ARP request packet sent
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
//
int arpResolve(u_long ip, u_char *hardware, NBuf* pNBuf)
{
arpEntry *entry;
if(inDHCP) {
memset(hardware,0xff,6);
return TRUE;
}
// Should this packet be sent to the gateway ?
if ((ip & mySetup.subnetMask) != mySetup.networkAddr) {
// Yes, we have a destination outside our network
// Since we only (currently) support one gateway send it there...
// **** IF we have a gateway defined THEN
// Do we have a gateway defined ?
if (mySetup.gatewayAddr) {
// **** Find entry for gateway
entry = arpLookup(mySetup.gatewayAddr, TRUE);
} else {
// **** No gateway is defined, indicate no entry found for gateway
entry = NULL;
}
} else {
// Otherwise find entry for host on our network
// Added support for IP broadcasts /mogi
// Do we have a local broadcast ?
if ((ip & ~netMask) == ~netMask) {
// Yes, send it as an Ethernet broadcast
// Copy ethernet broadcast address
memset(hardware, 0xFF, sizeof(entry->hardware));
// Return address has been "resolved"
return TRUE;
} else {
// No, this is not a broadcast packet
// Find the entry for this host on our network
entry = arpLookup(ip, TRUE);
}
}
if (!entry) {
// We didn't get an entry!
if (pNBuf) nFreeChain(pNBuf);
return FALSE;
}
// TRACE("uCIP: ARP Resolve LOOKUP IP OK %d.%d.%d.%d\n",
// ((entry)->ip >> 24) & 0xFF, ((entry)->ip >> 16) & 0xFF,
// ((entry)->ip >> 8) & 0xFF, ((entry)->ip) & 0xFF);
// Did we get a valid hardware address
if ((entry->state == ARP_RESOLVED) || (entry->state == ARP_FIXED)) {
// TRACE("uCIP: ARP Resolve IP IS RESOLVED OR FIXED\n");
// Yes! Copy ethernet address
memcpy(hardware, entry->hardware, sizeof(entry->hardware));
// Update expire time
entry->expire = time(NULL) + mySetup.arpExpire;
return TRUE;
}
// No hardware address found, is IP being resolved ?
if (entry->state == ARP_PENDING) {
TRACE("uCIP: ARP Resolve IP IS PENDING\n");
// Is it OK to send a new ARP request ?
if ( entry->expire - mySetup.arpExpire <= time(NULL) ) {
// Update expire time
// Allow a new request to be sent after 1 second
entry->expire = time(NULL) + mySetup.arpExpire + 1;
TRACE("uCIP: ARP Resolve REQUEST FOR IP %d.%d.%d.%d\n",
((entry)->ip >> 24) & 0xFF,
((entry)->ip >> 16) & 0xFF,
((entry)->ip >> 8) & 0xFF,
((entry)->ip) & 0xFF);
// **** Send ARP request
arpRequest(entry->ip);
}
// If a new packet is to be sent
if (pNBuf) {
// Free old queued packet (if any)
if (entry->packet) nFreeChain(entry->packet);
// Queue new packet
entry->packet = pNBuf;
}
return FALSE;
}
// This is wrong should never get here
// Cleanup...
if (pNBuf) nFreeChain(pNBuf);
// **** RETURN none found (FALSE)
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////
//
static void arpRemove(u_long index)
{
arpEntry *entry, *lastEntry = NULL;
// **** Get first arpEntry
entry = arpTable[arpEntries[index].ip & (ARP_TABLE_SIZE - 1)];
// **** IF this is the index we want removed THEN
if (&arpEntries[index] == entry) {
// **** Remove entry from chain
arpTable[arpEntries[index].ip & (ARP_TABLE_SIZE - 1)] =
arpTable[arpEntries[index].ip & (ARP_TABLE_SIZE - 1)]->next;
entry = NULL;
} else {
// **** Go to next entry
lastEntry = entry;
entry = entry->next;
}
// **** WHILE entries in chain
while (entry) {
// **** IF this is the index we want removed THEN
if (&arpEntries[index] == entry) {
// **** Remove entry from chain
lastEntry->next = lastEntry->next->next;
// **** RETURN
return;
} else {
// **** Go to next entry
lastEntry = entry;
entry = entry->next;
}
}
}
#pragma warning (pop)
////////////////////////////////////////////////////////////////////////////////
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -