lwip ARP相關處理(2)
阿新 • • 發佈:2019-01-07
if ( ipaddr )
{
/*etharp_cached_entry儲存了上次返回的索引*/
if ( arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE )
{
/*如果上次的還有效,並且是這個要找的ip,直接返回,這個技巧很快*/
/* the cached entry is stable */
if ( ip_addr_cmp ( ipaddr, &arp_table[etharp_cached_entry].ipaddr ) )
{
/* cached entry was the right one! */
ETHARP_STATS_INC ( etharp.cachehit );
return etharp_cached_entry;
}
}
}
/*下面的for做搜尋,並記錄一下表項的狀態和生存時間*/
for ( i = 0; i < ARP_TABLE_SIZE; ++i )
{
/* no empty entry found yet and now we do find one? */
if ( ( empty == ARP_TABLE_SIZE ) && ( arp_table[i].state == ETHARP_STATE_EMPTY ) )
{
/*empty == ARP_TABLE_SIZE
這個第一次生效會生效,這裡只進入一次,就是記錄第一個出現empty表項的位置*/
/* remember first empty entry */
empty = i;
}
/* pending entry? */
else if ( arp_table[i].state == ETHARP_STATE_PENDING )
{
/**看ip是否匹配,匹配的話就直接返回索引更新etharp_cached_entry,*/
/* if given, does IP address match IP address in ARP entry? */
if ( ipaddr && ip_addr_cmp ( ipaddr, &arp_table[i].ipaddr ) )
{
/* found exact IP address match, simply bail out */
etharp_cached_entry = i;
return i;
#if ARP_QUEUEING
/* pending with queued packets? */
}
else if ( arp_table[i].q != NULL )
{
/*找生存時間最長的*/
if ( arp_table[i].ctime >= age_queue )
{
old_queue = i;
age_queue = arp_table[i].ctime;
}
#endif
/* pending without queued packets? */
}
else
{
/*找生存時間最長的*/
if ( arp_table[i].ctime >= age_pending )
{
old_pending = i;
age_pending = arp_table[i].ctime;
}
}
}
/* stable entry? */
else if ( arp_table[i].state == ETHARP_STATE_STABLE )
{
/* if given, does IP address match IP address in ARP entry? */
if ( ipaddr && ip_addr_cmp ( ipaddr, &arp_table[i].ipaddr ) )
{
/*找到匹配的就直接返回了,就是它了!!*/
etharp_cached_entry = i;
return i;
/* remember entry with oldest stable entry in oldest, its age in maxtime */
}
else if ( arp_table[i].ctime >= age_stable )
{/*沒有就記錄一下它活了多久,一會會有判斷,如果活得太久了,就幹掉它,返回一個empty的給上層*/
old_stable = i;
age_stable = arp_table[i].ctime;
}
}
}
/* { we have no match } => try to create a new entry */
/* no empty entry found and not allowed to recycle? */
if ( ( ( empty == ARP_TABLE_SIZE ) && ( ( flags & ETHARP_TRY_HARD ) == 0 ) )
/* or don't create new entry, only search? */
|| ( ( flags & ETHARP_FIND_ONLY ) != 0 ) )
{
{
/*etharp_cached_entry儲存了上次返回的索引*/
if ( arp_table[etharp_cached_entry].state == ETHARP_STATE_STABLE )
{
/*如果上次的還有效,並且是這個要找的ip,直接返回,這個技巧很快*/
/* the cached entry is stable */
if ( ip_addr_cmp ( ipaddr, &arp_table[etharp_cached_entry].ipaddr ) )
{
/* cached entry was the right one! */
ETHARP_STATS_INC ( etharp.cachehit );
return etharp_cached_entry;
}
}
}
/*下面的for做搜尋,並記錄一下表項的狀態和生存時間*/
for ( i = 0; i < ARP_TABLE_SIZE; ++i )
{
/* no empty entry found yet and now we do find one? */
if ( ( empty == ARP_TABLE_SIZE ) && ( arp_table[i].state == ETHARP_STATE_EMPTY ) )
{
/*empty == ARP_TABLE_SIZE
這個第一次生效會生效,這裡只進入一次,就是記錄第一個出現empty表項的位置*/
/* remember first empty entry */
empty = i;
}
/* pending entry? */
else if ( arp_table[i].state == ETHARP_STATE_PENDING )
{
/**看ip是否匹配,匹配的話就直接返回索引更新etharp_cached_entry,*/
/* if given, does IP address match IP address in ARP entry? */
if ( ipaddr && ip_addr_cmp ( ipaddr, &arp_table[i].ipaddr ) )
{
/* found exact IP address match, simply bail out */
etharp_cached_entry = i;
return i;
#if ARP_QUEUEING
/* pending with queued packets? */
}
else if ( arp_table[i].q != NULL )
{
/*找生存時間最長的*/
if ( arp_table[i].ctime >= age_queue )
{
old_queue = i;
age_queue = arp_table[i].ctime;
}
#endif
/* pending without queued packets? */
}
else
{
/*找生存時間最長的*/
if ( arp_table[i].ctime >= age_pending )
{
old_pending = i;
age_pending = arp_table[i].ctime;
}
}
}
/* stable entry? */
else if ( arp_table[i].state == ETHARP_STATE_STABLE )
{
/* if given, does IP address match IP address in ARP entry? */
if ( ipaddr && ip_addr_cmp ( ipaddr, &arp_table[i].ipaddr ) )
{
/*找到匹配的就直接返回了,就是它了!!*/
etharp_cached_entry = i;
return i;
/* remember entry with oldest stable entry in oldest, its age in maxtime */
}
else if ( arp_table[i].ctime >= age_stable )
{/*沒有就記錄一下它活了多久,一會會有判斷,如果活得太久了,就幹掉它,返回一個empty的給上層*/
old_stable = i;
age_stable = arp_table[i].ctime;
}
}
}
/* { we have no match } => try to create a new entry */
/* no empty entry found and not allowed to recycle? */
if ( ( ( empty == ARP_TABLE_SIZE ) && ( ( flags & ETHARP_TRY_HARD ) == 0 ) )
/* or don't create new entry, only search? */
|| ( ( flags & ETHARP_FIND_ONLY ) != 0 ) )
{