📄 net_arp.c
字号:
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
NET_CTR *pctr;
#endif
NET_BUF_HDR *pbuf_hdr;
NET_ARP_HDR *parp_hdr;
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit rx (see Note #2). */
NetARP_RxPktDiscard(pbuf, perr);
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#endif
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------------- VALIDATE PTR ------------------- */
if (pbuf == (NET_BUF *)0) {
NetARP_RxPktDiscard(pbuf, perr);
NET_CTR_ERR_INC(NetARP_ErrNullPtrCtr);
return;
}
#endif
NET_CTR_STAT_INC(NetARP_StatRxPktCtr);
/* ----------------- VALIDATE ARP PKT ----------------- */
pbuf_hdr = &pbuf->Hdr;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
NetARP_RxPktValidateBuf(pbuf_hdr, perr); /* Validate rx'd buf. */
switch (*perr) {
case NET_ARP_ERR_NONE:
break;
case NET_ERR_INVALID_PROTOCOL:
case NET_BUF_ERR_INVALID_IX:
default:
NetARP_RxPktDiscard(pbuf, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
#endif
parp_hdr = (NET_ARP_HDR *)&pbuf->Data[pbuf_hdr->ARP_MsgIx];
NetARP_RxPktValidate(pbuf_hdr, parp_hdr, perr); /* Validate rx'd pkt. */
/*$PAGE*/
/* ----------------- UPDATE ARP CACHE ----------------- */
switch (*perr) { /* Chk err from NetARP_RxPktValidate(). */
case NET_ARP_ERR_NONE:
NetARP_RxPktCacheUpdate(parp_hdr, perr);
break;
case NET_ARP_ERR_INVALID_HW_TYPE:
case NET_ARP_ERR_INVALID_HW_LEN:
case NET_ARP_ERR_INVALID_HW_ADDR:
case NET_ARP_ERR_INVALID_PROTOCOL_TYPE:
case NET_ARP_ERR_INVALID_PROTOCOL_LEN:
case NET_ARP_ERR_INVALID_PROTOCOL_ADDR:
case NET_ARP_ERR_INVALID_OP_CODE:
case NET_ARP_ERR_INVALID_OP_ADDR:
case NET_ARP_ERR_INVALID_LEN_MSG:
default:
NetARP_RxPktDiscard(pbuf, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
/* ------------------- TX ARP REPLY ------------------- */
switch (*perr) { /* Chk err from NetARP_RxPktCacheUpdate(). */
case NET_ARP_ERR_CACHE_RESOLVED:
NetARP_RxPktReply(parp_hdr, perr);
break;
case NET_ARP_ERR_CACHE_NONE_AVAIL:
case NET_ARP_ERR_CACHE_INVALID_TYPE:
case NET_ARP_ERR_INVALID_OP_CODE:
case NET_ARP_ERR_RX_TARGET_REPLY:
case NET_ARP_ERR_RX_TARGET_NOT_THIS_HOST:
case NET_TMR_ERR_NULL_OBJ:
case NET_TMR_ERR_NULL_FNCT:
case NET_TMR_ERR_NONE_AVAIL:
case NET_TMR_ERR_INVALID_TYPE:
default:
NetARP_RxPktDiscard(pbuf, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
/* ---------- FREE ARP PKT / UPDATE RX STATS ---------- */
switch (*perr) { /* Chk err from NetARP_RxPktReply(). */
case NET_ARP_ERR_RX_REQ_TX_REPLY:
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
pctr = &NetARP_StatRxMsgReqProcessedCtr;
#endif
break;
case NET_ARP_ERR_RX_REPLY_TX_PKTS:
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
pctr = &NetARP_StatRxMsgReplyProcessedCtr;
#endif
break;
case NET_ARP_ERR_INVALID_OP_CODE:
case NET_ARP_ERR_RX_TARGET_NOT_THIS_HOST:
default:
NetARP_RxPktDiscard(pbuf, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
NetARP_RxPktFree(pbuf);
NET_CTR_STAT_INC(NetARP_StatRxMsgProcessedCtr);
NET_CTR_STAT_INC(*pctr);
*perr = NET_ARP_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetARP_CacheHandler()
*
* Description : (1) Resolve destination hardware address for transmit data packet :
*
* (a) Search ARP Cache List
* (b) If ARP cache found, handle packet based on ARP cache state :
*
* (1) PENDING -> Enqueue transmit packet buffer to ARP cache
* (2) RESOLVED -> Copy ARP cache's hardware address to data packet;
* Return to Network Interface to transmit data packet
*
* (c) If ARP cache NOT found, allocate new ARP cache in 'PENDING' state (see Note #1b1)
*
* See 'net_arp.h ARP CACHE STATES' for ARP cache state diagram.
*
* (2) This ARP cache handler function assumes the following :
*
* (a) ALL ARP caches in the ARP Cache List are valid [validated by NetARP_CacheGet()]
* (b) ANY ARP cache in the 'PENDING' state has already enqueued at LEAST one transmit
* packet buffer when ARP cache allocated [see NetARP_CacheGet()]
* (c) ALL ARP caches in the 'RESOLVED' state have valid hardware addresses
* (d) ALL transmit buffers enqueued on any ARP cache are valid
* (e) Buffer's ARP address pointers pre-configured by Network Interface to point to :
*
* (1) 'ARP_AddrProtocolPtr' Pointer to the protocol address used to
* resolve the hardware address
* (2) 'ARP_AddrHW_Ptr' Pointer to memory buffer to return the
* resolved hardware address
* (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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -