📄 net_icmp.c
字号:
* --- RETURNED BY NetICMP_TxPktDiscard() : ---
* NET_ERR_TX Transmit error; packet discarded.
*
* Return(s) : none.
*
* Caller(s) : various.
*
* This function is an INTERNAL network protocol suite function & MUST NOT be called by
* application function(s).
*
* Note(s) : (2) NetICMP_TxMsgErr() blocked until network initialization completes; perform NO action.
*
* (3) (a) The following IP header fields MUST be decoded &/or converted from network-order to host-
* order BEFORE any ICMP Error Messages are transmitted (see 'net_ip.c NetIP_RxPktValidate()
* Note #3') :
*
* (1) Header Length
* (2) Total Length
* (3) Source Address
* (4) Destination Address
*
* (b) The following IP header fields were NOT previously decoded &/or converted from network-
* order to host-order & are NOT available :
*
* (1) IP Data Length
*
* (4) Default case already invalidated in NetICMP_TxMsgErrValidate(). However, the default
* case is included as an extra precaution in case 'type' is incorrectly modified.
*
* (5) Assumes network buffer's protocol header size is large enough to accomodate ICMP header
* size (see 'net_buf.h NETWORK BUFFER INDEX & SIZE DEFINES Note #1').
*$PAGE*
* (6) Some buffer controls were previously initialized in NetBuf_Get() when the buffer
* was allocated earlier in this function. These buffer controls do NOT need to be
* re-initialized but are shown for completeness.
*
* (7) (a) ICMP message Check-Sum MUST be calculated AFTER the entire ICMP message has been
* prepared. In addition, ALL multi-octet words are converted from host-order to
* network-order since "the sum of 16-bit integers can be computed in either byte
* order" [RFC #1071, Section 2.(B)].
*
* (b) ICMP message Check-Sum field MUST be cleared to '0' BEFORE the ICMP message Check-Sum
* is calculated (see RFC #792, Sections 'Destination Unreachable Message : Checksum',
* 'Time Exceeded Message : Checksum', 'Source Quench Message : Checksum', & 'Parameter
* Problem Message : Checksum').
*
* (c) The ICMP message Check-Sum field is returned in network-order & MUST NOT be re-converted
* back to host-order (see 'net_util.c NetUtil_16BitOnesCplChkSumHdrCalc() Note #3b').
*
* (8) Network buffer already freed by lower layer; only increment error counter.
*
* (9) #### 'perr' may NOT be necessary (remove if unnecessary).
*********************************************************************************************************
*/
void NetICMP_TxMsgErr (NET_BUF *pbuf,
CPU_INT08U type,
CPU_INT08U code,
CPU_INT08U ptr,
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_BUF_HDR *pbuf_hdr;
NET_IP_HDR *pip_hdr;
NET_BUF *pmsg_err;
NET_BUF_HDR *pmsg_err_hdr;
NET_ICMP_HDR_ERR *picmp_hdr_err;
NET_ICMP_HDR_PARAM_PROB *picmp_hdr_param_prob;
CPU_INT16U msg_size_hdr;
CPU_INT16U msg_size_data_ip;
CPU_INT16U msg_size_data;
CPU_INT16U msg_size_tot;
CPU_INT16U msg_ix;
CPU_INT16U msg_ix_data;
CPU_INT16U msg_chk_sum;
NET_ERR err;
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit tx (see Note #2). */
*perr = NET_ERR_INIT_INCOMPLETE;
return;
}
#endif
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
/* ------------------- VALIDATE PTR ------------------- */
if (pbuf == (NET_BUF *)0) {
NetICMP_TxPktDiscard((NET_BUF *)0, perr);
NET_CTR_ERR_INC(NetICMP_ErrNullPtrCtr);
return;
}
#endif
/* ------------- VALIDATE ICMP TX ERR MSG ------------- */
pbuf_hdr = &pbuf->Hdr;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (pbuf_hdr->IP_HdrIx == NET_BUF_IX_NONE) {
NetICMP_TxPktDiscard((NET_BUF *)0, perr);
NET_CTR_ERR_INC(NetICMP_ErrRxInvalidBufIxCtr);
return;
}
#endif
pip_hdr = (NET_IP_HDR *)&pbuf->Data[pbuf_hdr->IP_HdrIx];
NetICMP_TxMsgErrValidate(pbuf, pbuf_hdr, pip_hdr, type, code, ptr, &err);
if (err != NET_ICMP_ERR_NONE) {
NetICMP_TxPktDiscard((NET_BUF *)0, perr);
return;
}
/*$PAGE*/
/* --------------- GET ICMP ERR MSG BUF --------------- */
/* Calc err msg buf size. */
switch (type) {
case NET_ICMP_MSG_TYPE_DEST_UNREACH:
msg_size_hdr = NET_ICMP_HDR_SIZE_DEST_UNREACH;
break;
case NET_ICMP_MSG_TYPE_SRC_QUENCH:
msg_size_hdr = NET_ICMP_HDR_SIZE_SRC_QUENCH;
break;
case NET_ICMP_MSG_TYPE_TIME_EXCEED:
msg_size_hdr = NET_ICMP_HDR_SIZE_TIME_EXCEED;
break;
case NET_ICMP_MSG_TYPE_PARAM_PROB:
msg_size_hdr = NET_ICMP_HDR_SIZE_PARAM_PROB;
break;
default: /* See Note #4. */
NetICMP_TxPktDiscard((NET_BUF *)0, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
if (pbuf_hdr->IP_TotLen >= pbuf_hdr->IP_HdrLen) { /* If IP tot len > IP hdr len & ... */
msg_size_data_ip = pbuf_hdr->IP_TotLen - pbuf_hdr->IP_HdrLen; /* Calc IP data len (see Note #3b1). */
if (msg_size_data_ip >= NET_ICMP_MSG_ERR_DATA_SIZE_MIN_OCTETS) { /* ... ip data >= min ICMP data len, ... */
/* ... get max ICMP err msg len. */
msg_size_data = pbuf_hdr->IP_HdrLen + NET_ICMP_MSG_ERR_DATA_SIZE_MIN_OCTETS;
} else { /* Else get max IP tot len. */
msg_size_data = pbuf_hdr->IP_TotLen;
}
} else { /* Else get max IP tot len. */
msg_size_data = pbuf_hdr->IP_TotLen;
}
msg_size_tot = msg_size_hdr + msg_size_data;
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
if (NET_BUF_DATA_TX_IX < msg_size_hdr) { /* See Note #5. */
NetICMP_TxPktDiscard((NET_BUF *)0, perr);
NET_CTR_ERR_INC(NetICMP_ErrTxInvalidBufIxCtr);
return;
}
#endif
msg_ix = NET_BUF_DATA_TX_IX - msg_size_hdr;
pmsg_err = NetBuf_Get((NET_BUF_SIZE) msg_size_tot, /* Get err msg buf. */
(NET_BUF_SIZE) msg_ix,
(CPU_INT16U ) NET_BUF_FLAG_NONE,
(NET_ERR *)&err);
if (err != NET_BUF_ERR_NONE) {
NetICMP_TxPktDiscard(pmsg_err, perr);
return;
}
msg_ix_data = msg_ix + msg_size_hdr;
NetBuf_DataWr((NET_BUF *) pmsg_err, /* Copy rx'd IP hdr & data into ICMP err tx buf. */
(NET_BUF_SIZE) msg_ix_data,
(NET_BUF_SIZE) msg_size_data,
(CPU_INT08U *) pip_hdr,
(NET_ERR *)&err);
if (err != NET_BUF_ERR_NONE) {
NetICMP_TxPktDiscard(pmsg_err, perr);
return;
}
/* Init err msg buf ctrls. */
pmsg_err_hdr = &pmsg_err->Hdr;
pmsg_err_hdr->ICMP_MsgIx = (CPU_INT16U )msg_ix;
pmsg_err_hdr->ICMP_MsgLen = (CPU_INT16U )msg_size_tot;
pmsg_err_hdr->ICMP_HdrLen = (CPU_INT16U )msg_size_hdr;
pmsg_err_hdr->TotLen = (NET_BUF_SIZE)pmsg_err_hdr->ICMP_MsgLen;
pmsg_err_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_ICMP;
#if 0 /* Init'd in NetBuf_Get() [see Note #6]. */
pmsg_err_hdr->DataIx = NET_BUF_IX_NONE;
pmsg_err_hdr->DataLen = 0;
#endif
/*$PAGE*/
/* --------------- PREPARE ICMP ERR MSG --------------- */
switch (type) {
case NET_ICMP_MSG_TYPE_DEST_UNREACH:
case NET_ICMP_MSG_TYPE_SRC_QUENCH:
case NET_ICMP_MSG_TYPE_TIME_EXCEED:
picmp_hdr_err = (NET_ICMP_HDR_ERR *)&pmsg_err->Data[pmsg_err_hdr->ICMP_MsgIx];
picmp_hdr_err->Type = type;
picmp_hdr_err->Code = code;
/* Clr unused octets. */
Mem_Clr((void *)picmp_hdr_err->Unused,
(CPU_SIZE_T)NET_ICMP_HDR_NBR_OCTETS_UNUSED);
/* Calc ICMP msg chk sum (see Note #7). */
NET_UTIL_VAL_SET_NET_16(&picmp_hdr_err->ChkSum, 0x0000); /* Clr chk sum (see Note #7b). */
msg_chk_sum = NetUtil_16BitOnesCplChkSumHdrCalc((void *) picmp_hdr_err,
(CPU_INT16U) pmsg_err_hdr->ICMP_MsgLen,
(NET_ERR *)&err);
NET_UTIL_VAL_COPY_16(&picmp_hdr_err->ChkSum, &msg_chk_sum); /* Copy chk sum in net order (see Note #7c).*/
break;
case NET_ICMP_MSG_TYPE_PARAM_PROB:
picmp_hdr_param_prob = (NET_ICMP_HDR_PARAM_PROB *)&pmsg_err->Data[pmsg_err_hdr->ICMP_MsgIx];
picmp_hdr_param_prob->Type = type;
picmp_hdr_param_prob->Code = code;
picmp_hdr_param_prob->Ptr = ptr;
/* Clr unused octets. */
Mem_Clr((void *)picmp_hdr_param_prob->Unused,
(CPU_SIZE_T)NET_ICMP_HDR_NBR_OCTETS_UNUSED_PARAM_PROB);
/* Calc ICMP msg chk sum (see Note #7). */
NET_UTIL_VAL_SET_NET_16(&picmp_hdr_param_prob->ChkSum, 0x0000);/* Clr chk sum (see Note #7b). */
msg_chk_sum = NetUtil_16BitOnesCplChkSumHdrCalc((void *) picmp_hdr_param_prob,
(CPU_INT16U) pmsg_err_hdr->ICMP_MsgLen,
(NET_ERR *)&err);
/* Copy chk sum in net order (see Note #7c).*/
NET_UTIL_VAL_COPY_16(&picmp_hdr_param_prob->ChkSum, &msg_chk_sum);
break;
default: /* See Note #4. */
NetICMP_TxPktDiscard(pmsg_err, perr);
return; /* Prevent 'break NOT reachable' compiler warning. */
}
if (err != NET_UTIL_ERR_NONE) { /* Chk err from NetUtil_16BitOnesCplChkSumHdrCalc(). */
NetICMP_TxPktDiscard(pmsg_err, perr);
return;
}
/* ----------------- TX ICMP ERR MSG ------------------ */
NetIP_Tx((NET_BUF *)pmsg_err,
(NET_IP_ADDR)pbuf_hdr->IP_AddrDest,
(NET_IP_ADDR)pbuf_hdr->IP_AddrSrc,
(NET_IP_TOS )NET_IP_TOS_DFLT, /* See Note #1da. */
(NET_IP_TTL )NET_IP_TTL_DFLT,
(CPU_INT16U )NET_IP_FLAG_NONE,
(void *)0,
(NET_ERR *)perr);
/* ------- FREE ICMP ERR MSG / UPDATE TX STATS -------- */
switch (*perr) {
case NET_IP_ERR_NONE:
NetICMP_TxPktFree(pmsg_err);
NET_CTR_STAT_INC(NetICMP_StatTxMsgCtr);
NET_CTR_STAT_INC(NetICMP_StatTxMsgErrCtr);
break;
case NET_ERR_INIT_INCOMPLETE:
case NET_ERR_TX:
NET_CTR_ERR_INC(NetICMP_ErrTxPktDiscardedCtr); /* See Note #8. */
return; /* Prevent 'break NOT reachable' compiler warning. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -