📄 net_util.c
字号:
if (hdr_size < 1) {
*perr = NET_UTIL_ERR_NULL_SIZE;
return (DEF_FAIL);
}
#endif
/* -------- VERIFY HDR'S 16-BIT ONE'S-CPL SUM --------- */
sum = NetUtil_16BitSumHdrCalc(phdr, hdr_size); /* Calc 16-bit sum (see Note #4a). */
while (sum >> 16) { /* While 16-bit sum ovf's, ... */
sum = (sum & 0x0000FFFF) + (sum >> 16); /* ... sum ovf bits back into 16-bit one's-cpl sum. */
}
chk_sum = (NET_CHK_SUM)sum;
chk_sum_host = NET_UTIL_NET_TO_HOST_16(chk_sum); /* Conv back to host-order (see Note #4b). */
/* Verify chk sum (see Note #1b). */
valid = (chk_sum_host == NET_UTIL_16_BIT_ONES_CPL_NEG_ZERO) ? DEF_OK : DEF_FAIL;
*perr = NET_UTIL_ERR_NONE;
return (valid);
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUtil_16BitOnesCplChkSumDataCalc()
*
* Description : Calculate 16-bit one's-complement check-sum on packet data.
*
* (1) See RFC #1071, Sections 1, 2.(1), & 4.1 for summary of 16-bit one's-complement
* check-sum & algorithm.
*
* (2) Check-sum calculated on packet data encapsulated in :
*
* (a) One or more network buffers Support non-fragmented & fragmented packets
* (b) Transport layer pseudo-header See RFC #768, Section 'Fields : Checksum' &
* RFC #793, Section 3.1 'Header Format :
* Checksum'.
*
* (3) To correctly calculate 16-bit one's-complement check-sums on memory buffers of any
* octet-length & word-alignment, the check-sums MUST be calculated in network-order on
* data & headers that are arranged in network-order (see also 'NetUtil_16BitSumDataCalc()
* Note #5b').
*
*
* Argument(s) : pdata_buf Pointer to packet data network buffer(s) (see Note #2a).
*
* ppseudo_hdr Pointer to transport layer pseudo-header (see Note #2b).
*
* pseudo_hdr_size Size of transport layer pseudo-header.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_UTIL_ERR_NONE Check-sum calculated; check return value.
*
* - RETURNED BY NetUtil_16BitOnesCplSumDataCalc() : -
* NET_UTIL_ERR_NULL_PTR Argument 'pdata_buf' passed a NULL pointer.
* NET_UTIL_ERR_NULL_SIZE Packet data is a zero size.
* NET_UTIL_ERR_INVALID_PROTOCOL Invalid data packet protocol.
* NET_BUF_ERR_INVALID_IX Invalid buffer index.
*
* Return(s) : 16-bit one's-complement check-sum, if NO errors.
*
* 0, otherwise.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
* application function(s).
*
* Note(s) : (4) (a) Since the 16-bit one's-complement check-sum calculations are returned in host-
* order, ...
*
* (b) ... the returned check-sum MUST NOT be re-converted back to network-order.
*
* See also 'NetUtil_16BitSumDataCalc() Note #5c3' &
* 'NetUtil_16BitOnesCplSumDataCalc() Note #4'.
*********************************************************************************************************
*/
NET_CHK_SUM NetUtil_16BitOnesCplChkSumDataCalc (void *pdata_buf,
void *ppseudo_hdr,
CPU_INT16U pseudo_hdr_size,
NET_ERR *perr)
{
CPU_INT16U sum;
NET_CHK_SUM chk_sum;
/* Calc 16-bit one's-cpl sum (see Note #4a). */
sum = NetUtil_16BitOnesCplSumDataCalc(pdata_buf, ppseudo_hdr, pseudo_hdr_size, perr);
if (*perr != NET_UTIL_ERR_NONE) {
return (0);
}
chk_sum = ~((NET_CHK_SUM)sum); /* Perform one's cpl on one's-cpl sum. */
*perr = NET_UTIL_ERR_NONE;
return (chk_sum); /* Rtn 16-bit chk sum (see Note #4). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUtil_16BitOnesCplChkSumDataVerify()
*
* Description : (1) Verify 16-bit one's-complement check-sum on packet data :
*
* (a) Calculate one's-complement sum on packet data & packet pseudo-header
* (b) Verify check-sum by comparison of one's-complement sum to one's-complement
* '-0' value (negative zero)
*
* (2) See RFC #1071, Sections 1, 2.(1), & 4.1 for summary of 16-bit one's-complement
* check-sum & algorithm.
*
* (3) Check-sum calculated on packet data encapsulated in :
*
* (a) One or more network buffers Support non-fragmented & fragmented packets
* (b) Transport layer pseudo-header See RFC #768, Section 'Fields : Checksum' &
* RFC #793, Section 3.1 'Header Format :
* Checksum'.
*
* (4) To correctly calculate 16-bit one's-complement check-sums on memory buffers of any
* octet-length & word-alignment, the check-sums MUST be calculated in network-order on
* data & headers that are arranged in network-order (see also 'NetUtil_16BitSumDataCalc()
* Note #5b').
*
*
* Argument(s) : pdata_buf Pointer to packet data network buffer(s) (see Note #3a).
*
* ppseudo_hdr Pointer to transport layer pseudo-header (see Note #3b).
*
* pseudo_hdr_size Size of transport layer pseudo-header.
*
* perr Pointer to variable that will receive the return error code from this function :
*
* NET_UTIL_ERR_NONE Check-sum calculated; check return value.
*
* - RETURNED BY NetUtil_16BitOnesCplSumDataCalc() : -
* NET_UTIL_ERR_NULL_PTR Argument 'pdata_buf' passed a NULL pointer.
* NET_UTIL_ERR_NULL_SIZE Packet data is a zero size.
* NET_UTIL_ERR_INVALID_PROTOCOL Invalid data packet protocol.
* NET_BUF_ERR_INVALID_IX Invalid buffer index.
*
* Return(s) : DEF_OK, if valid check-sum.
*
* DEF_FAIL, otherwise.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
* application function(s).
*
* Note(s) : (5) (a) Since the 16-bit one's-complement check-sum calculations are returned in host-
* order, ...
*
* (b) ... the returned check-sum MUST NOT be re-converted back to network-order for
* the final check-sum comparison.
*
* See also 'NetUtil_16BitSumDataCalc() Note #5c3' &
* 'NetUtil_16BitOnesCplSumDataCalc() Note #4'.
*********************************************************************************************************
*/
CPU_BOOLEAN NetUtil_16BitOnesCplChkSumDataVerify (void *pdata_buf,
void *ppseudo_hdr,
CPU_INT16U pseudo_hdr_size,
NET_ERR *perr)
{
CPU_INT16U sum;
NET_CHK_SUM chk_sum;
CPU_BOOLEAN valid;
/* Calc 16-bit one's-cpl sum (see Note #5a). */
sum = NetUtil_16BitOnesCplSumDataCalc(pdata_buf, ppseudo_hdr, pseudo_hdr_size, perr);
if (*perr != NET_UTIL_ERR_NONE) {
return (DEF_FAIL);
}
/* Verify chk sum (see Notes #1b & #5b). */
chk_sum = (NET_CHK_SUM)sum;
valid = (chk_sum == NET_UTIL_16_BIT_ONES_CPL_NEG_ZERO) ? DEF_OK : DEF_FAIL;
*perr = NET_UTIL_ERR_NONE;
return (valid);
}
/*$PAGE*/
/*
*********************************************************************************************************
*********************************************************************************************************
* LOCAL FUNCTIONS
*********************************************************************************************************
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* NetUtil_16BitSumHdrCalc()
*
* Description : Calculate 16-bit sum on packet header memory buffer.
*
* (1) Calculates the sum of consecutive 16-bit values.
*
* (2) 16-bit sum is returned as a 32-bit value to preserve possible 16-bit summation overflow
* in the upper 16-bits.
*
*
* Argument(s) : phdr Pointer to packet header.
* ---- Argument checked in NetUtil_16BitOnesCplChkSumHdrCalc(),
* NetUtil_16BitOnesCplChkSumHdrVerify(),
* NetUtil_16BitOnesCplSumDataCalc().
*
* hdr_size Size of packet header.
*
* Return(s) : 16-bit sum (see Note #2), if NO errors.
*
* 0, otherwise.
*
* Caller(s) : NetUtil_16BitOnesCplChkSumHdrCalc(),
* NetUtil_16BitOnesCplChkSumHdrVerify(),
* NetUtil_16BitOnesCplSumDataCalc().
*
* Note(s) : (3) Since many word-aligned processors REQUIRE that multi-octet words be located on word-
* aligned addresses, 16-bit sum calculation MUST ensure that 16-bit words are accessed
* on addresses that are multiples of 2 octets.
*
* If packet header memory buffer does NOT start on a 16-bit word address boundary, then
* 16-bit sum calculation MUST be performed by concatenating two consecutive 8-bit values.
*
* (4) Modulo arithmetic is used to determine whether a memory buffer starts on the desired
* word-aligned address boundary.
*
* Modulo arithmetic in ANSI-C REQUIREs operations performed on integer values. Thus,
* address values MUST be cast to an appropriately-sized integer value PRIOR to any
* modulo arithmetic operation.
*
* (5) (a) Although "the sum of 16-bit integers can be computed in either byte order"
* [RFC #1071, Section 2.(B)], the handling of odd-length &/or off-word-boundary
* memory buffers is performed assuming network-order.
*
* (b) However, to correctly & consistently calculate 16-bit integer sums for even-/
* odd-length & word-/off-word-boundary memory buffers, the sums MUST be calculated
* in network-order.
*
* (c) (1) To preserve possible 16-bit summation overflow (see Note #2) during all check-
* sum calculations, the 16-bit sum is returned as a 32-bit network-order value.
*
* (2) To encapsulate the network-order transform to the 16-bit check-sum calculations
* ONLY, the final check-sum MUST be converted to host-order.
*
* See 'NetUtil_16BitOnesCplChkSumHdrCalc() Note #3b' &
* 'NetUtil_16BitOnesCplChkSumHdrVerify() Note #4b').
*
* (3) However, since network-to-host-order conversion & host-order memory access are
* inverse operations, the final host-order check-sum value MUST NOT be converted
* back to network-order for calculation or comparison.
*
* (6) RFC #1071, Section 4.1 explicitly casts & sums the last odd-length octet in a check-sum
* calculation as a 16-bit value.
*
* ???? However, this contradicts the following sections which state that "if the total
* length is odd, ... the last octet is padded on the right with ... one octet of zeros
* ... to form a 16 bit word for ... purposes ... [of] computing the checksum" :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -