📄 net_arp.c
字号:
* NET_ARP_ERR_INVALID_OP_ADDR Invalid address for ARP operation
* (see Note #3).
* NET_ARP_ERR_INVALID_LEN_MSG Invalid ARP message length
* (see Note #1d).
*
* Return(s) : none.
*
* Caller(s) : NetARP_Rx().
*
* Note(s) : (2) See RFC #826, Section 'Packet Format' for ARP packet header format.
*
* (3) (a) An ARP Request SHOULD be transmitted onto the network by broadcast (see RFC #826,
* Section 'Packet Generation'). Therefore, any ARP Request NOT received as a broadcast
* packet SHOULD be discarded.
*
* (b) An ARP Reply SHOULD be transmitted directly to the ARP-Requesting host (see RFC #826,
* Section 'Packet Reception' algorithm) & SHOULD NOT be broadcast onto the network.
* Therefore, any ARP Reply received as a broadcast packet SHOULD be discarded.
*********************************************************************************************************
*/
/*$PAGE*/
static void NetARP_RxPktValidate (NET_BUF_HDR *pbuf_hdr,
NET_ARP_HDR *parp_hdr,
NET_ERR *perr)
{
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
CPU_INT16U hw_type;
CPU_INT16U protocol_type;
CPU_INT16U op_code;
CPU_BOOLEAN rx_broadcast;
CPU_BOOLEAN valid;
/* ------------ VALIDATE ARP HW TYPE/ADDR ------------- */
NET_UTIL_VAL_COPY_GET_NET_16(&hw_type, &parp_hdr->HW_Type);
if (hw_type != NET_ARP_CFG_HW_TYPE) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrHW_TypeCtr);
*perr = NET_ARP_ERR_INVALID_HW_TYPE;
return;
}
if (parp_hdr->HW_AddrLen != NET_ARP_CFG_HW_ADDR_LEN) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrHW_AddrLenCtr);
*perr = NET_ARP_ERR_INVALID_HW_LEN;
return;
}
valid = NetARP_IsValidAddrHW(&parp_hdr->HW_AddrSender[0]);
if (valid != DEF_YES) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrHW_AddrCtr);
*perr = NET_ARP_ERR_INVALID_HW_ADDR;
return;
}
/* --------- VALIDATE ARP PROTOCOL TYPE/ADDR ---------- */
NET_UTIL_VAL_COPY_GET_NET_16(&protocol_type, &parp_hdr->ProtocolType);
if (protocol_type != NET_ARP_CFG_PROTOCOL_TYPE) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrProtocolTypeCtr);
*perr = NET_ARP_ERR_INVALID_PROTOCOL_TYPE;
return;
}
if (parp_hdr->ProtocolAddrLen != NET_ARP_CFG_PROTOCOL_ADDR_LEN) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrProtocolAddrLenCtr);
*perr = NET_ARP_ERR_INVALID_PROTOCOL_LEN;
return;
}
valid = NetARP_IsValidAddrProtocol(&parp_hdr->ProtocolAddrSender[0]);
if (valid != DEF_YES) {
NET_CTR_ERR_INC(NetARP_ErrRxHdrProtocolAddrCtr);
*perr = NET_ARP_ERR_INVALID_PROTOCOL_ADDR;
return;
}
/* --------------- VALIDATE ARP OP CODE --------------- */
NET_UTIL_VAL_COPY_GET_NET_16(&op_code, &parp_hdr->OpCode);
rx_broadcast = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_RX);
switch (op_code) {
case NET_ARP_HDR_OP_REQ:
if (rx_broadcast != DEF_YES) { /* See Note #3a. */
NET_CTR_ERR_INC(NetARP_ErrRxHdrOpAddrCtr);
*perr = NET_ARP_ERR_INVALID_OP_ADDR;
return;
}
break;
case NET_ARP_HDR_OP_REPLY:
if (rx_broadcast != DEF_NO) { /* See Note #3b. */
NET_CTR_ERR_INC(NetARP_ErrRxHdrOpAddrCtr);
*perr = NET_ARP_ERR_INVALID_OP_ADDR;
return;
}
break;
default:
NET_CTR_ERR_INC(NetARP_ErrRxHdrOpCodeCtr);
*perr = NET_ARP_ERR_INVALID_OP_CODE;
return; /* Prevent 'break NOT reachable' compiler warning. */
}
/*$PAGE*/
/* ----- UPDATE BUF CTRLS / VALIDATE ARP MSG LEN ------ */
pbuf_hdr->ARP_MsgLen = NET_ARP_HDR_SIZE;
if (pbuf_hdr->ARP_MsgLen >= pbuf_hdr->IF_DataLenMin) { /* If ARP msg len >= min net IF data size & .. */
if (pbuf_hdr->ARP_MsgLen != pbuf_hdr->DataLen) { /* .. ARP msg len != rem pkt len, .. */
NET_CTR_ERR_INC(NetARP_ErrRxHdrMsgLenCtr);
*perr = NET_ARP_ERR_INVALID_LEN_MSG; /* .. rtn err (see Note #1d). */
return;
}
}
pbuf_hdr->DataLen -= (NET_BUF_SIZE)pbuf_hdr->ARP_MsgLen;
*perr = NET_ARP_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetARP_RxPktCacheUpdate()
*
* Description : (1) Update an ARP cache based on received ARP packet's sender addresses :
*
* (a) Verify ARP message's intended target address is this host
* (b) Search ARP Cache List
* (c) Update ARP cache
*
*
* Argument(s) : parp_hdr Pointer to received packet's ARP header.
* -------- Argument validated in NetARP_Rx().
*
* 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_RX_TARGET_REPLY ARP Reply received but NO corresponding ARP
* cache currently pending for ARP Reply.
*
* --- RETURNED BY NetARP_CacheAddResolved() : ----
* 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.
*
* - RETURNED BY NetARP_RxPktIsTargetThisHost() : -
* NET_ARP_ERR_RX_TARGET_NOT_THIS_HOST Received ARP message NOT intended for this host.
* NET_ARP_ERR_INVALID_OP_CODE Invalid ARP operation code.
*
* Return(s) : none.
*
* Caller(s) : NetARP_Rx().
*
* Note(s) : (2) The ARP cache algorithm implies that ALL messages received at the ARP layer automatically
* update the ARP Cache List EVEN if this host is NOT the intended target host of a received
* ARP message -- but ONLY if an ARP cache for the sender's addresses is already cached (see
* RFC #826, Section 'Packet Reception'). However, if NO ARP cache exists for the sender's
* addresses, then even the ARP cache algorithm implies that a misdirected or incorrectly
* received ARP message is discarded.
*
* A configurable ARP address filtering feature is provided to selectively filter & discard
* ALL misdirected or incorrectly received ARP messages (see 'net_cfg.h ADDRESS RESOLUTION
* PROTOCOL LAYER CONFIGURATION').
*
* (a) When ENABLED, the ARP address filter discards ...
*
* (1) ALL misdirected or incorrectly received ARP messages.
*
* (2) Any ARP Reply received for this host for which NO corresponding ARP cache currently
* exists. (Note : Such an ARP Reply may be a legitimate, yet late, ARP Reply to a
* pending ARP Request that has timed-out & been removed from the ARP Cache List.)
*
* (b) When DISABLED, the ARP address filter discards any misdirected or incorrectly received
* ARP messages where the sender's addresses are NOT already cached.
*
* (3) (a) RFC # 826, Section 'Related issue' states that "perhaps receiving of a packet from a
* host should reset a timeout in the address resolution entry".
*
* (b) RFC #1122, Section 2.3.2.1 affirms "that this timeout should be restarted when the
* cache entry is 'refreshed'".
*********************************************************************************************************
*/
static void NetARP_RxPktCacheUpdate (NET_ARP_HDR *parp_hdr,
NET_ERR *perr)
{
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
#if (NET_ARP_CFG_ADDR_FLTR_EN == DEF_ENABLED)
CPU_INT16U op_code;
#else
CPU_BOOLEAN cache_add;
#endif
CPU_INT08U *paddr_sender_hw;
CPU_INT08U *paddr_sender_protocol;
NET_ARP_CACHE *pcache;
NET_BUF *pbuf_head;
/*$PAGE*/
/* ----------------- CHK TARGET ADDR ------------------ */
NetARP_RxPktIsTargetThisHost(parp_hdr, perr);
#if (NET_ARP_CFG_ADDR_FLTR_EN == DEF_ENABLED)
if (*perr != NET_ARP_ERR_RX_TARGET_THIS_HOST) { /* See Note #2a1. */
NET_CTR_ERR_INC(NetARP_ErrRxPktTargetNotThisHostCtr);
return;
}
#else
cache_add = (*perr == NET_ARP_ERR_RX_TARGET_THIS_HOST) ? DEF_YES : DEF_NO;
#endif
/* ------------------ SRCH ARP CACHE ------------------ */
paddr_sender_hw = parp_hdr->HW_AddrSender;
paddr_sender_protocol = parp_hdr->ProtocolAddrSender;
pcache = NetARP_CacheSrch(paddr_sender_protocol);
/* ----------------- UPDATE ARP CACHE ----------------- */
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, add sender's hw addr, ... */
Mem_Copy((void *)&pcache->HW_Addr[0],
(void *) paddr_sender_hw,
(CPU_SIZE_T) NET_ARP_CFG_HW_ADDR_LEN);
NetTmr_Set((NET_TMR *)pcache->TmrPtr, /* See Note #3. */
(CPU_FNCT_PTR)NetARP_CacheTimeout,
(NET_TMR_TICK)NetARP_CacheTimeout_tick,
(NET_ERR *)perr);
pbuf_head = pcache->BufQ_Head;
pcache->BufQ_Head = (NET_BUF *)0;
pcache->BufQ_Tail = (NET_BUF *)0;
NetARP_CacheTxPktHandler(pbuf_head, /* ... & handle/tx cache's buf Q. */
paddr_sender_hw);
pcache->State = NET_ARP_CACHE_STATE_RESOLVED;
*perr = NET_ARP_ERR_CACHE_RESOLVED;
break;
case NET_ARP_CACHE_STATE_RESOLVED: /* If ARP cache resolved, update sender's hw addr. */
Mem_Copy((void *)&pcache->HW_Addr[0],
(void *) paddr_sender_hw,
(CPU_SIZE_T) NET_ARP_CFG_HW_ADDR_LEN);
NetTmr_Set((NET_TMR *)pcache->TmrPtr, /* See Note #3. */
(CPU_FNCT_PTR)NetARP_CacheTimeout,
(NET_TMR_TICK)NetARP_CacheTimeout_tick,
(NET_ERR *)perr);
*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_CacheAddResolved(paddr_sender_hw, paddr_sender_protocol, perr);
break;
}
} else { /* Else add new ARP cache into ARP Cache List. */
#if (NET_ARP_CFG_ADDR_FLTR_EN == DEF_ENABLED) /* See Note #2a2. */
NET_UTIL_VAL_COPY_GET_NET_16(&op_code, &parp_hdr->OpCode);
if (op_code != NET_ARP_HDR_OP_REQ) {
NET_CTR_ERR_INC(NetARP_ErrRxPktTargetReplyCtr);
*perr = NET_ARP_ERR_RX_TARGET_REPLY;
return;
}
#else /* See Note #2b. */
if (cache_add != DEF_YES) {
NET_CTR_ERR_INC(NetARP_ErrRxPktTargetNotThisHostCtr);
return; /* Err rtn'd by NetARP_RxPktIsTargetThisHost(). */
}
#endif
NetARP_CacheAddResolved(paddr_sender_hw, paddr_sender_protocol, perr);
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetARP_RxPktRepl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -