📄 net_arp.c
字号:
* (3) ARP addresses which MUST be in network-order
*
*
* Argument(s) : pbuf Pointer to network buffer to transmit.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ARP_ERR_CACHE_RESOLVED ARP cache resolved & hardware address
* successfully copied.
* NET_ARP_ERR_CACHE_PEND ARP cache in 'PENDING' state; transmit
* buffer enqueued to ARP cache.
* NET_ARP_ERR_NULL_PTR Argument 'pbuf' passed a NULL pointer;
* OR
* 'pbuf's 'ARP_AddrProtocolPtr'/'ARP_AddrHWPtr'
* are set as NULL pointers.
*
* ---- RETURNED BY NetARP_CacheAddPend() : ----
* NET_ARP_ERR_CACHE_NONE_AVAIL NO available ARP caches to allocate.
* NET_ARP_ERR_CACHE_INVALID_TYPE ARP cache is NOT a valid cache type.
* NET_TMR_ERR_NULL_OBJ Argument 'obj' passed a NULL pointer.
* NET_TMR_ERR_NULL_FNCT Argument 'fnct' passed a NULL pointer.
* NET_TMR_ERR_NONE_AVAIL NO available timers to allocate.
* NET_TMR_ERR_INVALID_TYPE Network timer is NOT a valid timer type.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Tx().
*
* This function is a network protocol suite to network interface (IF) function & SHOULD be
* called only by appropriate network interface function(s).
*
* Note(s) : (3) (a) ARP Cache List is accessed by
*
* (1) NetARP_CacheHandler()
* (2) NetARP_CacheAddPend() via NetARP_CacheInsert()
* (3) NetARP_CacheAddResolved() via NetARP_CacheInsert()
* (4) NetARP_CacheRemove() via NetARP_CacheUnlink()
* (5) NetARP_RxPktCacheUpdate()
* (6) ARP cache's 'TMR->Obj' pointer via NetARP_CacheReqTimeout() &
* NetARP_CacheTimeout()
*
* (b) Since the primary tasks of the network protocol suite are prevented from running
* concurrently (see 'net.h Note #2'), it is NOT necessary to protect the shared
* resources of the ARP Cache List since no asynchronous access from other network
* tasks is possible.
*
* (4) (a) RFC #1122, Section 2.3.2.2 states that "the link layer SHOULD" ... :
*
* (1) "Save (rather than discard) ... packets destined to the same unresolved
* IP address and" ...
* (2) "Transmit the saved packet[s] when the address has been resolved."
*
* (b) Since ARP Layer is the last layer to handle & queue the transmit network
* buffer, it is NOT necessary to increment the network buffer's reference
* counter to include the pending ARP cache buffer queue as a new reference
* to the network buffer.
*
* (5) Some buffer controls were previously initialized in NetBuf_Get() when the packet
* was received at the network interface layer. These buffer controls do NOT need
* to be re-initialized but are shown for completeness.
*********************************************************************************************************
*/
/*$PAGE*/
void NetARP_CacheHandler (NET_BUF *pbuf,
NET_ERR *perr)
{
#if ((NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) && \
(NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
CPU_INT08U *paddr_hw;
CPU_INT08U *paddr_protocol;
NET_BUF_HDR *pbuf_hdr;
NET_BUF_HDR *ptail_buf_hdr;
NET_BUF *ptail_buf;
NET_ARP_CACHE *pcache;
/* ------------------- VALIDATE PTRS ------------------ */
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (pbuf == (NET_BUF *)0) {
NET_CTR_ERR_INC(NetARP_ErrNullPtrCtr);
*perr = NET_ARP_ERR_NULL_PTR;
return;
}
#endif
pbuf_hdr = &pbuf->Hdr;
paddr_hw = pbuf_hdr->ARP_AddrHW_Ptr;
paddr_protocol = pbuf_hdr->ARP_AddrProtocolPtr;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (paddr_hw == (CPU_INT08U *)0) {
NET_CTR_ERR_INC(NetARP_ErrNullPtrCtr);
*perr = NET_ARP_ERR_NULL_PTR;
return;
}
if (paddr_protocol == (CPU_INT08U *)0) {
NET_CTR_ERR_INC(NetARP_ErrNullPtrCtr);
*perr = NET_ARP_ERR_NULL_PTR;
return;
}
#endif
/* ------------------ SRCH ARP CACHE ------------------ */
pcache = NetARP_CacheSrch(paddr_protocol);
if (pcache != (NET_ARP_CACHE *)0) { /* If ARP cache found, chk state. */
switch (pcache->State) {
case NET_ARP_CACHE_STATE_PEND: /* If ARP cache pend, append buf onto Q (see Note #4a1).*/
ptail_buf = pcache->BufQ_Tail;
if (ptail_buf != (NET_BUF *)0) { /* If Q NOT empty, append buf @ Q tail. */
ptail_buf_hdr = &ptail_buf->Hdr;
ptail_buf_hdr->NextSecListPtr = (void *)pbuf;
pbuf_hdr->PrevSecListPtr = (void *)ptail_buf;
pcache->BufQ_Tail = (NET_BUF *)pbuf;
} else { /* Else add buf as first q'd buf. */
pcache->BufQ_Head = (NET_BUF *)pbuf;
pcache->BufQ_Tail = (NET_BUF *)pbuf;
#if 0 /* Init'd in NetBuf_Get() [see Note #5]. */
pbuf_hdr->PrevSecListPtr = (void *)0;
pbuf_hdr->NextSecListPtr = (void *)0;
#endif
}
/* Set ARP cache as unlink fnct/obj. */
pbuf_hdr->UnlinkFnctPtr = (CPU_FNCT_PTR)NetARP_CacheUnlinkBuf;
pbuf_hdr->UnlinkObjPtr = (void *)pcache;
*perr = NET_ARP_ERR_CACHE_PEND;
break;
case NET_ARP_CACHE_STATE_RESOLVED: /* If ARP cache resolved, copy hw addr. */
Mem_Copy((void *) paddr_hw,
(void *)&pcache->HW_Addr[0],
(CPU_SIZE_T) NET_ARP_CFG_HW_ADDR_LEN);
*perr = NET_ARP_ERR_CACHE_RESOLVED;
break;
case NET_ARP_CACHE_STATE_NONE:
case NET_ARP_CACHE_STATE_FREE:
default:
NetARP_CacheRemove(pcache, DEF_YES);
NetARP_CacheAddPend(pbuf, pbuf_hdr, paddr_protocol, perr);
break;
}
} else { /* Else add new ARP cache into ARP Cache List. */
NetARP_CacheAddPend(pbuf, pbuf_hdr, paddr_protocol, perr);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetARP_CacheCalcStat()
*
* Description : (1) Calculate ARP statistics :
*
* (a) ARP cache found percentage
*
*
* Argument(s) : none.
*
* Return(s) : ARP cache found percentage, if NO errors,
*
* NULL cache found percentage, otherwise.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (2) NetARP_CacheCalcStat() blocked until network initialization completes; return NULL
* ARP cache found percentage.
*
* (3) These ARP statistics calculation(s) are potentially expensive operations. Recommended
* only from low-priority, background tasks.
*********************************************************************************************************
*/
CPU_INT08U NetARP_CacheCalcStat (void)
{
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
CPU_SR cpu_sr;
#endif
NET_CTR pct_numer_hi;
NET_CTR pct_numer_lo;
NET_CTR pct_denom_hi;
NET_CTR pct_denom_lo;
#endif
CPU_INT08U pct;
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (Net_InitDone != DEF_YES) { /* If init NOT complete, ... */
return (0); /* ... rtn NULL pct (see Note #2). */
}
#endif
/* ------------- CALC ARP CACHE FOUND PCT ------------- */
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
CPU_CRITICAL_ENTER();
pct_numer_hi = NetARP_CacheFoundCtr_hi;
pct_numer_lo = NetARP_CacheFoundCtr_lo;
pct_denom_hi = NetARP_CacheSrchCtr_hi;
pct_denom_lo = NetARP_CacheSrchCtr_lo;
CPU_CRITICAL_EXIT();
pct = NetCtr_CalcPctLarge(pct_numer_hi,
pct_numer_lo,
pct_denom_hi,
pct_denom_lo);
CPU_CRITICAL_ENTER();
NetARP_CacheFoundPct = pct;
CPU_CRITICAL_EXIT();
#else
pct = 0;
#endif
return (pct);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetARP_CacheGetAddrHW()
*
* Description : (1) Get hardware address that corresponds to a specific ARP cache's protocol address :
*
* (a) Search ARP Cache List for ARP cache with desired protocol address
* (b) If corresponding ARP cache found, get/return hardware address
*
*
* Argument(s) : paddr_hw Pointer to a memory buffer that will receive the hardware address :
* (see Notes #2a & 3a) :
*
* Hardware address that corresponds to the desired protocol address,
* if NO errors.
*
* Hardware address cleared to all zeros (see Note #2a3), otherwise.
*
* addr_hw_len_buf Length of hardware address memory buffer (in octets) [see Note #2a1].
*
* paddr_protocol Pointer to the specific protocol address to search for corresponding
* hardware address (see Note #3b).
*
* addr_protocol_len Length of protocol address (in octets) [see Note #2b].
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ARP_ERR_NONE Hardware address successfully returned.
* NET_ARP_ERR_CACHE_NOT_FOUND ARP cache with corresponding hardware/protocol
* address NOT found.
* NET_ARP_ERR_CACHE_PEND ARP cache in 'PENDING' state; hardware address
* NOT yet resolved (see Note #4).
*
* NET_ARP_ERR_NULL_PTR Argument(s) 'paddr_hw'/'paddr_protocol' passed
* a NULL pointer.
* NET_ARP_ERR_INVALID_HW_LEN Invalid ARP hardware address length.
* NET_ARP_ERR_INVALID_PROTOCOL_LEN Invalid ARP protocol address length.
*
* Return(s) : Length of returned hardware address (see Note #2a2), if available.
*
* 0, otherwise.
*
* Caller(s) : Application.
*
* This function is a network protocol suite application interface (API) function & MAY be
* called by application function(s).
*
* Note(s) : (2) (a) (1) The size of the memory buffer that will receive the returned hardware address
* MUST be greater than or equal to NET_ARP_CFG_HW_ADDR_LEN.
*
* (2) The length of any returned hardware address is equal to NET_ARP_CFG_HW_ADDR_LEN.
*
* (3) Address memory array cleared in case of any error(s).
*
* (A) Address memory array SHOULD be initialized to return a NULL address PRIOR
* to all other validation or function handling in case of any error(s).
*
* (b) The length of the protocol address MUST be equal to NET_ARP_CFG_PROTOCOL_ADDR_LEN
* & is included for correctness & completeness.
*
* (3) ARP addresses MUST be in network-order :
*
* (a) 'paddr_hw' hardware address returned in network-order
* (b) 'paddr_protocol' MUST point to a protocol address that is in network-order
*
* See also 'NetARP_CacheHandler() Note #2e3'.
*
* (4) While an ARP cache is in 'PENDING' state the hardware address is NOT yet resolved,
* but MAY be resolved in the near future by an awaited ARP Reply.
*********************************************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -