📄 net_if.c
字号:
#else
pctr = (NET_CTR *) 0;
#endif
NetBuf_FreeBuf((NET_BUF *)pbuf,
(NET_CTR *)pctr);
*perr = NET_ERR_RX;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetIF_TxPktHandler()
*
* Description : Transmit data packets via network interface layer.
*
* Argument(s) : pbuf_q Pointer to network buffer list with data packet(s) to transmit.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Tx(),
* NetARP_RxPktCacheUpdate().
*
* Note(s) : none.
*********************************************************************************************************
*/
static void NetIF_TxPktHandler (NET_BUF *pbuf_q)
{
NET_BUF *pbuf_list;
NET_BUF *pbuf_list_next;
NET_BUF *pbuf;
NET_BUF *pbuf_next;
NET_BUF_HDR *pbuf_hdr;
NET_ERR err;
pbuf_list = pbuf_q;
while (pbuf_list != (NET_BUF *)0) { /* Tx ALL buf lists in Q. */
pbuf_hdr = &pbuf_list->Hdr;
pbuf_list_next = (NET_BUF *)pbuf_hdr->NextSecListPtr;
pbuf = (NET_BUF *)pbuf_list;
while (pbuf != (NET_BUF *)0) { /* Tx ALL bufs in buf list. */
pbuf_hdr = &pbuf->Hdr;
pbuf_next = (NET_BUF *)pbuf_hdr->NextBufPtr;
NetIF_TxPkt(pbuf, &err); /* Tx pkt to IF. */
pbuf = pbuf_next;
}
pbuf_list = pbuf_list_next;
}
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetIF_TxPktValidate()
*
* Description : (1) Validate IF transmit packet parameters :
*
* (a) Packets with the following invalid parameters will be "silently discarded" :
*
* (1) Protocols other than supported protocols :
* (A) ARP
* (B) IP
*
* (2) Total Length
*
*
* Argument(s) : pbuf Pointer to network buffer to transmit IF packet.
* ---- Argument checked in NetIF_Tx().
*
* pbuf_hdr Pointer to network buffer header.
* -------- Argument validated in NetIF_Tx().
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_IF_ERR_NONE Transmit packet validated.
* NET_ERR_INVALID_PROTOCOL Invalid/unknown protocol type.
* NET_BUF_ERR_INVALID_IX Invalid or insufficient buffer index.
* NET_IF_ERR_INVALID_LEN_DATA Invalid protocol/data length.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Tx().
*
* Note(s) : none.
*********************************************************************************************************
*/
/*$PAGE*/
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
static void NetIF_TxPktValidate (NET_BUF *pbuf,
NET_BUF_HDR *pbuf_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 ix;
CPU_INT16U len;
/* ----------------- VALIDATE PROTOCOL ---------------- */
switch (pbuf_hdr->ProtocolHdrType) {
case NET_PROTOCOL_TYPE_ARP:
ix = pbuf_hdr->ARP_MsgIx;
len = pbuf_hdr->ARP_MsgLen;
break;
case NET_PROTOCOL_TYPE_IP:
ix = pbuf_hdr->IP_HdrIx;
len = pbuf_hdr->IP_TotLen;
break;
case NET_PROTOCOL_TYPE_NONE:
default:
NET_CTR_ERR_INC(NetIF_ErrTxProtocolCtr);
*perr = NET_ERR_INVALID_PROTOCOL;
return; /* Prevent 'break NOT reachable' compiler warning. */
}
if (ix == NET_BUF_IX_NONE) {
NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr);
*perr = NET_BUF_ERR_INVALID_IX;
return;
}
if (ix < NET_IF_HDR_SIZE_MAX) {
NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr);
*perr = NET_BUF_ERR_INVALID_IX;
return;
}
/* -------------- VALIDATE TOT DATA LEN --------------- */
if (len != pbuf_hdr->TotLen) {
NET_CTR_ERR_INC(NetIF_ErrTxHdrDataLenCtr);
*perr = NET_IF_ERR_INVALID_LEN_DATA;
return;
}
*perr = NET_IF_ERR_NONE;
}
#endif
/*$PAGE*/
/*
*********************************************************************************************************
* NetIF_TxPktPrepareFrame()
*
* Description : (1) Prepare data packet with Ethernet frame format :
*
* (a) Demultiplex Ethernet frame type
* (b) Update buffer controls
* (c) Write Ethernet values into packet frame
* (1) Ethernet destination broadcast address, if necessary
* (2) Ethernet source MAC address
* (3) Ethernet frame type
* (d) Clear Ethernet frame pad octets, if any
*
*
* Argument(s) : pbuf Pointer to network buffer with data packet to encapsulate.
* ---- Argument checked in NetIF_Tx().
*
* pbuf_hdr Pointer to network buffer header.
* -------- Argument validated in NetIF_Tx().
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_IF_ERR_TX_BROADCAST Ethernet frame successfully prepared for
* Ethernet broadcast on local network.
* NET_IF_ERR_TX_ARP Ethernet frame successfully prepared &
* requires ARP hardware address binding.
* NET_ERR_INVALID_PROTOCOL Invalid network protocol.
* NET_BUF_ERR_INVALID_IX Invalid or insufficient buffer index.
* NET_BUF_ERR_INVALID_LEN Insufficient buffer length.
*
* Return(s) : none.
*
* Caller(s) : NetIF_Tx().
*
* Note(s) : (2) Supports ONLY Ethernet frame format for network transmit (see 'net_if.c Note #2a').
*
* (3) Supports ONLY ARP & IP protocols (see 'net.h Note #1a').
*
* (4) To prepare the packet buffer for ARP resolution, the buffer's ARP protocol address
* pointer needs to be configured to the appropriate outbound address :
*
* (a) For ARP packets, the ARP layer will configure the ARP protocol address pointer
* (see 'net_arp.c NetARP_TxPktPrepareHdr() Note #1d').
*
* (b) For IP packets, configure the ARP protocol address pointer to the IP's next-
* hop address.
*
* (5) RFC #894, Section 'Frame Format' states :
*
* (a) "The minimum length of the data field of a packet sent over an Ethernet is 46
* octets."
*
* (b) (1) "If necessary, the data field should be padded (with octets of zero) to
* meet the Ethernet minimum frame size."
* (2) "This padding is not part of the IP packet and is not included in the
* total length field of the IP header."
*********************************************************************************************************
*/
static void NetIF_TxPktPrepareFrame (NET_BUF *pbuf,
NET_BUF_HDR *pbuf_hdr,
NET_ERR *perr)
{
#if (((NET_CTR_CFG_STAT_EN == DEF_ENABLED) || \
(NET_CTR_CFG_ERR_EN == DEF_ENABLED)) && \
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
CPU_SR cpu_sr;
#endif
NET_IF_HDR_ETHER *pif_hdr_ether;
CPU_INT16U protocol_ix;
CPU_INT16U frame_type;
CPU_INT16U clr_ix;
CPU_INT16U clr_len;
CPU_INT16U clr_size;
CPU_BOOLEAN clr_buf_mem;
CPU_BOOLEAN tx_broadcast;
/*$PAGE*/
/* ----------------- DEMUX FRAME TYPE ----------------- */
switch (pbuf_hdr->ProtocolHdrType) { /* Demux protocol for frame type (see Note #3). */
case NET_PROTOCOL_TYPE_ARP:
protocol_ix = pbuf_hdr->ARP_MsgIx;
frame_type = NET_IF_FRAME_ETHER_TYPE_ARP;
break;
case NET_PROTOCOL_TYPE_IP:
protocol_ix = pbuf_hdr->IP_HdrIx;
frame_type = NET_IF_FRAME_ETHER_TYPE_IP;
/* Cfg ARP addr ptr (see Note #4b). */
pbuf_hdr->ARP_AddrProtocolPtr = (CPU_INT08U *)&pbuf_hdr->IP_AddrNextHopNetOrder;
break;
case NET_PROTOCOL_TYPE_NONE:
default:
NET_CTR_ERR_INC(NetIF_ErrInvalidProtocolCtr);
*perr = NET_ERR_INVALID_PROTOCOL;
return; /* Prevent 'break NOT reachable' compiler warning. */
}
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------- VALIDATE IX -------------- */
if (protocol_ix == NET_BUF_IX_NONE) {
NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr);
*perr = NET_BUF_ERR_INVALID_IX;
return;
}
if (protocol_ix < NET_IF_HDR_SIZE_MAX) {
NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr);
*perr = NET_BUF_ERR_INVALID_IX;
return;
}
#endif
/* ----------- UPDATE BUF CTRLS ----------- */
pbuf_hdr->IF_HdrLen = NET_IF_FRAME_HDR_SIZE_ETHER;
pbuf_hdr->IF_HdrIx = protocol_ix - pbuf_hdr->IF_HdrLen;
pbuf_hdr->TotLen += (NET_BUF_SIZE) pbuf_hdr->IF_HdrLen;
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_FRAME;
/* --------- PREPARE ETHER FRAME ---------- */
pif_hdr_ether = (NET_IF_HDR_ETHER *)&pbuf->Data[pbuf_hdr->IF_HdrIx];
/* --------- PREPARE FRAME ADDRS ---------- */
tx_broadcast = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_TX);
if (tx_broadcast == DEF_YES) { /* If dest addr broadcast, ... */
Mem_Copy((void *)&pif_hdr_ether->AddrDest[0], /* .. wr broadcast addr into frame. */
(void *)&NetIF_AddrBroadcast[0],
(CPU_SIZE_T) NET_IF_ADDR_SIZE);
NET_CTR_STAT_INC(NetIF_StatTxPktBroadcastCtr);
*perr = NET_IF_ERR_TX_BROADCAST;
} else { /* Else req ARP hw addr binding. */
pbuf_hdr->ARP_AddrHW_Ptr = (void *)&pif_hdr_ether->AddrDest[0];
*perr = NET_IF_ERR_TX_ARP;
}
Mem_Copy((void *)&pif_hdr_ether->AddrSrc[0], /* Wr src addr into frame. */
(void *)&NetIF_MAC_Addr[0],
(CPU_SIZE_T) NET_IF_ADDR_SIZE);
/* ---------- PREPARE FRAME TYPE ---------- */
NET_UTIL_VAL_COPY_SET_NET_16(&pif_hdr_ether->FrameType, &frame_type);
/* --------- CLR/PAD FRAME OCTETS --------- */
if (pbuf_hdr->TotLen < NET_IF_FRAME_MIN_SIZE) { /* If tot len < min frame len (see Note #5a)*/
clr_buf_mem = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_CLR_MEM);
if (clr_buf_mem != DEF_YES) { /* ... & buf mem NOT clr, ... */
clr_ix = pbuf_hdr->IF_HdrIx + (CPU_INT16U)pbuf_hdr->TotLen;
clr_len = NET_IF_FRA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -