📄 arp.c
字号:
DEBUGOUT(" Refreshing Existing ARP Entry..\n\r");
for( j=0; j<MAXHWALEN; j++ )
qstruct->hwadr[j] = *hwadr++;
qstruct->ttl = ARP_TIMEOUT;
qstruct->retries = ARP_MAXRETRY;
qstruct->state = ARP_RESOLVED;
/* All OK */
return (0);
}
}
/* Does this address belong to outer world? */
if( IsSub(pra, &localmachine) == 0)
return(-1);
if( localmachine.defgw == pra )
{
if(localmachine.defgw != 0)
{
type = ARP_FIXED_IP;
}
}
/* Address was'nt on cache. Need to allocate new one */
DEBUGOUT("Allocating New ARP Entry..\n\r");
i = arpalloc(type);
if( i < 0 ) /* No Entries Left? */
return(-1);
/* Fill the fields */
qstruct = &arptable[i];
qstruct->pradr = pra; /* Fill IP */
for(i=0; i<MAXHWALEN; i++)
qstruct->hwadr[i] = *hwadr++; /* Fill HW address */
qstruct->retries = ARP_MAXRETRY;
qstruct->ttl = ARP_TIMEOUT;
qstruct->state = ARP_RESOLVED;
DEBUGOUT("ARP Entry Created!..\n\r");
return(1);
}
/******************************************************************************
Function: arpfind
Parameters: UINT32 pra - protocol address
struct netif *localmachine - pointer to config. of network
interface used
UINT8 type - type of address allocated if not found
Return val: struct arpentry* - pointer to solved entry of arp table
0 - entry not found or not ready yet
Date: 01.11.2001
Desc: Find an ARP entry given a protocol address. If no entry is found,
new one is allocated and ARPREQ sent.
*******************************************************************************/
struct arpentry* arpfind (LWORD pra, struct netif *machine, UINT8 type)
{
struct arpentry *qstruct;
INT8 i;
DEBUGOUT("Trying to find MAC address from ARP Cache\n\r");
/* Is the address in the cache */
for( i=0; i<ARP_TSIZE; i++ )
{
qstruct = &arptable[i];
if( qstruct->state == ARP_FREE )
continue;
if( qstruct->pradr == pra)
{
/* The address is in cache, is it valid? */
DEBUGOUT("Address In Cache\n\r");
if( qstruct->state < ARP_RESOLVED )
{
DEBUGOUT("Address in cache but unresolved :(\n\r");
return(0);
}
/* All OK */
return(qstruct);
}
}
/* The address wasn't on the cache. Is it in our Subnet? */
if( IsSub(pra, machine) )
{
/* Yep, we need to send ARP REQUEST */
DEBUGOUT("Need to send ARP Request to local network..\n\r");
if( machine->defgw == pra )
{
if(machine->defgw != 0)
{
type = ARP_FIXED_IP;
}
}
i = arpalloc(type);
if( i < 0 ) /* No Entries Left? */
return(0);
/* Send Request after filling the fields */
qstruct = &arptable[i];
qstruct->pradr = pra; /* Fill IP */
qstruct->hwadr[0] = 0xFF; /* Fill Broadcast IP */
qstruct->hwadr[1] = 0xFF;
qstruct->hwadr[2] = 0xFF;
qstruct->hwadr[3] = 0xFF;
qstruct->hwadr[4] = 0xFF;
qstruct->hwadr[5] = 0xFF;
qstruct->retries = ARP_MAXRETRY;
qstruct->ttl = ARP_RESEND;
arpsendreq( i );
qstruct->state = ARP_PENDING; /* Waiting for Reply */
return(0);
}
/* The Address belongst to the outern world, need to use MAC of */
/* Default Gateway */
DEBUGOUT("Need to use MAC of Default GW\n\r");
if(machine->defgw == 0) /* It's not specified */
return(0);
for( i=0; i<ARP_TSIZE; i++ )
{
qstruct = &arptable[i];
if( qstruct->state == ARP_FREE )
continue;
if( qstruct->pradr == machine->defgw )
{
/* The address is in cache, is it valid? */
if( qstruct->state < ARP_RESOLVED )
{
DEBUGOUT("The Address of Def. GW is not Solved!\n\r");
return(0);
}
/* All OK */
DEBUGOUT(" >> Default Gateway MAC found!\n\r");
return(qstruct);
}
}
/* No default GW address on cache, allocate entry for it? */
i = arpalloc(ARP_FIXED_IP);
if( i < 0 ) /* No Entries Left? */
return(0);
/* Send Request after filling the fields */
qstruct = &arptable[i];
qstruct->pradr = machine->defgw; /* Fill IP */
qstruct->hwadr[0] = 0xFF; /* Fill Broadcast IP */
qstruct->hwadr[1] = 0xFF;
qstruct->hwadr[2] = 0xFF;
qstruct->hwadr[3] = 0xFF;
qstruct->hwadr[4] = 0xFF;
qstruct->hwadr[5] = 0xFF;
qstruct->retries = ARP_MAXRETRY;
qstruct->ttl = ARP_RESEND;
arpsendreq( i );
qstruct->state = ARP_PENDING; /* Waiting for Reply */
return 0;
}
/******************************************************************************
Function: arp_keepcache
Parameters: UINT32 pra - ip address to be held on cache
Return val: INT16 0 - OK
(-1) - Not OK
Date: 02.4.2003
Desc: Tries to keep given dynamic IP on cache. Notice that there is no
guarantee for that because round robin cache replacement may
override the entry.
This function is best suitable for keeping ARP for TCP connections
by calling it periodically.
*******************************************************************************/
INT16 arp_keepcache (UINT32 pra)
{
struct arpentry *qstruct;
INT8 i;
DEBUGOUT("Trying to keep IP on cache\r\n");
/* Is the address in the cache */
for( i=0; i<ARP_TSIZE; i++ )
{
qstruct = &arptable[i];
if( qstruct->state == ARP_FREE )
continue;
if( qstruct->state < ARP_RESOLVED )
continue;
if( qstruct->pradr == pra)
{
/* The address is in cache, is it valid? */
if( qstruct->type != ARP_TEMP_IP )
return(-1);
/* Is it time to start refrsh the entry? */
if( qstruct->ttl <= (ARP_RESEND * 2) )
qstruct->state = ARP_REFRESHING;
/* All OK */
DEBUGOUT("Keeping address on cache\r\n");
return(0);
}
}
return(-1);
}
/******************************************************************************
Function: arpmanage
Parameters: none
Return val: void
Date: 04.11.2001
Desc: Iterate through ARP cache aging entries. If timed-out entry is
found, remove it (dynamic address) or update it
(static address). This function MUST be called periodically by
system.
*******************************************************************************/
void arpmanage (void)
{
struct arpentry *qstruct;
UINT8 i,j;
static UINT8 aenext=0;
/* Check Timer before entering */
if( check_timer(ArpTimer) )
return;
init_timer( ArpTimer, ARP_MANG_TOUT*TIMERTIC);
//DEBUGOUT("Managing ARP Cache\n\r");
for( i=0; i<ARP_TSIZE; i++ )
{
//DEBUGOUT(".");
qstruct = &arptable[aenext];
j = aenext;
/* Take next entry next time */
aenext++;
if(aenext >= ARP_TSIZE)
aenext = 0;
if( qstruct->state == ARP_FREE )
continue;
/* TODO: How about ARP_RESERVED? */
if( qstruct->ttl > 0 ) /* Aging */
qstruct->ttl --;
if( qstruct->ttl == 0 ) /* Timed Out? */
{
/* Do it for temporay entries */
DEBUGOUT("Found Timed out Entry..\n\r");
if( qstruct->type == ARP_TEMP_IP )
{
/* Release it? */
if( qstruct->state == ARP_RESOLVED )
{
DEBUGOUT("Releasing ARP Entry..\n\r");
qstruct->state = ARP_FREE;
continue;
}
/* Decrease retries left */
if( qstruct->retries > 0 )
qstruct->retries--;
if( qstruct->retries == 0 )
{
DEBUGOUT("ARP Replies Used up, releasing entry..\n\r");
qstruct->state = ARP_FREE;
continue;
}
/* So we need to resend ARP request */
DEBUGOUT("Trying to Resolve dynamic ARP Entry..\n\r");
qstruct->ttl = ARP_RESEND;
arpsendreq( j );
if(qstruct->state != ARP_REFRESHING)
qstruct->state = ARP_PENDING; /* Waiting for Reply */
return;
}
/* Do it for Static Entries */
if( qstruct->type == ARP_FIXED_IP )
{
/* So we need to resend ARP request */
/* Do not try to refresh broadcast */
if(qstruct->pradr == IP_BROADCAST_ADDRESS)
{
qstruct->ttl = ARP_TIMEOUT;
continue;
}
DEBUGOUT("Refreshing Static ARP Entry..\n\r");
if( qstruct->retries > 0 )
qstruct->retries--;
if( qstruct->retries == 0 )
qstruct->state = ARP_PENDING;
else
qstruct->state = ARP_REFRESHING;
qstruct->ttl = ARP_RESEND;
arpsendreq( j );
return;
}
}
}
}
/******************************************************************************
Function: arpinit
Parameters: none
Return val: none
Date: 01.11.2001
Desc: Initialize data structures for ARP processing
*******************************************************************************/
void arpinit (void)
{
struct arpentry *qstruct;
INT8 i;
DEBUGOUT("Initializing ARP");
for( i=0; i<ARP_TSIZE; i++ )
{
qstruct = &arptable[i];
qstruct->state = ARP_FREE;
qstruct->type = ARP_TEMP_IP;
DEBUGOUT(".");
}
ArpTimer = get_timer();
init_timer(ArpTimer, ARP_MANG_TOUT*TIMERTIC);
/* set broadcast entry */
qstruct = &arptable[0];
qstruct->pradr = IP_BROADCAST_ADDRESS;
qstruct->state = ARP_RESOLVED;
qstruct->type = ARP_FIXED_IP;
qstruct->ttl = ARP_TIMEOUT;
qstruct->retries = ARP_MAXRETRY;
for(i=0; i<MAXHWALEN; i++)
qstruct->hwadr[i] = 0xFF;
DEBUGOUT("\n\r");
}
/******************************************************************************
Function: IsSub
Parameters: UINT32 ipadr - IP address under check
struct netif *machine - pointer to config. of network
interface used
Return val: 1 - ipadr belongs to subnet of given machine
0 - ipadr is NOT a part of subnet on given machine
Date: 05.11.2001
Desc: Checks if the given IP address belongst to subnet of given
machine.
*******************************************************************************/
UINT8 IsSub (LWORD ipadr, struct netif* machine)
{
UINT32 ltemp;
ltemp = ipadr & machine->netmask; /* Get Subnet part */
ltemp ^= (machine->localip & machine->netmask); /* Compare to my IP */
if( ltemp )
return(0);
return(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -