📄 net_udp.c
字号:
* (4) (a) UDP header Check-Sum field MUST be validated BEFORE (or AFTER) any multi-octet words
* are converted from network-order to host-order since "the sum of 16-bit integers can
* be computed in either byte order" [RFC #1071, Section 2.(B)].
*
* In other words, the UDP Datagram Check-Sum CANNOT be validated AFTER SOME but NOT ALL
* multi-octet words have been converted from network-order to host-order.
*
* (b) However, ALL received packets' multi-octet words are converted in local or network
* buffer variables ONLY (see Note #1bA). Therefore, UDP Datagram Check-Sum may be
* validated at any point.
*
* (c) The UDP Datagram Check-Sum MUST be validated AFTER the datagram length field has been
* validated so that the total UDP Datagram Length (in octets) will already be calculated
* for the UDP Check-Sum calculation.
*
* For efficiency, the UDP Datagram Check-Sum is validated AFTER all other UDP header
* fields have been validated. Thus, the iteration-intensive UDP Datagram Check-Sum is
* calculated only after all other UDP header fields have been quickly validated.
*
* (d) (1) Before the UDP Datagram Check-Sum is validated, it is necessary to convert the
* Check-Sum from network-order to host-order to verify whether the received UDP
* datagram's Check-Sum is valid -- i.e. whether the UDP datagram was transmitted
* with or without a computed Check-Sum (see RFC #768, Section 'Fields : Checksum').
*
* (2) Since the value that indicates no check-sum was computed for the received UDP
* datagram is one's-complement positive zero -- all check-sum bits equal to zero,
* a value that is endian-order independent -- it is NOT absolutely necessary to
* convert the UDP Datagram Check-Sum from network-order to host-order.
*
* However, network data value macro's inherently convert data words from network
* word order to CPU word order.
*
* See also 'net_util.h NETWORK DATA VALUE MACRO'S Note #1a1'.
*
* (3) (A) Any UDP datagram received with NO computed check-sum is flagged so that "an
* application MAY optionally ... discard ... datagrams without checksums" (see
* RFC #1122, Section 4.1.3.4).
*
* (B) UDP buffer flag value to clear was previously initialized in NetBuf_Get() when
* the buffer was allocated. This buffer flag value does NOT need to be re-cleared
* but is shown for completeness.
*
* (e) (1) In addition to the UDP datagram header & data, the UDP Check-Sum calculation
* includes "a pseudo header of information from the IP header ... conceptually
* prefixed to the UDP header [which] contains the source address, the destination
* address, the protocol, and the UDP length" (see RFC #768, Section 'Fields :
* Checksum').
*
* (2) Since network check-sum functions REQUIRE that 16-bit one's-complement check-
* sum calculations be performed on headers & data arranged in network-order (see
* 'net_util.c NetUtil_16BitOnesCplChkSumDataVerify() Note #4'), UDP pseudo-header
* values MUST be set or converted to network-order.
*
* (f) RFC #768, Section 'Fields : Checksum' specifies that "the data [is] padded with zero
* octets at the end (if necessary) to make a multiple of two octets".
*
* See also 'net_util.c NetUtil_16BitSumDataCalc() Note #8'.
*
* (5) (a) Since the minimum network buffer size MUST be configured such that the entire UDP
* header MUST be received in a single packet (see 'net_buf.h NETWORK BUFFER INDEX &
* SIZE DEFINES Note #1c'), after the UDP header size is decremented from the first
* packet buffer's remaining number of data octets, any remaining octets MUST be user
* &/or application data octets.
*
* (1) Note that the 'Data' index is updated regardless of a null-size data length.
*
* (b) If additional packet buffers exist, the remaining IP datagram 'Data' MUST be user
* &/or application data. Therefore, the 'Data' length does NOT need to be adjusted
* but the 'Data' index MUST be updated.
*
* (c) #### Total UDP Datagram Length & Data Length is duplicated in ALL fragmented packet
* buffers (may NOT be necessary; remove if unnecessary).
*
* (6) RFC #1122, Sections 3.2.1 & 3.2.2 require that IP & ICMP packets with certain invalid
* header fields be "silently discarded". However, NO RFC specifies how UDP should handle
* received datagrams with invalid header fields.
*
* In addition, UDP is a "transaction oriented" protocol that does NOT guarantee "delivery
* and duplicate protection" of UDP datagrams (see RFC #768, Section 'Introduction').
*
* Therefore, it is assumed that ALL UDP datagrams with ANY invalid header fields SHOULD
* be silently discarded.
*********************************************************************************************************
*/
/*$PAGE*/
static void NetUDP_RxPktValidate (NET_BUF *pbuf,
NET_BUF_HDR *pbuf_hdr,
NET_UDP_HDR *pudp_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 udp_tot_len;
CPU_INT16U udp_data_len;
NET_CHK_SUM udp_chk_sum;
CPU_BOOLEAN udp_chk_sum_valid;
NET_UDP_PSEUDO_HDR udp_pseudo_hdr;
NET_BUF *pbuf_next;
NET_BUF_HDR *pbuf_next_hdr;
/* ---------------- VALIDATE UDP PORTS ---------------- */
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->TCP_UDP_PortSrc, &pudp_hdr->PortSrc);
if (pbuf_hdr->TCP_UDP_PortSrc == NET_UDP_PORT_NBR_RESERVED) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrPortSrcCtr);
*perr = NET_UDP_ERR_INVALID_PORT_NBR;
return;
}
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->TCP_UDP_PortDest, &pudp_hdr->PortDest);
if (pbuf_hdr->TCP_UDP_PortDest == NET_UDP_PORT_NBR_RESERVED) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrPortDestCtr);
*perr = NET_UDP_ERR_INVALID_PORT_NBR;
return;
}
/* ------------ VALIDATE UDP DATAGRAM LEN ------------- */
/* See Note #3. */
NET_UTIL_VAL_COPY_GET_NET_16(&udp_tot_len, &pudp_hdr->DatagramLen);
pbuf_hdr->TCP_UDP_TotLen = udp_tot_len;
if (pbuf_hdr->TCP_UDP_TotLen < NET_UDP_TOT_LEN_MIN) { /* If datagram len < min tot len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
if (pbuf_hdr->TCP_UDP_TotLen > NET_UDP_TOT_LEN_MAX) { /* If datagram len > max tot len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
if (pbuf_hdr->TCP_UDP_TotLen != pbuf_hdr->IP_DatagramLen) { /* If datagram len != IP datagram len, rtn err. */
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDatagramLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN;
return;
}
/*$PAGE*/
/* --------------- VALIDATE UDP CHK SUM --------------- */
/* See Note #4. */
NET_UTIL_VAL_COPY_GET_NET_16(&udp_chk_sum, &pudp_hdr->ChkSum);
if (udp_chk_sum != NET_UDP_HDR_CHK_SUM_NONE) { /* If chk sum rx'd, verify chk sum (see Note #4d). */
/* Prepare UDP chk sum pseudo-hdr (see Note #4e). */
udp_pseudo_hdr.AddrSrc = (NET_IP_ADDR)NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrSrc);
udp_pseudo_hdr.AddrDest = (NET_IP_ADDR)NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrDest);
udp_pseudo_hdr.Zero = (CPU_INT08U )0x00;
udp_pseudo_hdr.Protocol = (CPU_INT08U )NET_IP_HDR_PROTOCOL_UDP;
udp_pseudo_hdr.DatagramLen = (CPU_INT16U )NET_UTIL_HOST_TO_NET_16(pbuf_hdr->TCP_UDP_TotLen);
udp_chk_sum_valid = NetUtil_16BitOnesCplChkSumDataVerify((void *) pbuf,
(void *)&udp_pseudo_hdr,
(CPU_INT16U) NET_UDP_PSEUDO_HDR_SIZE,
(NET_ERR *) perr);
if (udp_chk_sum_valid != DEF_OK) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrChkSumCtr);
*perr = NET_UDP_ERR_INVALID_CHK_SUM;
return;
}
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_UDP_RX_CHK_SUM_VALID);
} else { /* Else discard or flag NO rx'd chk sum (see Note #4d3).*/
#if (NET_UDP_CFG_RX_CHK_SUM_DISCARD_EN != DEF_DISABLED)
NET_CTR_ERR_INC(NetUDP_ErrRxHdrChkSumCtr);
*perr = NET_UDP_ERR_INVALID_CHK_SUM;
return;
#endif
#if 0 /* Clr'd in NetBuf_Get() [see Note #4d3B]. */
DEF_BIT_CLR(pbuf_hdr->Flags, NET_BUF_FLAG_UDP_RX_CHK_SUM_VALID);
#endif
}
/* ----------------- UPDATE BUF CTRLS ----------------- */
/* Calc UDP data len/ix (see Note #5a). */
pbuf_hdr->TCP_UDP_HdrLen = NET_UDP_HDR_SIZE;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (pbuf_hdr->TCP_UDP_HdrLen > udp_tot_len) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDataLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN_DATA;
return;
}
if (pbuf_hdr->TCP_UDP_HdrLen > pbuf_hdr->DataLen) {
NET_CTR_ERR_INC(NetUDP_ErrRxHdrDataLenCtr);
*perr = NET_UDP_ERR_INVALID_LEN_DATA;
return;
}
#endif
udp_data_len = udp_tot_len - pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->TCP_UDP_DataLen = udp_data_len;
pbuf_hdr->DataLen -= (NET_BUF_SIZE) pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->DataIx = pbuf_hdr->TCP_UDP_HdrDataIx + pbuf_hdr->TCP_UDP_HdrLen;
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_APP;
pbuf_next = (NET_BUF *)pbuf_hdr->NextBufPtr;
while (pbuf_next != (NET_BUF *)0) { /* Calc ALL pkt bufs' data len/ix (see Note #5b). */
pbuf_next_hdr = &pbuf_next->Hdr;
pbuf_next_hdr->DataIx = pbuf_next_hdr->TCP_UDP_HdrDataIx;
pbuf_next_hdr->TCP_UDP_HdrLen = 0; /* NULL UDP hdr len in each pkt buf. */
pbuf_next_hdr->TCP_UDP_TotLen = udp_tot_len; /* Dup UDP tot len & ... */
pbuf_next_hdr->TCP_UDP_DataLen = udp_data_len; /* ... data len in each pkt buf (see Note #5c). */
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_APP;
pbuf_next = (NET_BUF *)pbuf_next_hdr->NextBufPtr;
}
*perr = NET_UDP_ERR_NONE;
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUDP_RxPktDemuxDatagram()
*
* Description : Demultiplex UDP datagram to appropriate socket or application connection.
*
* Argument(s) : pbuf Pointer to network buffer that received UDP datagram.
* ---- Argument checked in NetUDP_Rx().
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
* NET_ERR_RX Receive error; packet discarded.
* NET_ERR_RX_DEST Invalid destination; no connection available
* for received packet.
*
* -------- RETURNED BY NetSock_Rx() : --------
* NET_SOCK_ERR_NONE UDP datagram successfully received to
* socket connection.
*
* - RETURNED BY NetUDP_RxPktDemuxAppData() : -
* NET_APP_ERR_NONE UDP datagram successfully received to
* application connection.
*
* Return(s) : none.
*
* Caller(s) : NetUDP_Rx().
*
* Note(s) : (1) (a) Attempt demultiplex of received UDP datagram to socket connections first, if enabled.
*
* (b) On any error, attempt demultiplex to application connections, if enabled.
*
* (2) When network buffer is demultiplexed to socket or application receive, the buffer's reference
* counter is NOT incremented since the UDP layer does NOT maintain a reference to the buffer.
*********************************************************************************************************
*/
static void NetUDP_RxPktDemuxDatagram (NET_BUF *pbuf,
NET_ERR *perr)
{
#if ((NET_UDP_CFG_APP_API_SEL == N
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -