📄 net_util.c
字号:
*
* (a) RFC #768, Section 'Fields : Checksum'
* (b) RFC #792, Section 'Echo or Echo Reply Message : Checksum'
* (c) RFC #793, Section 3.1 'Header Format : Checksum'
*
* See also 'NetUtil_16BitSumDataCalc() Note #8'.
*********************************************************************************************************
*/
/*$PAGE*/
static CPU_INT32U NetUtil_16BitSumHdrCalc (void *phdr,
CPU_INT16U hdr_size)
{
CPU_INT32U sum_32;
CPU_INT32U sum_val_32;
CPU_INT16U hdr_val_16;
CPU_INT16U size_rem;
CPU_INT16U *phdr_16;
CPU_INT08U *phdr_08;
CPU_INT08U modulo_16;
/* ---------------- VALIDATE SIZE ----------------- */
if (hdr_size < 1) {
return (0);
}
size_rem = hdr_size;
sum_32 = 0;
modulo_16 = (CPU_INT08U)((CPU_ADDR)phdr % sizeof(CPU_INT16U)); /* See Note #4. */
if (modulo_16 == 0) { /* If pkt hdr on 16-bit word boundary (see Note #3),*/
phdr_16 = (CPU_INT16U *)phdr;
while (size_rem >= sizeof(CPU_INT16U)) {
hdr_val_16 = (CPU_INT16U)*phdr_16++;
sum_val_32 = (CPU_INT32U) NET_UTIL_HOST_TO_NET_16(hdr_val_16); /* Conv to net-order (see Note #5b). */
sum_32 += (CPU_INT32U) sum_val_32; /* ... calc sum with 16-bit data words. */
size_rem -= sizeof(CPU_INT16U);
}
phdr_08 = (CPU_INT08U *)phdr_16;
} else { /* Else if pkt hdr NOT on 16-bit word boundary, ... */
phdr_08 = (CPU_INT08U *)phdr;
while (size_rem >= sizeof(CPU_INT16U)) {
sum_val_32 = (CPU_INT32U)*phdr_08++;
sum_val_32 <<= DEF_OCTET_NBR_BITS;
sum_val_32 += (CPU_INT32U)*phdr_08++;
sum_32 += (CPU_INT32U) sum_val_32; /* ... calc sum with 8-bit data vals. */
size_rem -= sizeof(CPU_INT16U);
}
}
if (size_rem > 0) { /* Sum last octet, if any (see Note #6). */
sum_32 += (CPU_INT32U)*phdr_08;
}
return (sum_32); /* Rtn 16-bit sum (see Note #5c1). */
}
/*$PAGE*/
/*
*********************************************************************************************************
* NetUtil_16BitSumDataCalc()
*
* Description : Calculate 16-bit sum on packet data 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) : p_data Pointer to packet data.
* ------ Argument validated in NetUtil_16BitOnesCplSumDataCalc().
*
* data_size Size of packet data (in this network buffer only
* [see 'NetUtil_16BitOnesCplSumDataCalc() Note #1a']).
*
* poctet_prev Pointer to last octet from a fragmented packet's previous buffer.
* ----------- Argument validated in NetUtil_16BitOnesCplSumDataCalc().
*
* poctet_last Pointer to variable that will receive the value of the last octet from a
* ----------- fragmented packet's current buffer.
*
* Argument validated in NetUtil_16BitOnesCplSumDataCalc().
*
* prev_octet_valid Indicate whether pointer to the last octet of the packet's previous
* ---------------- buffer is valid.
*
* Argument validated in NetUtil_16BitOnesCplSumDataCalc().
*
* last_pkt_buf Indicate whether the current packet buffer is the last packet buffer.
* ------------ Argument validated in NetUtil_16BitOnesCplSumDataCalc().
*
* psum_err Pointer to variable that will receive the error return code(s) from this function :
*
* NET_UTIL_16_BIT_SUM_ERR_NONE No error return codes.
*
* The following error return codes are bit-field codes logically OR'd & MUST
* be individually tested by bit-wise tests :
*
* NET_UTIL_16_BIT_SUM_ERR_NULL_SIZE Packet buffer's data size is
* a zero size.
* NET_UTIL_16_BIT_SUM_ERR_LAST_OCTET Last odd-length octet in packet
* buffer is available; check
* 'poctet_last' return value.
*
* Return(s) : 16-bit sum (see Note #2), if NO errors.
*
* 0, otherwise.
*
* Caller(s) : NetUtil_16BitOnesCplSumDataCalc().
*$PAGE*
* 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 data 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 so that the last octet of any packet buffer is correctly pre-
* pended to the first octet of the next packet buffer.
*
* (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_16BitOnesCplSumDataCalc() Note #4').
*
* (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) Optimized 32-bit sum calculations implemented in the network protocol suite's network-
* specific library port optimization file(s).
*
* See also 'net_util.h FUNCTION PROTOTYPES DEFINED IN PRODUCT'S net_util_a.* Note #1'.
*
* (7) Since pointer arithmetic is based on the specific pointer data type & inherent pointer
* data type size, pointer arithmetic operands :
*
* (a) MUST be in terms of the specific pointer data type & data type size; ...
* (b) SHOULD NOT & in some cases MUST NOT be cast to other data types or data type sizes.
*
* (8) The following sections 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" :
*
* (a) RFC #768, Section 'Fields : Checksum'
* (b) RFC #792, Section 'Echo or Echo Reply Message : Checksum'
* (c) RFC #793, Section 3.1 'Header Format : Checksum'
*
* See also 'NetUtil_16BitSumHdrCalc() Note #6'.
*********************************************************************************************************
*/
/*$PAGE*/
static CPU_INT32U NetUtil_16BitSumDataCalc (void *p_data,
CPU_INT16U data_size,
CPU_INT08U *poctet_prev,
CPU_INT08U *poctet_last,
CPU_BOOLEAN prev_octet_valid,
CPU_BOOLEAN last_pkt_buf,
CPU_INT08U *psum_err)
{
#if (NET_CFG_OPTIMIZE == NET_OPTIMIZE_SPD)
CPU_INT08U modulo_32;
#if ((defined(uC_CFG_OPTIMIZE_ASM_EN)) && \
(uC_CFG_OPTIMIZE_ASM_EN == DEF_ENABLED))
CPU_INT16U size_rem_32_offset;
CPU_INT16U size_rem_32;
#else
CPU_INT32U data_val_32;
CPU_INT32U *pdata_32;
#endif
#endif
CPU_INT32U sum_32;
CPU_INT32U sum_val_32;
CPU_INT16U data_val_16;
CPU_INT16U size_rem;
CPU_INT16U *pdata_16;
CPU_INT08U *pdata_08;
CPU_INT08U modulo_16;
CPU_BOOLEAN pkt_aligned_16;
sum_32 = 0;
if (data_size < 1) { /* ------------ HANDLE NULL-SIZE DATA PKT ------------- */
*psum_err = NET_UTIL_16_BIT_SUM_ERR_NULL_SIZE;
if (prev_octet_valid != DEF_NO) { /* If null size & last octet from prev pkt buf avail .. */
if (last_pkt_buf != DEF_NO) { /* ... & on last pkt buf, ... */
sum_val_32 = (CPU_INT32U)*poctet_prev; /* ... cast prev pkt buf's last octet, ... */
sum_val_32 <<= DEF_OCTET_NBR_BITS; /* ... pad odd-len pkt len (see Note #5) ... */
sum_32 = sum_val_32; /* ... & rtn prev pkt buf's last octet as last sum. */
} else { /* ... & NOT on last pkt buf, ... */
*poctet_last = *poctet_prev; /* ... rtn last octet from prev pkt buf as last octet. */
DEF_BIT_SET(*psum_err, NET_UTIL_16_BIT_SUM_ERR_LAST_OCTET);
}
} else {
; /* If null size & NO prev octet, NO action(s) req'd. */
}
return (sum_32); /* Rtn 16-bit sum (see Note #5c1). */
}
/*$PAGE*/
/* ----------- HANDLE NON-NULL DATA PKT ----------- */
size_rem = data_size;
*psum_err = NET_UTIL_16_BIT_SUM_ERR_NONE;
/* See Notes #3 & #4. */
modulo_16 = (CPU_INT08U)((CPU_ADDR)p_data % sizeof(CPU_INT16U));
pkt_aligned_16 = (((modulo_16 == 0) && (prev_octet_valid == DEF_NO )) ||
((modulo_16 != 0) && (prev_octet_valid == DEF_YES))) ? DEF_YES : DEF_NO;
pdata_08 = (CPU_INT08U *)p_data;
if (prev_octet_valid == DEF_YES) { /* If last octet from prev pkt buf avail, ... */
sum_val_32 = (CPU_INT32U)*poctet_prev;
sum_val_32 <<= DEF_OCTET_NBR_BITS; /* ... prepend last octet from prev pkt buf ... */
sum_val_32 += (CPU_INT32U)*pdata_08++;
sum_32 += (CPU_INT32U) sum_val_32; /* ... to first octet in cur pkt buf. */
size_rem -= sizeof(CPU_INT08U);
}
if (pkt_aligned_16 == DEF_YES) { /* If pkt data aligned on 16-bit boundary, .. */
/* .. calc sum with 16- & 32-bit data words. */
pdata_16 = (CPU_INT16U *)pdata_08;
#if (NET_CFG_OPTIMIZE == NET_OPTIMIZE_SPD)
modulo_32 = (CPU_INT08U )((CPU_ADDR)pdata_16 % sizeof(CPU_INT32U)); /* See Note #4. */
if ((modulo_32 != 0) && /* If leading 16-bit pkt data avail, .. */
(size_rem >= sizeof(CPU_INT16U))) {
data_val_16 = (CPU_INT16U)*pdata_16++;
sum_val_32 = (CPU_INT32U) NET_UTIL_HOST_TO_NET_16(data_val_16); /* Conv to net-order (see Note #5b). */
sum_32 += (CPU_INT32U) sum_val_32; /* .. start calc sum with leading 16-bit data word. */
size_rem -= sizeof(CPU_INT16U);
}
#if ((defined(uC_CFG_OPTIMIZE_ASM_EN)) && \
(uC_CFG_OPTIMIZE_ASM_EN == DEF_ENABLED))
/* Calc optimized 32-bit size rem. */
size_rem_32_offset = (CPU_INT16U)(size_rem % sizeof(CPU_INT32U));
size_rem_32 = (CPU_INT16U)(size_rem - size_rem_32_offset);
/* Calc optimized 32-bit sum (see Note #6). */
sum_val_32 = (CPU_INT32U)NetUtil_16BitSumDataCalcAlign_32((void *)pdata_16,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -