mirror of
https://github.com/dimoniche/solarium.vlad.git
synced 2026-01-30 21:13:31 +03:00
6283 lines
294 KiB
C
6283 lines
294 KiB
C
/*
|
||
*********************************************************************************************************
|
||
* uC/TCP-IP
|
||
* The Embedded TCP/IP Suite
|
||
*
|
||
* (c) Copyright 2003-2007; Micrium, Inc.; Weston, FL
|
||
*
|
||
* All rights reserved. Protected by international copyright laws.
|
||
*
|
||
* uC/TCP-IP is provided in source form for FREE evaluation, for educational
|
||
* use or peaceful research. If you plan on using uC/TCP-IP in a commercial
|
||
* product you need to contact Micrium to properly license its use in your
|
||
* product. We provide ALL the source code for your convenience and to help
|
||
* you experience uC/TCP-IP. The fact that the source code is provided does
|
||
* NOT mean that you can use it without paying a licensing fee.
|
||
*
|
||
* Knowledge of the source code may NOT be used to develop a similar product.
|
||
*
|
||
* Please help us continue to provide the Embedded community with the finest
|
||
* software available. Your honesty is greatly appreciated.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
*
|
||
* NETWORK IP LAYER
|
||
* (INTERNET PROTOCOL)
|
||
*
|
||
* Filename : net_ip.c
|
||
* Version : V1.89
|
||
* Programmer(s) : ITJ
|
||
*********************************************************************************************************
|
||
* Note(s) : (1) Supports Internet Protocol as described in RFC #791, also known as IPv4, with the
|
||
* following restrictions/constraints :
|
||
*
|
||
* (a) ONLY supports a single network interface/ RFC # 791, Section 2.3
|
||
* host IP address 'Addressing'
|
||
*
|
||
* (b) ONLY supports a single default gateway RFC #1122, Section 3.3.1
|
||
*
|
||
* (c) IP forwarding/routing NOT supported RFC #1122, Sections 3.3.1,
|
||
* 3.3.4 & 3.3.5
|
||
*
|
||
* (d) IP multicasting NOT supported RFC #1122, Section 3.3.7
|
||
*
|
||
* (e) Transmit fragmentation NOT currently supported RFC # 791, Section 2.3
|
||
* 'Fragmentation &
|
||
* Reassembly'
|
||
* (f) IP Security options NOT currently supported RFC #1108
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* INCLUDE FILES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#define NET_IP_MODULE
|
||
#include <net.h>
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL DEFINES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL CONSTANTS
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL DATA TYPES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL TABLES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL GLOBAL VARIABLES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL FUNCTION PROTOTYPES
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/* -------- VALIDATE RX DATAGRAMS --------- */
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_RxPktValidateBuf (NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
#endif
|
||
|
||
static void NetIP_RxPktValidate (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_RxPktValidateOpt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_hdr,
|
||
CPU_INT08U ip_hdr_len_size,
|
||
NET_ERR *perr);
|
||
|
||
static CPU_BOOLEAN NetIP_RxPktValidateOptRoute (CPU_INT08U *popts,
|
||
CPU_INT08U opt_list_len_rem,
|
||
CPU_INT08U *popt_len,
|
||
NET_ERR *perr);
|
||
|
||
static CPU_BOOLEAN NetIP_RxPktValidateOptTS (CPU_INT08U *popts,
|
||
CPU_INT08U opt_list_len_rem,
|
||
CPU_INT08U *popt_len,
|
||
NET_ERR *perr);
|
||
|
||
|
||
/* ------------ REASM RX FRAGS ------------ */
|
||
|
||
static NET_BUF *NetIP_RxPktFragReasm (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static NET_BUF *NetIP_RxPktFragListAdd (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
NET_ERR *perr);
|
||
|
||
static NET_BUF *NetIP_RxPktFragListInsert (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
NET_BUF *pfrag_list,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_RxPktFragListRemove (NET_BUF *pfrag_list,
|
||
CPU_BOOLEAN tmr_free);
|
||
|
||
static void NetIP_RxPktFragListDiscard (NET_BUF *pfrag_list,
|
||
CPU_BOOLEAN tmr_free,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_RxPktFragListUpdate (NET_BUF *pfrag_list,
|
||
NET_BUF_HDR *pfrag_list_buf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
NET_ERR *perr);
|
||
|
||
static NET_BUF *NetIP_RxPktFragListChkComplete(NET_BUF *pfrag_list,
|
||
NET_BUF_HDR *pfrag_list_buf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_RxPktFragTimeout (void *pfrag_list_timeout);
|
||
|
||
|
||
/* ---------- DEMUX RX DATAGRAMS ---------- */
|
||
|
||
static void NetIP_RxPktDemuxDatagram (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
|
||
|
||
static void NetIP_RxPktDiscard (NET_BUF *pbuf,
|
||
NET_ERR *perr);
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ----------- VALIDATE TX PKTS ----------- */
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_TxPktValidate (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
void *popts,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktValidateOpt (void *popts,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktValidateOptRouteTS (void *popt_route_ts,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
NET_ERR *perr);
|
||
#endif
|
||
|
||
/* -------------- TX IP PKTS -------------- */
|
||
|
||
static void NetIP_TxPkt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
void *popts,
|
||
NET_ERR *perr);
|
||
|
||
static CPU_INT08U NetIP_TxPktPrepareOpt (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktPrepareOptRoute (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktPrepareOptTS (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktPrepareOptTSRoute (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktPrepareHdr (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U ip_hdr_len_tot,
|
||
CPU_INT08U ip_opt_len_tot,
|
||
CPU_INT16U protocol_ix,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
CPU_INT32U *pip_hdr_opts,
|
||
NET_ERR *perr);
|
||
|
||
|
||
/* ------------ TX IP DATAGRAMS ----------- */
|
||
|
||
static void NetIP_TxPktDatagram (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_TxPktDatagramNextHopSel (NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
|
||
|
||
static void NetIP_TxPktDiscard (NET_BUF *pbuf,
|
||
NET_ERR *perr);
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------ RE-TX IP PKTS ------------- */
|
||
|
||
static void NetIP_ReTxPkt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
static void NetIP_ReTxPktPrepareHdr (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr);
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* LOCAL CONFIGURATION ERRORS
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_Init()
|
||
*
|
||
* Description : (1) Initialize Internet Protocol Layer :
|
||
*
|
||
* (a) Initialize IP pointers & counters
|
||
* (b) Initialize IP statistics & error counters
|
||
*
|
||
*
|
||
* Argument(s) : none.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : Net_Init().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & MUST NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
void NetIP_Init (void)
|
||
{
|
||
/* ---------------- INIT IP PTRS/CTRS ----------------- */
|
||
/* Ptrs used to update Rx Frag Reasm Lists. */
|
||
NetIP_FragReasmListsHead = (NET_BUF *)0;
|
||
NetIP_FragReasmListsTail = (NET_BUF *)0;
|
||
|
||
NetIP_TxIDCtr = NET_IP_ID_INIT;
|
||
|
||
|
||
/* ------------- INIT IP STAT & ERR CTRS -------------- */
|
||
#if (NET_CTR_CFG_STAT_EN == DEF_ENABLED)
|
||
NetIP_StatRxPktCtr = 0;
|
||
NetIP_StatRxDatagramProcessedCtr = 0;
|
||
|
||
NetIP_StatRxDestLocalCtr = 0;
|
||
NetIP_StatRxDestBroadcastCtr = 0;
|
||
|
||
NetIP_StatRxFragCtr = 0;
|
||
NetIP_StatRxFragDatagramReasmCtr = 0;
|
||
|
||
NetIP_StatTxDatagramCtr = 0;
|
||
NetIP_StatTxDestLocalCtr = 0;
|
||
NetIP_StatTxDestBroadcastCtr = 0;
|
||
#endif
|
||
|
||
|
||
#if (NET_CTR_CFG_ERR_EN == DEF_ENABLED)
|
||
NetIP_ErrNullPtrCtr = 0;
|
||
|
||
|
||
NetIP_ErrCfgAddrThisHostCtr = 0;
|
||
NetIP_ErrCfgAddrDfltGatewayCtr = 0;
|
||
|
||
|
||
NetIP_ErrRxHdrVerCtr = 0;
|
||
NetIP_ErrRxHdrLenCtr = 0;
|
||
NetIP_ErrRxHdrTotLenCtr = 0;
|
||
NetIP_ErrRxHdrFlagsCtr = 0;
|
||
NetIP_ErrRxHdrFragCtr = 0;
|
||
NetIP_ErrRxHdrProtocolCtr = 0;
|
||
NetIP_ErrRxHdrChkSumCtr = 0;
|
||
NetIP_ErrRxHdrAddrSrcCtr = 0;
|
||
NetIP_ErrRxHdrOptsCtr = 0;
|
||
NetIP_ErrRxHdrOptsBufNoneAvailCtr = 0;
|
||
NetIP_ErrRxHdrOptsBufWrCtr = 0;
|
||
|
||
NetIP_ErrRxDestCtr = 0;
|
||
NetIP_ErrRxDestBroadcastCtr = 0;
|
||
|
||
NetIP_ErrRxFragSizeCtr = 0;
|
||
NetIP_ErrRxFragDiscardedCtr = 0;
|
||
NetIP_ErrRxFragDatagramDiscardedCtr = 0;
|
||
NetIP_ErrRxFragDatagramTimeoutCtr = 0;
|
||
|
||
NetIP_ErrRxPktDiscardedCtr = 0;
|
||
|
||
|
||
NetIP_ErrTxProtocolCtr = 0;
|
||
NetIP_ErrTxOptTypeCtr = 0;
|
||
|
||
NetIP_ErrTxDestCtr = 0;
|
||
|
||
NetIP_ErrTxPktDiscardedCtr = 0;
|
||
|
||
/*$PAGE*/
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
NetIP_ErrRxInvalidBufIxCtr = 0;
|
||
|
||
NetIP_ErrRxHdrDataLenCtr = 0;
|
||
|
||
NetIP_ErrRxFragFlagsCtr = 0;
|
||
NetIP_ErrRxFragOffsetCtr = 0;
|
||
|
||
|
||
NetIP_ErrTxInvalidBufIxCtr = 0;
|
||
|
||
NetIP_ErrTxHdrTOS_Ctr = 0;
|
||
NetIP_ErrTxHdrDataLenCtr = 0;
|
||
NetIP_ErrTxHdrAddrSrcCtr = 0;
|
||
NetIP_ErrTxHdrAddrDestCtr = 0;
|
||
NetIP_ErrTxHdrFlagsCtr = 0;
|
||
NetIP_ErrTxHdrOptLenCtr = 0;
|
||
NetIP_ErrTxHdrOptCfgCtr = 0;
|
||
#endif
|
||
|
||
|
||
#if 0 /* #### NOT currently implemented. */
|
||
/* See 'net_ip.c Note #1e'. */
|
||
NetIP_ErrTxFragDiscardedCtr = 0;
|
||
NetIP_ErrTxFragDiscardedDontFragCtr = 0;
|
||
#endif
|
||
#endif
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_CfgAddrThisHost()
|
||
*
|
||
* Description : (1) Configure this host's IP address :
|
||
*
|
||
* (a) Validate this host's IP address & subnet mask
|
||
* (b) Configure this host's IP address, subnet mask, & subnet
|
||
*
|
||
*
|
||
* Argument(s) : addr_host Desired IP address for this host (see Note #2).
|
||
*
|
||
* addr_subnet_mask Desired IP address subnet mask for this host (see Note #2).
|
||
*
|
||
* Return(s) : DEF_OK, if valid host IP address & subnet mask configured.
|
||
*
|
||
* DEF_FAIL, otherwise.
|
||
*
|
||
* Caller(s) : Net_InitDflt() [see Note #3],
|
||
* Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (2) Host IP addresses MUST be in host-order.
|
||
*
|
||
* (3) The default initialization configuration by Net_InitDflt() is invalid & forces the
|
||
* developer or higher-layer protocol application to configure a valid IP address &
|
||
* subnet mask.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_BOOLEAN NetIP_CfgAddrThisHost (NET_IP_ADDR addr_host,
|
||
NET_IP_ADDR addr_subnet_mask)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
CPU_BOOLEAN valid_addr;
|
||
CPU_BOOLEAN valid_cfg;
|
||
|
||
|
||
valid_addr = NetIP_IsValidAddrThisHost(addr_host, addr_subnet_mask);
|
||
valid_cfg = (valid_addr == DEF_YES) ? DEF_OK : DEF_FAIL;
|
||
|
||
if (valid_cfg == DEF_OK) {
|
||
CPU_CRITICAL_ENTER();
|
||
NetIP_AddrThisHost = addr_host;
|
||
NetIP_AddrThisHostNetOrder = (NET_IP_ADDR) NET_UTIL_HOST_TO_NET_32(addr_host);
|
||
NetIP_AddrThisHostSubnetMask = (NET_IP_ADDR) addr_subnet_mask;
|
||
NetIP_AddrThisHostSubnetMaskHost = (NET_IP_ADDR)~addr_subnet_mask;
|
||
NetIP_AddrThisHostSubnetNet = addr_host & addr_subnet_mask;
|
||
CPU_CRITICAL_EXIT();
|
||
|
||
} else {
|
||
NET_CTR_ERR_INC(NetIP_ErrCfgAddrThisHostCtr);
|
||
CPU_CRITICAL_ENTER();
|
||
NetIP_AddrThisHost = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
NetIP_AddrThisHostNetOrder = (NET_IP_ADDR)NET_UTIL_HOST_TO_NET_32(NET_IP_ADDR_NONE);
|
||
NetIP_AddrThisHostSubnetMask = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
NetIP_AddrThisHostSubnetMaskHost = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
NetIP_AddrThisHostSubnetNet = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
CPU_CRITICAL_EXIT();
|
||
}
|
||
|
||
return (valid_cfg);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_CfgAddrDfltGateway()
|
||
*
|
||
* Description : (1) Configure this host's default gateway IP address :
|
||
*
|
||
* (a) Validate this host's default gateway IP address
|
||
* (b) Configure this host's default gateway IP address
|
||
*
|
||
*
|
||
* Argument(s) : addr_dflt_gateway Desired IP address for this host's default gateway (see Note #2).
|
||
*
|
||
* Return(s) : DEF_OK, if valid default gateway IP address configured.
|
||
*
|
||
* DEF_FAIL, otherwise.
|
||
*
|
||
* Caller(s) : Net_InitDflt() [see Note #3],
|
||
* Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (2) Default gateway address MUST be in host-order.
|
||
*
|
||
* (3) The default initialization configuration by Net_InitDflt() is invalid & forces the
|
||
* developer or higher-layer protocol application to configure a valid default gateway
|
||
* IP address.
|
||
*
|
||
* (4) (a) RFC #1122, Section 3.3.1.1. states that "the host IP layer MUST operate correctly
|
||
* in a minimal network environment, and in particular, when there are no gateways".
|
||
*
|
||
* In other words, a host on an isolated network should be able to correctly operate
|
||
* & communicate with all other hosts on its local network without need of a gateway
|
||
* or configuration of a gateway.
|
||
*
|
||
* (b) However, if this host's network interface is a network type (versus a serial
|
||
* connection) AND the default gateway is configured with an invalid IP address
|
||
* NOT on the local network, then ALL non-local-network destination IP datagrams
|
||
* will be discarded at the physical link-layer/network interface.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_BOOLEAN NetIP_CfgAddrDfltGateway (NET_IP_ADDR addr_dflt_gateway)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
CPU_BOOLEAN valid_addr;
|
||
CPU_BOOLEAN valid_cfg;
|
||
|
||
|
||
valid_addr = NetIP_IsValidAddrHost(addr_dflt_gateway);
|
||
valid_cfg = (valid_addr == DEF_YES) ? DEF_OK : DEF_FAIL;
|
||
|
||
if (valid_cfg == DEF_OK) {
|
||
CPU_CRITICAL_ENTER();
|
||
NetIP_AddrDfltGateway = (NET_IP_ADDR)addr_dflt_gateway;
|
||
CPU_CRITICAL_EXIT();
|
||
|
||
} else {
|
||
NET_CTR_ERR_INC(NetIP_ErrCfgAddrDfltGatewayCtr);
|
||
CPU_CRITICAL_ENTER();
|
||
NetIP_AddrDfltGateway = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
CPU_CRITICAL_EXIT();
|
||
}
|
||
|
||
return (valid_cfg);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_CfgFragReasmTimeout()
|
||
*
|
||
* Description : Configure IP fragment reassembly timeout.
|
||
*
|
||
* (1) IP fragment reassembly timeout is the maximum time allowed between received IP fragments
|
||
* from the same IP datagram.
|
||
*
|
||
*
|
||
* Argument(s) : timeout_sec Desired value for IP fragment reassembly timeout (in seconds).
|
||
*
|
||
* Return(s) : DEF_OK, IP fragment reassembly timeout configured.
|
||
*
|
||
* Caller(s) : Net_InitDflt(),
|
||
* Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (2) Timeout in seconds converted to 'NET_TMR_TICK' ticks in order to pre-compute initial
|
||
* timeout value in 'NET_TMR_TICK' ticks.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_BOOLEAN NetIP_CfgFragReasmTimeout (CPU_INT08U timeout_sec)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
NET_TMR_TICK tick;
|
||
|
||
|
||
if (timeout_sec < NET_IP_FRAG_REASM_TIMEOUT_MIN_SEC) {
|
||
timeout_sec = NET_IP_FRAG_REASM_TIMEOUT_MIN_SEC;
|
||
}
|
||
if (timeout_sec > NET_IP_FRAG_REASM_TIMEOUT_MAX_SEC) {
|
||
timeout_sec = NET_IP_FRAG_REASM_TIMEOUT_MAX_SEC;
|
||
}
|
||
|
||
tick = (NET_TMR_TICK)timeout_sec * NET_TMR_TIME_TICK_PER_SEC;
|
||
CPU_CRITICAL_ENTER();
|
||
NetIP_FragReasmTimeout_sec = timeout_sec;
|
||
NetIP_FragReasmTimeout_tick = tick;
|
||
CPU_CRITICAL_EXIT();
|
||
|
||
return (DEF_OK);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_GetAddrThisHost()
|
||
*
|
||
* Description : Get this host's IP address.
|
||
*
|
||
* Argument(s) : none.
|
||
*
|
||
* Return(s) : This host's IP address in host-order.
|
||
*
|
||
* Caller(s) : Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
NET_IP_ADDR NetIP_GetAddrThisHost (void)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
NET_IP_ADDR addr;
|
||
|
||
|
||
CPU_CRITICAL_ENTER();
|
||
addr = NetIP_AddrThisHost;
|
||
CPU_CRITICAL_EXIT();
|
||
|
||
return (addr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_GetAddrDfltGateway()
|
||
*
|
||
* Description : Get this host's default gateway IP address.
|
||
*
|
||
* Argument(s) : none.
|
||
*
|
||
* Return(s) : This host's default gateway IP address in host-order.
|
||
*
|
||
* Caller(s) : Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
NET_IP_ADDR NetIP_GetAddrDfltGateway (void)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
NET_IP_ADDR addr;
|
||
|
||
|
||
CPU_CRITICAL_ENTER();
|
||
addr = NetIP_AddrDfltGateway;
|
||
CPU_CRITICAL_EXIT();
|
||
|
||
return (addr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_GetAddrStrThisHost()
|
||
*
|
||
* Description : Get this host's IP address as an ASCII string.
|
||
*
|
||
* Argument(s) : paddr Pointer to an ASCII character array that will receive the return IP address
|
||
* ASCII string from this function (see Note #1).
|
||
*
|
||
* Return(s) : Pointer to this host's IP address string, if NO errors.
|
||
*
|
||
* Pointer to NULL, otherwise.
|
||
*
|
||
* Caller(s) : Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (1) The size of the ASCII character array that will receive the return IP address ASCII
|
||
* string MUST be greater than or equal to NET_ASCII_LEN_MAX_ADDR_IP.
|
||
*
|
||
* See also 'net_ascii.c NetASCII_IP_to_Str() Note #2'.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_CHAR *NetIP_GetAddrStrThisHost (CPU_CHAR *paddr)
|
||
{
|
||
NET_IP_ADDR addr;
|
||
NET_ERR err;
|
||
|
||
|
||
addr = NetIP_GetAddrThisHost(); /* Get this host's IP addr. */
|
||
|
||
NetASCII_IP_to_Str(addr, paddr, DEF_NO, &err); /* Conv IP addr to IP addr str. */
|
||
if (err != NET_ASCII_ERR_NONE) { /* On any str err, ... */
|
||
*paddr = (CPU_CHAR )0; /* ... rtn NULL addr ... */
|
||
return ((CPU_CHAR *)0); /* ... & rtn NULL. */
|
||
}
|
||
|
||
return (paddr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_GetAddrStrDfltGateway()
|
||
*
|
||
* Description : Get this host's default gateway IP address as an ASCII string.
|
||
*
|
||
* Argument(s) : paddr Pointer to an ASCII character array that will receive the return IP address
|
||
* ASCII string from this function (see Note #1).
|
||
*
|
||
* Return(s) : Pointer to this host's default gateway IP address string, if NO errors.
|
||
*
|
||
* Pointer to NULL, otherwise.
|
||
*
|
||
* Caller(s) : Application.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (1) The size of the ASCII character array that will receive the return IP address ASCII
|
||
* string MUST be greater than or equal to NET_ASCII_LEN_MAX_ADDR_IP.
|
||
*
|
||
* See also 'net_ascii.c NetASCII_IP_to_Str() Note #2'.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_CHAR *NetIP_GetAddrStrDfltGateway (CPU_CHAR *paddr)
|
||
{
|
||
NET_IP_ADDR addr;
|
||
NET_ERR err;
|
||
|
||
|
||
addr = NetIP_GetAddrDfltGateway(); /* Get this host's dflt gateway IP addr. */
|
||
|
||
NetASCII_IP_to_Str(addr, paddr, DEF_NO, &err); /* Conv IP addr to IP addr str. */
|
||
if (err != NET_ASCII_ERR_NONE) { /* On any str err, ... */
|
||
*paddr = (CPU_CHAR )0; /* ... rtn NULL addr ... */
|
||
return ((CPU_CHAR *)0); /* ... & rtn NULL. */
|
||
}
|
||
|
||
return (paddr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_IsValidAddrHost()
|
||
*
|
||
* Description : (1) Validate an IP host address which MUST NOT be one of the following :
|
||
*
|
||
* (a) This Host RFC #1122, Section 3.2.1.3.(a)
|
||
* (b) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (c) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
* (d) Specified Host RFC #1122, Section 3.2.1.3.(b)
|
||
* (e) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
*
|
||
* (2) ONLY validates typical IP host addresses, since 'This Host' & 'Specified Host' IP host
|
||
* addresses are ONLY valid during a host's initialization (see Notes #1a & #1d). This
|
||
* function CANNOT be used to validate host addresses if any 'This Host' or 'Specified Host'
|
||
* host addresses are passed.
|
||
*
|
||
*
|
||
* Argument(s) : addr_host IP host address to validate.
|
||
*
|
||
* Return(s) : DEF_YES, if IP host address valid.
|
||
*
|
||
* DEF_NO, otherwise.
|
||
*
|
||
* Caller(s) : various.
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : (3) See 'net_ip.h IP ADDRESS DEFINES Notes #2, #3, & #4' for supported IP addresses.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
CPU_BOOLEAN NetIP_IsValidAddrHost (NET_IP_ADDR addr_host)
|
||
{
|
||
CPU_BOOLEAN valid;
|
||
|
||
|
||
valid = DEF_YES;
|
||
/* -------------- VALIDATE HOST ADDR -------------- */
|
||
/* Chk invalid 'This Host' (see Note #1a). */
|
||
if (addr_host == NET_IP_ADDR_THIS_HOST) {
|
||
valid = DEF_NO;
|
||
/* Chk invalid limited broadcast (see Note #1b). */
|
||
} else if (addr_host == NET_IP_ADDR_BROADCAST) {
|
||
valid = DEF_NO;
|
||
/* Chk invalid localhost (see Note #1c). */
|
||
} else if ((addr_host & NET_IP_ADDR_LOCAL_HOST_MASK) == NET_IP_ADDR_LOCAL_HOST) {
|
||
valid = DEF_NO;
|
||
|
||
} else if ((addr_host & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
/* Chk invalid Class-A specified (see Note #1d). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
/* Chk invalid Class-A broadcast (see Note #1e). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
|
||
} else if ((addr_host & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
/* Chk invalid Class-B specified (see Note #1d). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
/* Chk invalid Class-B broadcast (see Note #1e). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
|
||
} else if ((addr_host & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
/* Chk invalid Class-C specified (see Note #1d). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
/* Chk invalid Class-C broadcast (see Note #1e). */
|
||
if ((addr_host & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
valid = DEF_NO;
|
||
}
|
||
|
||
} else { /* Invalid addr class (see Note #3). */
|
||
valid = DEF_NO;
|
||
}
|
||
|
||
|
||
return (valid);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_IsValidAddrThisHost()
|
||
*
|
||
* Description : (1) Validate this host's IP address which MUST NOT be one of the following :
|
||
*
|
||
* (a) This Host RFC #1122, Section 3.2.1.3.(a)
|
||
* (b) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (c) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
* (d) Specified Host RFC #1122, Section 3.2.1.3.(b)
|
||
* (e) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
* (f) Subnet Broadcast RFC #1122, Section 3.2.1.3.(e)
|
||
*
|
||
* (2) ONLY validates this host's IP address, since 'This Host' & 'Specified Host' IP host
|
||
* addresses are ONLY valid during a host's initialization (see Notes #1a & #1d). This
|
||
* function CANNOT be used to validate host addresses if any 'This Host' or 'Specified Host'
|
||
* host addresses are passed.
|
||
*
|
||
*
|
||
* Argument(s) : addr_host IP host address to validate.
|
||
*
|
||
* addr_subnet_mask IP subnet mask.
|
||
*
|
||
* Return(s) : DEF_YES, if this host's IP address valid.
|
||
*
|
||
* DEF_NO, otherwise.
|
||
*
|
||
* Caller(s) : NetIP_CfgAddrThisHost().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : (3) See 'net_ip.h IP ADDRESS DEFINES Notes #2, #3, & #4' for supported IP addresses.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_BOOLEAN NetIP_IsValidAddrThisHost (NET_IP_ADDR addr_host,
|
||
NET_IP_ADDR addr_subnet_mask)
|
||
{
|
||
CPU_BOOLEAN valid_host;
|
||
CPU_BOOLEAN valid_mask;
|
||
CPU_BOOLEAN valid;
|
||
|
||
|
||
valid_host = NetIP_IsValidAddrHost(addr_host);
|
||
valid_mask = NetIP_IsValidAddrSubnetMask(addr_subnet_mask);
|
||
|
||
valid = ((valid_host == DEF_YES) &&
|
||
(valid_mask == DEF_YES)) ? DEF_YES : DEF_NO;
|
||
|
||
if (valid == DEF_YES) {
|
||
/* Chk invalid subnet specified (see Note #1d). */
|
||
if ((addr_host & addr_subnet_mask) == NET_IP_ADDR_THIS_HOST) {
|
||
valid = DEF_NO;
|
||
}
|
||
/* Chk invalid subnet broadcast (see Note #1f). */
|
||
if ((addr_host & addr_subnet_mask) == NET_IP_ADDR_BROADCAST) {
|
||
valid = DEF_NO;
|
||
}
|
||
}
|
||
|
||
|
||
return (valid);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_IsValidAddrSubnetMask()
|
||
*
|
||
* Description : (1) Validate an IP subnet mask :
|
||
*
|
||
* (a) RFC #1122, Section 3.2.1.3 states that ... :
|
||
*
|
||
* (1) "IP addresses are not permitted to have the value 0 or -1 for any of the ...
|
||
* <Subnet-number> fields" ...
|
||
* (2) "This implies that each of these fields will be at least two bits long."
|
||
*
|
||
* (b) RFC #950, Section 2.1 'Special Addresses' reiterates that "the values of all
|
||
* zeros and all ones in the subnet field should not be assigned to actual
|
||
* (physical) subnets".
|
||
*
|
||
* (c) RFC #950, Section 2.1 also states that "the bits that identify the subnet ...
|
||
* need not be adjacent in the address. However, we recommend that the subnet
|
||
* bits be contiguous and located as the most significant bits of the local
|
||
* address".
|
||
*
|
||
* See also 'net_ip.h IP ADDRESS DEFINES Note #3'.
|
||
*
|
||
* Argument(s) : addr_subnet_mask IP subnet mask to validate.
|
||
*
|
||
* Return(s) : DEF_YES, if IP subnet mask valid.
|
||
*
|
||
* DEF_NO, otherwise.
|
||
*
|
||
* Caller(s) : NetIP_IsValidAddrThisHost().
|
||
*
|
||
* This function is a network protocol suite application interface (API) function & MAY be
|
||
* called by application function(s).
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
CPU_BOOLEAN NetIP_IsValidAddrSubnetMask (NET_IP_ADDR addr_subnet_mask)
|
||
{
|
||
CPU_BOOLEAN valid;
|
||
NET_IP_ADDR mask;
|
||
CPU_INT08U mask_size;
|
||
CPU_INT08U mask_nbr_one_bits;
|
||
CPU_INT08U mask_nbr_one_bits_min;
|
||
CPU_INT08U mask_nbr_one_bits_max;
|
||
CPU_INT08U i;
|
||
|
||
/* ------------- VALIDATE SUBNET MASK ------------- */
|
||
/* Chk invalid subnet class (see Note #1c). */
|
||
if ((addr_subnet_mask & NET_IP_ADDR_CLASS_SUBNET_MASK) == NET_IP_ADDR_NONE) {
|
||
valid = DEF_NO;
|
||
|
||
} else { /* Chk invalid subnet mask (see Notes #1a & #1b). */
|
||
mask_size = sizeof(addr_subnet_mask) * DEF_OCTET_NBR_BITS;
|
||
mask = DEF_BIT_00;
|
||
mask_nbr_one_bits = 0;
|
||
for (i = 0; i < mask_size; i++) { /* Calc nbr subnet bits. */
|
||
if (addr_subnet_mask & mask) {
|
||
mask_nbr_one_bits++;
|
||
}
|
||
mask <<= 1;
|
||
}
|
||
|
||
mask_nbr_one_bits_min = 2; /* See Note #1a2. */
|
||
mask_nbr_one_bits_max = mask_size - mask_nbr_one_bits_min;
|
||
/* Chk invalid nbr subnet bits (see Note #1a2). */
|
||
if (mask_nbr_one_bits < mask_nbr_one_bits_min) {
|
||
valid = DEF_NO;
|
||
|
||
} else if (mask_nbr_one_bits > mask_nbr_one_bits_max) {
|
||
valid = DEF_NO;
|
||
|
||
} else {
|
||
valid = DEF_YES;
|
||
}
|
||
}
|
||
|
||
|
||
return (valid);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_Rx()
|
||
*
|
||
* Description : (1) Process received datagrams & forward to network protocol layers :
|
||
*
|
||
* (a) Validate IP packet & options
|
||
* (b) Reassemble fragmented datagrams
|
||
* (c) Demultiplex datagram to higher-layer protocols
|
||
* (d) Update receive statistics
|
||
*
|
||
* (2) Although IP data units are typically referred to as 'datagrams' (see RFC #791, Section 1.1),
|
||
* the term 'IP packet' (see RFC #1983, 'packet') is used for IP Receive until the packet is
|
||
* validated, & possibly reassembled, as an IP datagram.
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer that received IP packet.
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP datagram successfully received & processed.
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
*
|
||
* ----- RETURNED BY NetIP_RxPktDiscard() : -----
|
||
* NET_ERR_RX Receive error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIF_RxPktFrameDemux(),
|
||
* NetIP_TxPktDatagram().
|
||
*
|
||
* This function is a network protocol suite to network interface (IF) function & SHOULD be
|
||
* called only by appropriate network interface function(s).
|
||
*
|
||
* Note(s) : (3) NetIP_Rx() blocked until network initialization completes.
|
||
*
|
||
* (4) Since NetIP_RxPktFragReasm() may return a pointer to a different packet buffer (see
|
||
* 'NetIP_RxPktFragReasm() Return(s)', 'pbuf_hdr' MUST be reloaded.
|
||
*
|
||
* (5) (a) For single packet buffer IP datagrams, the datagram length is equal to the IP
|
||
* Total Length minus the IP Header Length.
|
||
*
|
||
* (b) For multiple packet buffer, fragmented IP datagrams, the datagram length is
|
||
* equal to the previously calculated total fragment size.
|
||
*
|
||
* (1) IP datagram length is stored ONLY in the first packet buffer of any
|
||
* fragmented packet buffers.
|
||
*
|
||
* (6) Network buffer already freed by higher layer; only increment error counter.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
void NetIP_Rx (NET_BUF *pbuf,
|
||
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;
|
||
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
|
||
if (Net_InitDone != DEF_YES) { /* If init NOT complete, exit rx (see Note #3). */
|
||
*perr = NET_ERR_INIT_INCOMPLETE;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------- */
|
||
if (pbuf == (NET_BUF *)0) {
|
||
NetIP_RxPktDiscard(pbuf, perr);
|
||
NET_CTR_ERR_INC(NetIP_ErrNullPtrCtr);
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
NET_CTR_STAT_INC(NetIP_StatRxPktCtr);
|
||
|
||
|
||
/* ------------------ VALIDATE IP PKT ----------------- */
|
||
pbuf_hdr = &pbuf->Hdr;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
NetIP_RxPktValidateBuf(pbuf_hdr, perr); /* Validate rx'd buf. */
|
||
switch (*perr) {
|
||
case NET_IP_ERR_NONE:
|
||
break;
|
||
|
||
|
||
case NET_ERR_INVALID_PROTOCOL:
|
||
case NET_BUF_ERR_INVALID_IX:
|
||
default:
|
||
NetIP_RxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
#endif
|
||
pip_hdr = (NET_IP_HDR *)&pbuf->Data[pbuf_hdr->IP_HdrIx];
|
||
NetIP_RxPktValidate(pbuf, pbuf_hdr, pip_hdr, perr); /* Validate rx'd pkt. */
|
||
|
||
|
||
/* ------------------- REASM FRAGS -------------------- */
|
||
switch (*perr) {
|
||
case NET_IP_ERR_NONE:
|
||
pbuf = NetIP_RxPktFragReasm(pbuf, pbuf_hdr, pip_hdr, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_ERR_INVALID_VER:
|
||
case NET_IP_ERR_INVALID_LEN_HDR:
|
||
case NET_IP_ERR_INVALID_LEN_TOT:
|
||
case NET_IP_ERR_INVALID_LEN_DATA:
|
||
case NET_IP_ERR_INVALID_FLAG:
|
||
case NET_IP_ERR_INVALID_FRAG:
|
||
case NET_IP_ERR_INVALID_PROTOCOL:
|
||
case NET_IP_ERR_INVALID_CHK_SUM:
|
||
case NET_IP_ERR_INVALID_ADDR_SRC:
|
||
case NET_IP_ERR_INVALID_ADDR_DEST:
|
||
case NET_IP_ERR_INVALID_OPT:
|
||
case NET_IP_ERR_INVALID_OPT_LEN:
|
||
case NET_IP_ERR_INVALID_OPT_NBR:
|
||
case NET_IP_ERR_INVALID_OPT_END:
|
||
case NET_IP_ERR_INVALID_OPT_FLAG:
|
||
case NET_IP_ERR_RX_OPT_BUF_NONE_AVAIL:
|
||
case NET_IP_ERR_RX_OPT_BUF_WR:
|
||
default:
|
||
NetIP_RxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/* -------------- DEMUX DATAGRAM -------------- */
|
||
switch (*perr) { /* Chk err from NetIP_RxPktFragReasm(). */
|
||
case NET_IP_ERR_RX_FRAG_NONE:
|
||
case NET_IP_ERR_RX_FRAG_COMPLETE:
|
||
pbuf_hdr = &pbuf->Hdr; /* Reload buf hdr ptr (see Note #4). */
|
||
if (*perr == NET_IP_ERR_RX_FRAG_NONE) { /* If pkt NOT frag'd, ... */
|
||
pbuf_hdr->IP_DatagramLen = pbuf_hdr->IP_TotLen /* ... calc buf datagram len (see Note #5a). */
|
||
- pbuf_hdr->IP_HdrLen;
|
||
} else { /* Else set tot frag size ... */
|
||
pbuf_hdr->IP_DatagramLen = pbuf_hdr->IP_FragSizeTot; /* ... as datagram len (see Note #5b). */
|
||
}
|
||
NetIP_RxPktDemuxDatagram(pbuf, pbuf_hdr, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_ERR_RX_FRAG_REASM: /* Frag'd datagram in reasm. */
|
||
*perr = NET_IP_ERR_NONE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
|
||
|
||
case NET_IP_ERR_RX_FRAG_DISCARD:
|
||
case NET_IP_ERR_RX_FRAG_OFFSET:
|
||
case NET_IP_ERR_RX_FRAG_SIZE:
|
||
case NET_IP_ERR_RX_FRAG_SIZE_TOT:
|
||
case NET_IP_ERR_RX_FRAG_LEN_TOT:
|
||
default:
|
||
NetIP_RxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
/* ----------------- UPDATE RX STATS ------------------ */
|
||
switch (*perr) { /* Chk err from NetIP_RxPktDemuxDatagram(). */
|
||
case NET_ICMP_ERR_NONE:
|
||
case NET_TCP_ERR_NONE:
|
||
case NET_UDP_ERR_NONE:
|
||
NET_CTR_STAT_INC(NetIP_StatRxDatagramProcessedCtr);
|
||
*perr = NET_IP_ERR_NONE;
|
||
break;
|
||
|
||
|
||
case NET_ERR_RX:
|
||
NET_CTR_ERR_INC(NetIP_ErrRxPktDiscardedCtr); /* See Note #6. */
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
|
||
|
||
case NET_ERR_INIT_INCOMPLETE:
|
||
case NET_ERR_INVALID_PROTOCOL:
|
||
default:
|
||
NetIP_RxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_Tx()
|
||
*
|
||
* Description : (1) Prepare & transmit packets from transport protocol layers to network interface layer :
|
||
*
|
||
* (a) Validate transmit packet
|
||
* (b) Prepare & transmit packet datagram
|
||
* (c) Update transmit statistics
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
*
|
||
* addr_src Source IP address.
|
||
*
|
||
* addr_dest Destination IP address.
|
||
*
|
||
* TOS Specific TOS to transmit IP packet
|
||
* (see 'net_ip.h IP HEADER TYPE OF SERVICE (TOS) DEFINES').
|
||
*
|
||
* TTL Specific TTL to transmit IP packet (see RFC #1122, Section 3.2.1.7) :
|
||
*
|
||
* NET_IP_HDR_TTL_MIN 1 minimum TTL transmit value
|
||
* NET_IP_HDR_TTL_MAX 255 maximum TTL transmit value
|
||
* NET_IP_HDR_TTL_DFLT default TTL transmit value
|
||
* NET_IP_HDR_TTL_NONE 0 replace with default TTL
|
||
*
|
||
* flags Flags to select transmit options; bit-field flags logically OR'd :
|
||
*
|
||
* NET_IP_FLAG_NONE No IP transmit flags selected.
|
||
* NET_IP_FLAG_TX_DONT_FRAG Set IP 'Don't Frag' flag.
|
||
*
|
||
* popts Pointer to one or more IP options configuration data structures :
|
||
*
|
||
* NULL NO IP transmit options configuration.
|
||
* NET_IP_OPT_CFG_ROUTE_TS Route &/or Internet Timestamp options configuration.
|
||
* NET_IP_OPT_CFG_SECURITY Security options configuration
|
||
* (see 'net_ip.c Note #1f').
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP datagram(s) successfully prepared & transmitted
|
||
* to network interface layer.
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
*
|
||
* ------- RETURNED BY NetIP_TxPktDiscard() : -------
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetICMP_TxMsgErr(),
|
||
* NetICMP_TxMsgReq(),
|
||
* NetICMP_TxMsgReply(),
|
||
* NetUDP_Tx(),
|
||
* NetTCP_TxPkt().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : (2) NetIP_Tx() blocked until network initialization completes.
|
||
*
|
||
* (3) Network buffer already freed by lower layer; only increment error counter.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
void NetIP_Tx (NET_BUF *pbuf,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
void *popts,
|
||
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;
|
||
|
||
|
||
#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) {
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
NET_CTR_ERR_INC(NetIP_ErrNullPtrCtr);
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
/* ---------------- VALIDATE TX IP PKT ---------------- */
|
||
pbuf_hdr = &pbuf->Hdr;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
NetIP_TxPktValidate(pbuf,
|
||
pbuf_hdr,
|
||
addr_src,
|
||
addr_dest,
|
||
TOS,
|
||
TTL,
|
||
flags,
|
||
popts,
|
||
perr);
|
||
switch (*perr) {
|
||
case NET_IP_ERR_NONE:
|
||
break;
|
||
|
||
|
||
case NET_ERR_INVALID_PROTOCOL:
|
||
case NET_BUF_ERR_INVALID_IX:
|
||
case NET_IP_ERR_INVALID_LEN_DATA:
|
||
case NET_IP_ERR_INVALID_TOS:
|
||
case NET_IP_ERR_INVALID_ADDR_SRC:
|
||
case NET_IP_ERR_INVALID_ADDR_DEST:
|
||
case NET_IP_ERR_INVALID_FLAG:
|
||
case NET_IP_ERR_INVALID_OPT_TYPE:
|
||
case NET_IP_ERR_INVALID_OPT_LEN:
|
||
case NET_IP_ERR_INVALID_OPT_CFG:
|
||
case NET_IP_ERR_INVALID_OPT_ROUTE:
|
||
default:
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/* -------------------- TX IP PKT --------------------- */
|
||
NetIP_TxPkt(pbuf,
|
||
pbuf_hdr,
|
||
addr_src,
|
||
addr_dest,
|
||
TOS,
|
||
TTL,
|
||
flags,
|
||
popts,
|
||
perr);
|
||
|
||
|
||
/* ----------------- UPDATE TX STATS ------------------ */
|
||
switch (*perr) {
|
||
case NET_IP_ERR_NONE:
|
||
case NET_IF_ERR_NONE:
|
||
NET_CTR_STAT_INC(NetIP_StatTxDatagramCtr);
|
||
*perr = NET_IP_ERR_NONE;
|
||
break;
|
||
|
||
|
||
case NET_ERR_RX:
|
||
case NET_ERR_TX:
|
||
NET_CTR_ERR_INC(NetIP_ErrTxPktDiscardedCtr); /* See Note #3. */
|
||
*perr = NET_ERR_TX;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
|
||
|
||
case NET_ERR_INIT_INCOMPLETE:
|
||
case NET_ERR_INVALID_PROTOCOL:
|
||
case NET_IP_ERR_INVALID_LEN_HDR:
|
||
case NET_IP_ERR_INVALID_FRAG:
|
||
case NET_IP_ERR_INVALID_OPT_TYPE:
|
||
case NET_IP_ERR_INVALID_OPT_LEN:
|
||
case NET_IP_ERR_TX_DEST_INVALID:
|
||
case NET_IP_ERR_INVALID_ADDR_HOST:
|
||
case NET_IP_ERR_INVALID_ADDR_NET:
|
||
case NET_IP_ERR_INVALID_ADDR_GATEWAY:
|
||
case NET_BUF_ERR_INVALID_IX:
|
||
case NET_BUF_ERR_INVALID_LEN:
|
||
case NET_UTIL_ERR_NULL_PTR:
|
||
case NET_UTIL_ERR_NULL_SIZE:
|
||
default:
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_ReTx()
|
||
*
|
||
* Description : (1) Prepare & re-transmit packets from transport protocol layers to network interface layer :
|
||
*
|
||
* (a) Validate re-transmit packet
|
||
* (b) Prepare & re-transmit packet datagram
|
||
* (c) Update re-transmit statistics
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to re-transmit IP packet.
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP datagram(s) successfully prepared & re-transmitted
|
||
* to network interface layer.
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
*
|
||
* -------- RETURNED BY NetIP_TxPktDiscard() : ---------
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetTCP_TxConnReTxQ_Timeout().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : (2) NetIP_ReTx() blocked until network initialization completes.
|
||
*
|
||
* (3) Network buffer already freed by lower layer; only increment error counter.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
void NetIP_ReTx (NET_BUF *pbuf,
|
||
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;
|
||
|
||
|
||
#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) {
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
NET_CTR_ERR_INC(NetIP_ErrNullPtrCtr);
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
/* -------------- VALIDATE RE-TX IP PKT --------------- */
|
||
pbuf_hdr = &pbuf->Hdr;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (pbuf_hdr->IP_HdrIx == NET_BUF_IX_NONE) {
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
NET_CTR_ERR_INC(NetIP_ErrTxInvalidBufIxCtr);
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
/* ------------------- RE-TX IP PKT ------------------- */
|
||
NetIP_ReTxPkt(pbuf,
|
||
pbuf_hdr,
|
||
perr);
|
||
|
||
|
||
/* ---------------- UPDATE RE-TX STATS ---------------- */
|
||
switch (*perr) {
|
||
case NET_IP_ERR_NONE:
|
||
case NET_IF_ERR_NONE:
|
||
NET_CTR_STAT_INC(NetIP_StatTxDatagramCtr);
|
||
*perr = NET_IP_ERR_NONE;
|
||
break;
|
||
|
||
|
||
case NET_ERR_RX:
|
||
case NET_ERR_TX:
|
||
NET_CTR_ERR_INC(NetIP_ErrTxPktDiscardedCtr); /* See Note #3. */
|
||
*perr = NET_ERR_TX;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
|
||
|
||
case NET_ERR_INIT_INCOMPLETE:
|
||
case NET_IP_ERR_TX_DEST_INVALID:
|
||
case NET_IP_ERR_INVALID_ADDR_HOST:
|
||
case NET_IP_ERR_INVALID_ADDR_NET:
|
||
case NET_IP_ERR_INVALID_ADDR_GATEWAY:
|
||
case NET_UTIL_ERR_NULL_PTR:
|
||
case NET_UTIL_ERR_NULL_SIZE:
|
||
default:
|
||
NetIP_TxPktDiscard(pbuf, perr);
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
*********************************************************************************************************
|
||
* LOCAL FUNCTIONS
|
||
*********************************************************************************************************
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktValidateBuf()
|
||
*
|
||
* Description : Validate received buffer header as IP protocol.
|
||
*
|
||
* Argument(s) : pbuf_hdr Pointer to network buffer header that received IP packet.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Received buffer's IP header validated.
|
||
* NET_ERR_INVALID_PROTOCOL Buffer's protocol type is NOT IP.
|
||
* NET_BUF_ERR_INVALID_IX Invalid buffer index.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Rx().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_RxPktValidateBuf (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
|
||
|
||
/* ---------------- VALIDATE IP BUF HDR --------------- */
|
||
if (pbuf_hdr->ProtocolHdrType != NET_PROTOCOL_TYPE_IP) {
|
||
NET_CTR_ERR_INC(Net_ErrInvalidProtocolCtr);
|
||
*perr = NET_ERR_INVALID_PROTOCOL;
|
||
return;
|
||
}
|
||
|
||
if (pbuf_hdr->IP_HdrIx == NET_BUF_IX_NONE) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxInvalidBufIxCtr);
|
||
*perr = NET_BUF_ERR_INVALID_IX;
|
||
return;
|
||
}
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktValidate()
|
||
*
|
||
* Description : (1) Validate received IP packet :
|
||
*
|
||
* (a) (1) Validate the received packet's following IP header fields :
|
||
*
|
||
* (A) Version
|
||
* (B) Header Length
|
||
* (C) Total Length See Note #4
|
||
* (D) Flags
|
||
* (E) Fragment Offset
|
||
* (F) Protocol
|
||
* (G) Check-Sum See Note #5
|
||
* (H) Source Address See Note #9c
|
||
* (I) Destination Address See Note #9d
|
||
* (J) Options
|
||
*
|
||
* (2) Validation ignores the following IP header fields :
|
||
*
|
||
* (A) Type of Service (TOS)
|
||
* (B) Identification (ID)
|
||
* (C) Time-to-Live (TTL)
|
||
*
|
||
* (b) Convert the following IP header fields from network-order to host-order :
|
||
*
|
||
* (1) Total Length See Notes #1bB1 & #3b
|
||
* (2) Identification (ID) See Note #1bB2
|
||
* (3) Flags/Fragment Offset See Note #1bB3
|
||
* (4) Check-Sum See Note #5d
|
||
* (5) Source Address See Notes #1bB4 & #3c
|
||
* (6) Destination Address See Notes #1bB5 & #3d
|
||
* (7) All Options' multi-octet words See Notes #1bB6 & #1bC
|
||
*
|
||
* (A) These fields are NOT converted directly in the received packet buffer's
|
||
* data area but are converted in local or network buffer variables ONLY.
|
||
*
|
||
* (B) The following IP header fields are converted & stored in network buffer
|
||
* variables :
|
||
*
|
||
* (1) Total Length
|
||
* (2) Identification (ID)
|
||
* (3) Flags/Fragment Offset
|
||
* (4) Source Address
|
||
* (5) Destination Address
|
||
* (6) IP Options' multi-octet words
|
||
*
|
||
* (C) Since any IP packet may receive a number of various IP options that may
|
||
* require conversion from network-order to host-order, IP options are copied
|
||
* into a separate network buffer for validation, conversion, & demultiplexing.
|
||
*
|
||
* (c) Update network buffer's protocol controls.
|
||
*
|
||
* (d) Process IP packet in ICMP Receive Handler.
|
||
*
|
||
*$PAGE*
|
||
* Argument(s) : pbuf Pointer to network buffer that received IP packet.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* pip_hdr Pointer to received packet's IP header.
|
||
* ------- Argument validated in NetIP_Rx()/NetIP_RxPktValidateBuf().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Received packet validated.
|
||
* NET_IP_ERR_INVALID_VER Invalid IP version.
|
||
* NET_IP_ERR_INVALID_LEN_HDR Invalid IP header length.
|
||
* NET_IP_ERR_INVALID_LEN_TOT Invalid IP total length.
|
||
* NET_IP_ERR_INVALID_LEN_DATA Invalid IP data length.
|
||
* NET_IP_ERR_INVALID_FLAG Invalid IP flags.
|
||
* NET_IP_ERR_INVALID_FRAG Invalid IP fragmentation.
|
||
* NET_IP_ERR_INVALID_PROTOCOL Invalid/unknown protocol type.
|
||
* NET_IP_ERR_INVALID_CHK_SUM Invalid IP check-sum.
|
||
* NET_IP_ERR_INVALID_ADDR_SRC Invalid IP source address.
|
||
* NET_IP_ERR_INVALID_ADDR_DEST Invalid IP destination address.
|
||
* NET_IP_ERR_INVALID_ADDR_BROADCAST Invalid IP broadcast.
|
||
*
|
||
* - RETURNED BY NetIP_RxPktValidateOpt() : --
|
||
* NET_IP_ERR_RX_OPT_BUF_NONE_AVAIL No available buffers to process IP options.
|
||
* NET_IP_ERR_RX_OPT_BUF_WR IP options failed to write to buffer.
|
||
* NET_IP_ERR_INVALID_OPT Invalid IP option.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
* NET_IP_ERR_INVALID_OPT_NBR Invalid IP option number of same option.
|
||
* NET_IP_ERR_INVALID_OPT_END Invalid IP option list ending.
|
||
* NET_IP_ERR_INVALID_OPT_FLAG Invalid IP option flag.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Rx().
|
||
*
|
||
* Note(s) : (2) See 'net_ip.h IP HEADER' for IP header format.
|
||
*
|
||
* (3) 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_icmp.c NetICMP_TxMsgErr() Note #3') :
|
||
*
|
||
* (a) Header Length
|
||
* (b) Total Length
|
||
* (c) Source Address
|
||
* (d) Destination Address
|
||
*
|
||
* (4) (a) In addition to validating that the IP header Total Length is greater than or equal to the
|
||
* IP header Header Length, the IP total length is compared to the remaining packet length
|
||
* which should be identical.
|
||
*
|
||
* (b) (1) However, some network interface frame types append 'pad' octets (octets with a dummy
|
||
* value to be ignored) if the data length for the frame does NOT meet the frame's
|
||
* required minimum size. Thus, if the IP total length is NOT greater than the frame's
|
||
* minimum size, then pad octets were appended & the IP total length CANNOT be compared.
|
||
*
|
||
* (2) If pad octets were appended to the total frame length, then the current data length
|
||
* may be greater than the IP datagram length. However, this value should be reset to
|
||
* the IP datagram's length to correctly calculate higher-layer application data length.
|
||
*
|
||
* (5) (a) IP 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 IP header 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, IP header Check-Sum may be validated
|
||
* at any point.
|
||
*
|
||
* (c) For convenience, the IP header Check-Sum is validated AFTER IP Version, Header Length,
|
||
* & Total Length fields have been validated. Thus, invalid IP version or length packets
|
||
* are quickly discarded (see Notes #9a, #8a, & #8b) & the total IP header length
|
||
* (in octets) will already be calculated for the IP Check-Sum calculation.
|
||
*
|
||
* (d) After the IP header Check-Sum is validated, it is NOT necessary to convert the Check-
|
||
* Sum from network-order to host-order since it is NOT required for further processing.
|
||
*$PAGE*
|
||
* (6) (a) RFC #791, Section 3.2 'Fragmentation and Reassembly' states that "if an internet datagram
|
||
* is fragmented" :
|
||
*
|
||
* (1) "Fragments are counted in units of 8 octets."
|
||
* (2) "The minimum fragment is 8 octets."
|
||
*
|
||
* (b) (1) However, this CANNOT apply "if this is the last fragment" ...
|
||
* (A) "(that is the more fragments field is zero)"; ...
|
||
* (2) Which may be of ANY size.
|
||
*
|
||
* See also 'net_ip.h IP FRAGMENTATION DEFINES Note #1a'.
|
||
*
|
||
* (7) (a) RFC #792, Section 'Destination Unreachable Message : Description' states that "if, in
|
||
* the destination host, the IP module cannot deliver the datagram because the indicated
|
||
* protocol module ... is not active, the destination host may send a destination unreachable
|
||
* message to the source host".
|
||
*
|
||
* (b) Default case already invalidated earlier in this function. However, the default case
|
||
* is included as an extra precaution in case 'Protocol' is incorrectly modified.
|
||
*
|
||
* (8) ICMP Error Messages are sent if any of the following IP header fields are invalid :
|
||
*
|
||
* (a) Header Length ICMP 'Parameter Problem' Error Message
|
||
* (b) Total Length ICMP 'Parameter Problem' Error Message
|
||
* (c) Flags ICMP 'Parameter Problem' Error Message
|
||
* (d) Fragment Offset ICMP 'Parameter Problem' Error Message
|
||
* (e) Protocol ICMP 'Unreachable Protocol' Error Message
|
||
* (f) Options ICMP 'Parameter Problem' Error Messages
|
||
* [see NetIP_RxPktValidateOpt()]
|
||
*
|
||
* (9) RFC #1122, Section 3.2.1 requires that IP packets with the following invalid IP header
|
||
* fields be "silently discarded" :
|
||
*
|
||
* (a) Version RFC #1122, Section 3.2.1.1
|
||
* (b) Check-Sum RFC #1122, Section 3.2.1.2
|
||
*
|
||
* (c) Source Address
|
||
* (1) MUST NOT be one of the following :
|
||
* (A) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (B) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
* (C) Subnet Broadcast RFC #1122, Section 3.2.1.3.(e)
|
||
* (D) Multicast RFC #1122, Section 3.2.1.3
|
||
* (2) SHOULD NOT be one of the following :
|
||
* (A) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
*
|
||
* (d) Destination Address
|
||
* (1) MUST be one of the following :
|
||
* (A) This host's RFC #1122, Section 3.2.1.3
|
||
* (B) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
* (C) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (D) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
* (E) Subnet Broadcast RFC #1122, Section 3.2.1.3.(e)
|
||
* (2) MUST NOT be one of the following :
|
||
* (A) This Host RFC #1122, Section 3.2.1.3.(a)
|
||
* (B) Specified Host RFC #1122, Section 3.2.1.3.(b)
|
||
*
|
||
* (3) (A) RFC #1122, Section 3.3.6 states that "when a host sends a datagram
|
||
* to a link-layer broadcast address, the IP destination address MUST
|
||
* be a legal IP broadcast or IP multicast address".
|
||
*
|
||
* Thus, any packet received as an IP broadcast destination address
|
||
* MUST also have been received as a link-layer broadcast.
|
||
*
|
||
* (B) RFC #1122, Section 3.3.6 further states that "a host SHOULD silently
|
||
* discard a datagram that is received via a link-layer broadcast ...
|
||
* but does not specify an IP multicast or broadcast destination address".
|
||
*
|
||
* Thus, any packet received as a link-layer broadcast MUST also be
|
||
* received as an IP broadcast.
|
||
*
|
||
* (C) Therefore, any packet received as EITHER a link-layer broadcast or
|
||
* an IP broadcast, but not BOTH, MUST be silently discarded.
|
||
*
|
||
* (10) See 'net_ip.h IP ADDRESS DEFINES Notes #2, #3, & #4' for supported IP addresses.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_RxPktValidate (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_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_ERR msg_err;
|
||
CPU_INT08U ip_ver;
|
||
CPU_INT08U ip_hdr_len;
|
||
CPU_INT16U ip_hdr_len_tot;
|
||
CPU_INT16U ip_flags;
|
||
CPU_INT16U ip_frag_offset;
|
||
CPU_INT16U protocol_ix;
|
||
CPU_BOOLEAN ip_flag_reserved;
|
||
CPU_BOOLEAN ip_flag_dont_frag;
|
||
CPU_BOOLEAN ip_flag_frags_more;
|
||
CPU_BOOLEAN ip_chk_sum_valid;
|
||
CPU_BOOLEAN ip_broadcast;
|
||
CPU_BOOLEAN rx_broadcast;
|
||
|
||
|
||
/* ---------------- CONVERT IP FIELDS ----------------- */
|
||
/* See Note #3. */
|
||
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->IP_TotLen, &pip_hdr->TotLen);
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&pbuf_hdr->IP_AddrSrc, &pip_hdr->AddrSrc);
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&pbuf_hdr->IP_AddrDest, &pip_hdr->AddrDest);
|
||
|
||
|
||
|
||
/* ----------------- VALIDATE IP VER ------------------ */
|
||
ip_ver = pip_hdr->Ver_HdrLen & NET_IP_HDR_VER_MASK; /* See 'net_ip.h IP HEADER Note #2'. */
|
||
ip_ver >>= NET_IP_HDR_VER_SHIFT;
|
||
if (ip_ver != NET_IP_HDR_VER) { /* Validate IP ver. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrVerCtr);
|
||
*perr = NET_IP_ERR_INVALID_VER;
|
||
return;
|
||
}
|
||
|
||
|
||
/* --------------- VALIDATE IP HDR LEN ---------------- */
|
||
/* See 'net_ip.h IP HEADER Note #2'. */
|
||
ip_hdr_len = pip_hdr->Ver_HdrLen & NET_IP_HDR_LEN_MASK;
|
||
ip_hdr_len_tot = (CPU_INT16U)ip_hdr_len * NET_IP_HDR_LEN_WORD_SIZE;
|
||
pbuf_hdr->IP_HdrLen = (CPU_INT16U)ip_hdr_len_tot; /* See Note #3a. */
|
||
|
||
if (ip_hdr_len < NET_IP_HDR_LEN_MIN) { /* If hdr len < min hdr len, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrLenCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_HDR_LEN, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_LEN_HDR;
|
||
return;
|
||
}
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (ip_hdr_len > NET_IP_HDR_LEN_MAX) { /* If hdr len > max hdr len, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrLenCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_HDR_LEN, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_LEN_HDR;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
/* --------------- VALIDATE IP TOT LEN ---------------- */
|
||
#if 0 /* See Note #3b. */
|
||
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->IP_TotLen, &pip_hdr->TotLen);
|
||
#endif
|
||
if (pbuf_hdr->IP_TotLen < ip_hdr_len_tot) { /* If IP tot len < hdr len, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrTotLenCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_TOT_LEN, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_LEN_TOT;
|
||
return;
|
||
}
|
||
|
||
if (pbuf_hdr->IP_TotLen >= pbuf_hdr->IF_DataLenMin) { /* If IP tot len >= min net IF data size & ... */
|
||
if (pbuf_hdr->IP_TotLen != pbuf_hdr->DataLen) { /* .. IP tot len != rem pkt len, rtn err (see Note #4). */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrTotLenCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_TOT_LEN, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_LEN_TOT;
|
||
return;
|
||
}
|
||
} else { /* Else reset data len to IP tot len (see Note #4b2). */
|
||
pbuf_hdr->DataLen = (NET_BUF_SIZE)pbuf_hdr->IP_TotLen;
|
||
}
|
||
|
||
pbuf_hdr->IP_DataLen = pbuf_hdr->IP_TotLen - pbuf_hdr->IP_HdrLen;
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ---------------- VALIDATE IP CHK SUM --------------- */
|
||
/* See Note #5. */
|
||
ip_chk_sum_valid = NetUtil_16BitOnesCplChkSumHdrVerify((void *)pip_hdr,
|
||
(CPU_INT16U)ip_hdr_len_tot,
|
||
(NET_ERR *)perr);
|
||
if (ip_chk_sum_valid != DEF_OK) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrChkSumCtr);
|
||
*perr = NET_IP_ERR_INVALID_CHK_SUM;
|
||
return;
|
||
}
|
||
#if 0 /* Conv to host-order NOT necessary (see Note #5d). */
|
||
(void)NET_UTIL_VAL_GET_NET_16(&pip_hdr->ChkSum);
|
||
#endif
|
||
|
||
|
||
|
||
/* ------------------ CONVERT IP ID ------------------- */
|
||
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->IP_ID, &pip_hdr->ID);
|
||
|
||
|
||
/* ---------------- VALIDATE IP FLAGS ----------------- */
|
||
/* See 'net_ip.h IP HEADER Note #4'. */
|
||
NET_UTIL_VAL_COPY_GET_NET_16(&pbuf_hdr->IP_Flags_FragOffset, &pip_hdr->Flags_FragOffset);
|
||
ip_flags = pbuf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FLAG_MASK;
|
||
#if 1 /* ???? Allow invalid reserved flag for rx'd datagrams? */
|
||
ip_flag_reserved = DEF_BIT_IS_SET_ANY(ip_flags, NET_IP_HDR_FLAG_RESERVED);
|
||
if (ip_flag_reserved != DEF_NO) { /* If reserved flag bit set, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrFlagsCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_FLAGS, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_FLAG;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
/* ----------------- VALIDATE IP FRAG ----------------- */
|
||
/* See 'net_ip.h IP HEADER Note #4'. */
|
||
ip_flag_dont_frag = DEF_BIT_IS_SET(ip_flags, NET_IP_HDR_FLAG_FRAG_DONT);
|
||
ip_flag_frags_more = DEF_BIT_IS_SET(ip_flags, NET_IP_HDR_FLAG_FRAG_MORE);
|
||
if (ip_flag_dont_frag != DEF_NO) { /* If 'Don't Frag' flag set & ... */
|
||
if (ip_flag_frags_more != DEF_NO) { /* ... 'More Frags' flag set, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrFragCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_FRAG_OFFSET, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_FRAG;
|
||
return;
|
||
}
|
||
|
||
ip_frag_offset = pbuf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FRAG_OFFSET_MASK;
|
||
if (ip_frag_offset != NET_IP_HDR_FRAG_OFFSET_NONE) { /* ... frag offset != 0, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrFragCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_FRAG_OFFSET, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_FRAG;
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (ip_flag_frags_more != DEF_NO) { /* If 'More Frags' set (see Note #6b1A) ... */
|
||
/* ... & IP data len NOT multiple of ... */
|
||
if ((pbuf_hdr->IP_DataLen % NET_IP_FRAG_SIZE_UNIT) != 0) { /* ... frag size units (see Note #6a), rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrFragCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_TOT_LEN, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_FRAG;
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* --------------- VALIDATE IP PROTOCOL --------------- */
|
||
switch (pip_hdr->Protocol) { /* See 'net_ip.h IP HEADER Note #5'. */
|
||
case NET_IP_HDR_PROTOCOL_ICMP:
|
||
case NET_IP_HDR_PROTOCOL_TCP:
|
||
case NET_IP_HDR_PROTOCOL_UDP:
|
||
break;
|
||
|
||
|
||
default: /* See Note #7a. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrProtocolCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_DEST_UNREACH, NET_ICMP_MSG_CODE_DEST_PROTOCOL, NET_ICMP_MSG_PTR_NONE, &msg_err);
|
||
*perr = NET_IP_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------- VALIDATE IP SRC ADDR ------------- */
|
||
/* See Note #9c. */
|
||
#if 0 /* See Note #3c. */
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&pbuf_hdr->IP_AddrSrc, &pip_hdr->AddrSrc);
|
||
#endif
|
||
/* Chk invalid localhost (see Note #9c2A). */
|
||
if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_LOCAL_HOST_MASK) == NET_IP_ADDR_LOCAL_HOST) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
/* Chk invalid limited broadcast (see Note #9c1A). */
|
||
if (pbuf_hdr->IP_AddrSrc == NET_IP_ADDR_BROADCAST) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
/* Chk invalid Class-A broadcast (see Note #9c1B). */
|
||
if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
/* Chk invalid Class-B broadcast (see Note #9c1B). */
|
||
if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
/* Chk invalid Class-C broadcast (see Note #9c1B). */
|
||
if ((pbuf_hdr->IP_AddrSrc & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else { /* Discard invalid addr class (see Note #10). */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
/* Chk invalid subnet broadcast (see Note #9c1C). */
|
||
if (NetIP_AddrThisHostSubnetMask != NET_IP_ADDR_NONE) {
|
||
if ((pbuf_hdr->IP_AddrSrc & NetIP_AddrThisHostSubnetMask) ==
|
||
NetIP_AddrThisHostSubnetNet ) {
|
||
if ((pbuf_hdr->IP_AddrSrc & NetIP_AddrThisHostSubnetMaskHost) ==
|
||
(NET_IP_ADDR_BROADCAST & NetIP_AddrThisHostSubnetMaskHost)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------- VALIDATE IP DEST ADDR ------------ */
|
||
/* See Note #9d. */
|
||
#if 0 /* See Note #3d. */
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&pbuf_hdr->IP_AddrDest, &pip_hdr->AddrDest);
|
||
#endif
|
||
ip_broadcast = DEF_NO;
|
||
|
||
if (pbuf_hdr->IP_AddrDest == NetIP_AddrThisHost) { /* Chk this host's addr (see Note #9d1A). */
|
||
|
||
if (NetIP_AddrThisHost == NET_IP_ADDR_NONE) { /* Chk invalid 'This Host' (see Note #9d2A). */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
} else {
|
||
/* Chk localhost (see Note #9d1B). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_LOCAL_HOST_MASK) == NET_IP_ADDR_LOCAL_HOST) {
|
||
/* Chk localhost invalid addrs. */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_LOCAL_HOST_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_LOCAL_HOST_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_LOCAL_HOST_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_LOCAL_HOST_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
NET_CTR_STAT_INC(NetIP_StatRxDestLocalCtr);
|
||
|
||
|
||
} else {
|
||
/* Chk invalid 'This Host' (see Note #9d2A). */
|
||
if (pbuf_hdr->IP_AddrDest == NET_IP_ADDR_THIS_HOST) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/*$PAGE*/
|
||
/* Chk limited broadcast (see Note #9d1C). */
|
||
if (pbuf_hdr->IP_AddrDest != NET_IP_ADDR_BROADCAST) {
|
||
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
/* Chk Class-A specified host (see Note #9d2B). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/* Chk Class-A broadcast (see Note #9d1D). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
ip_broadcast = DEF_YES;
|
||
}
|
||
|
||
} else if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
/* Chk Class-B specified host (see Note #9d2B). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/* Chk Class-B broadcast (see Note #9d1D). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
ip_broadcast = DEF_YES;
|
||
}
|
||
|
||
} else if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
/* Chk Class-C specified host (see Note #9d2B). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/* Chk Class-C broadcast (see Note #9d1D). */
|
||
if ((pbuf_hdr->IP_AddrDest & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
ip_broadcast = DEF_YES;
|
||
}
|
||
|
||
} else { /* Discard invalid addr class (see Note #10). */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
/* Chk subnet broadcast (see Note #9d1E). */
|
||
if ((pbuf_hdr->IP_AddrDest & NetIP_AddrThisHostSubnetMask) ==
|
||
NetIP_AddrThisHostSubnetNet ) {
|
||
if ((pbuf_hdr->IP_AddrDest & NetIP_AddrThisHostSubnetMaskHost) ==
|
||
(NET_IP_ADDR_BROADCAST & NetIP_AddrThisHostSubnetMaskHost)) {
|
||
ip_broadcast = DEF_YES;
|
||
}
|
||
}
|
||
|
||
} else {
|
||
ip_broadcast = DEF_YES;
|
||
}
|
||
|
||
/* If NOT this host's or localhost addr, ... */
|
||
if (ip_broadcast != DEF_YES) { /* ... & NOT broadcast addr; ... */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST; /* ... rtn err. */
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* Chk invalid broadcast (see Note #9d3). */
|
||
rx_broadcast = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_RX);
|
||
if (ip_broadcast == DEF_NO) { /* If IP broadcast rx'd ... */
|
||
if (rx_broadcast != DEF_NO) { /* ... NOT also net IF broadcast rx'd, ... */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestBroadcastCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_BROADCAST; /* ... rtn err. */
|
||
return;
|
||
}
|
||
} else { /* If NO IP broadcast rx'd ... */
|
||
if (rx_broadcast != DEF_YES) { /* ... BUT net IF broadcast rx'd, ... */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxDestBroadcastCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_BROADCAST; /* ... rtn err. */
|
||
return;
|
||
}
|
||
NET_CTR_STAT_INC(NetIP_StatRxDestBroadcastCtr);
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ----------------- VALIDATE IP OPTS ----------------- */
|
||
if (ip_hdr_len_tot > NET_IP_HDR_SIZE_MIN) { /* If hdr len > min, validate/process IP opts. */
|
||
NetIP_RxPktValidateOpt((NET_BUF *)pbuf,
|
||
(NET_BUF_HDR *)pbuf_hdr,
|
||
(NET_IP_HDR *)pip_hdr,
|
||
(CPU_INT08U )ip_hdr_len_tot,
|
||
(NET_ERR *)perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ----------------- UPDATE BUF CTRLS ----------------- */
|
||
#if 0 /* See Note #3a. */
|
||
pbuf_hdr->IP_HdrLen = ip_hdr_len_tot;
|
||
#endif
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (pbuf_hdr->IP_HdrLen > pbuf_hdr->DataLen) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrDataLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_LEN_DATA;
|
||
return;
|
||
}
|
||
#endif
|
||
pbuf_hdr->DataLen -= (NET_BUF_SIZE) pbuf_hdr->IP_HdrLen;
|
||
protocol_ix = (CPU_INT16U )(pbuf_hdr->IP_HdrIx + pbuf_hdr->IP_HdrLen);
|
||
switch (pip_hdr->Protocol) {
|
||
case NET_IP_HDR_PROTOCOL_ICMP:
|
||
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_ICMP;
|
||
pbuf_hdr->ICMP_MsgIx = protocol_ix;
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_PROTOCOL_TCP:
|
||
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_TCP;
|
||
pbuf_hdr->TCP_UDP_HdrDataIx = protocol_ix;
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_PROTOCOL_UDP:
|
||
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_UDP;
|
||
pbuf_hdr->TCP_UDP_HdrDataIx = protocol_ix;
|
||
break;
|
||
|
||
|
||
default: /* See Note #7b. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrProtocolCtr);
|
||
*perr = NET_IP_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
|
||
/* ------------------ ICMP RX HANDLER ----------------- */
|
||
NetICMP_HandlerRx(pbuf);
|
||
|
||
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktValidateOpt()
|
||
*
|
||
* Description : (1) Validate & process received packet's IP options :
|
||
*
|
||
* (a) Get buffer to process IP options See 'NetIP_RxPktValidate() Note #1bC'
|
||
* (b) Decode/validate IP options
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer that received IP packet.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* pip_hdr Pointer to received packet's IP header.
|
||
* ------- Argument validated in NetIP_Rx()/NetIP_RxPktValidateBuf().
|
||
*
|
||
* ip_hdr_len_size Length of received packet's IP header.
|
||
* --------------- Argument validated in NetIP_RxPktValidate().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP options validated & processed.
|
||
* NET_IP_ERR_RX_OPT_BUF_NONE_AVAIL No available buffers to process IP options.
|
||
* NET_IP_ERR_RX_OPT_BUF_WR IP options failed to write to buffer.
|
||
* NET_IP_ERR_INVALID_OPT Invalid IP option.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
* NET_IP_ERR_INVALID_OPT_NBR Invalid IP option number of same option.
|
||
* NET_IP_ERR_INVALID_OPT_END Invalid IP option list ending.
|
||
* NET_IP_ERR_INVALID_OPT_FLAG Invalid IP option flag.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_RxPktValidate().
|
||
*
|
||
* Note(s) : (2) (a) See 'net_ip.h IP HEADER OPTIONS DEFINES' for supported IP options' summary.
|
||
*
|
||
* (b) See 'net_ip.c Note #5' for unsupported IP options.
|
||
*
|
||
* (3) RFC #1122, Section 3.2.1.8 lists the processing of the following IP options as optional :
|
||
*
|
||
* (a) Record Route RFC #1122, Section 3.2.1.8.(d)
|
||
* (b) Internet Timestamp RFC #1122, Section 3.2.1.8.(e)
|
||
*
|
||
* (4) Each option's length MUST be multiples of NET_IP_HDR_OPT_SIZE_WORD octets so that "the
|
||
* beginning of a subsequent option [aligns] on a 32-bit boundary" (RFC #791, Section 3.1
|
||
* 'Options : No Operation').
|
||
*
|
||
* (5) RFC #1122, Section 3.2.1.8.(c) prohibits "an IP header" from transmitting with "more
|
||
* than one Source Route option".
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_RxPktValidateOpt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_hdr,
|
||
CPU_INT08U ip_hdr_len_size,
|
||
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
|
||
NET_ERR err;
|
||
NET_BUF *popt_buf;
|
||
NET_BUF_HDR *popt_buf_hdr;
|
||
CPU_INT08U *popts;
|
||
CPU_INT08U opt_list_len_size;
|
||
CPU_INT08U opt_list_len_rem;
|
||
CPU_INT08U opt_len;
|
||
CPU_INT08U opt_nbr_src_routes;
|
||
CPU_INT08U opt_ix_err;
|
||
CPU_INT16U opt_ix;
|
||
CPU_BOOLEAN opt_err;
|
||
CPU_BOOLEAN opt_list_end;
|
||
|
||
|
||
opt_list_len_size = ip_hdr_len_size - NET_IP_HDR_SIZE_MIN; /* Calc opt list len size. */
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ----------- VALIDATE IP HDR OPT LIST SIZE ---------- */
|
||
if (opt_list_len_size > NET_IP_HDR_OPT_SIZE_MAX) { /* If tot opt len > max opt size, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrOptsCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_OPTS, &err);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return;
|
||
}
|
||
|
||
if ((opt_list_len_size % NET_IP_HDR_OPT_SIZE_WORD) != 0) { /* If tot opt len NOT multiple of opt size, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrOptsCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, NET_ICMP_PTR_IX_IP_HDR_OPTS, &err);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
/* ------------ GET BUF TO PROCESS IP OPTS ------------ */
|
||
opt_ix = NET_IP_OPT_IX_RX;
|
||
popt_buf = NetBuf_Get((NET_BUF_SIZE) opt_list_len_size,
|
||
(NET_BUF_SIZE) opt_ix,
|
||
(CPU_INT16U ) NET_BUF_FLAG_NONE,
|
||
(NET_ERR *)&err);
|
||
if (err != NET_BUF_ERR_NONE) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrOptsBufNoneAvailCtr);
|
||
*perr = NET_IP_ERR_RX_OPT_BUF_NONE_AVAIL;
|
||
return;
|
||
}
|
||
|
||
NetBuf_DataWr((NET_BUF *) popt_buf, /* Copy IP opts from rx'd pkt to IP opt buf. */
|
||
(NET_BUF_SIZE) opt_ix,
|
||
(NET_BUF_SIZE) opt_list_len_size,
|
||
(CPU_INT08U *)&pip_hdr->Opts[0],
|
||
(NET_ERR *)&err);
|
||
if (err != NET_BUF_ERR_NONE) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrOptsBufWrCtr);
|
||
*perr = NET_IP_ERR_RX_OPT_BUF_WR;
|
||
return;
|
||
}
|
||
/* Init IP opt buf ctrls. */
|
||
pbuf_hdr->IP_OptPtr = (void *) popt_buf;
|
||
popt_buf_hdr = (NET_BUF_HDR *)&popt_buf->Hdr;
|
||
popt_buf_hdr->IP_HdrIx = (CPU_INT16U ) opt_ix;
|
||
popt_buf_hdr->IP_HdrLen = (CPU_INT16U ) opt_list_len_size;
|
||
popt_buf_hdr->TotLen = (NET_BUF_SIZE ) popt_buf_hdr->IP_HdrLen;
|
||
popt_buf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_IP_OPT;
|
||
|
||
|
||
/*$PAGE*/
|
||
opt_err = DEF_NO;
|
||
opt_list_end = DEF_NO;
|
||
opt_nbr_src_routes = 0;
|
||
|
||
popts = (CPU_INT08U *)&popt_buf->Data[opt_ix];
|
||
opt_list_len_rem = opt_list_len_size;
|
||
|
||
/* ------------- DECODE/VALIDATE IP OPTS -------------- */
|
||
while (opt_list_len_rem > 0) { /* Process each opt in list (see Notes #2 & #4). */
|
||
switch (*popts) {
|
||
case NET_IP_HDR_OPT_END_LIST: /* ------------------- END OPT LIST ------------------- */
|
||
opt_list_end = DEF_YES; /* Mark end of opt list. */
|
||
opt_len = NET_IP_HDR_OPT_SIZE_WORD;
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_OPT_NOP: /* --------------------- NOP OPT ---------------------- */
|
||
opt_len = NET_IP_HDR_OPT_SIZE_WORD;
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_LOOSE: /* ---------------- SRC/REC ROUTE OPTS ---------------- */
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_STRICT:
|
||
case NET_IP_HDR_OPT_ROUTE_REC:
|
||
if (opt_list_end == DEF_NO) {
|
||
if (opt_nbr_src_routes < 1) {
|
||
opt_nbr_src_routes++;
|
||
opt_err = NetIP_RxPktValidateOptRoute(popts, opt_list_len_rem, &opt_len, perr);
|
||
|
||
} else { /* If > 1 src route opt, rtn err (see Note #5). */
|
||
*perr = NET_IP_ERR_INVALID_OPT_NBR;
|
||
opt_err = DEF_YES;
|
||
}
|
||
} else { /* If opt found AFTER end of opt list, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_END;
|
||
opt_err = DEF_YES;
|
||
}
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_OPT_TS: /* --------------------- TS OPTS ---------------------- */
|
||
if (opt_list_end == DEF_NO) {
|
||
opt_err = NetIP_RxPktValidateOptTS(popts, opt_list_len_rem, &opt_len, perr);
|
||
|
||
} else { /* If opt found AFTER end of opt list, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_END;
|
||
opt_err = DEF_YES;
|
||
}
|
||
break;
|
||
|
||
#if 0 /* ----------------- UNSUPPORTED OPTS ----------------- */
|
||
/* See Note #2b. */
|
||
case NET_IP_HDR_OPT_SECURITY:
|
||
case NET_IP_HDR_OPT_SECURITY_EXTENDED:
|
||
/* 'break' intentionally omitted; do NOT move from the */
|
||
/* ... following case : 'default'. */
|
||
#endif
|
||
|
||
default: /* ------------------- INVALID OPTS ------------------- */
|
||
*perr = NET_IP_ERR_INVALID_OPT;
|
||
opt_err = DEF_YES;
|
||
break;
|
||
}
|
||
|
||
if (opt_err == DEF_NO) {
|
||
if (opt_list_len_rem >= opt_len) {
|
||
opt_list_len_rem -= opt_len;
|
||
popts += opt_len;
|
||
} else { /* If rem opt list len NOT multiple of opt size, ... */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN; /* ... rtn err. */
|
||
opt_err = DEF_YES;
|
||
}
|
||
}
|
||
|
||
if (opt_err != DEF_NO) { /* If ANY opt errs, tx ICMP err msg. */
|
||
opt_ix_err = NET_ICMP_PTR_IX_IP_HDR_OPTS + (opt_list_len_size - opt_list_len_rem);
|
||
NET_CTR_ERR_INC(NetIP_ErrRxHdrOptsCtr);
|
||
NetICMP_TxMsgErr(pbuf, NET_ICMP_MSG_TYPE_PARAM_PROB, NET_ICMP_MSG_CODE_PARAM_PROB_IP_HDR, opt_ix_err, &err);
|
||
return;
|
||
}
|
||
}
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktValidateOptRoute()
|
||
*
|
||
* Description : (1) Validate & process Source Route options :
|
||
*
|
||
* (a) Convert ALL Source Route IP addresses from network-order to host-order
|
||
* (b) Add this host's IP address to Source Route
|
||
*
|
||
* (2) See 'net_ip.h IP SOURCE ROUTE OPTION DATA TYPE' for Source Route options summary.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to Source Route option.
|
||
* ----- Argument validated in NetIP_RxPktValidateOpt().
|
||
*
|
||
* opt_list_len_rem Remaining option list length (in octets).
|
||
*
|
||
* popt_len Pointer to variable that will receive the Source Route option length (in octets).
|
||
* -------- Argument validated in NetIP_RxPktValidateOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Source Route IP option validated & processed.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
*
|
||
* Return(s) : DEF_NO, NO Source Route option error.
|
||
*
|
||
* DEF_YES, otherwise.
|
||
*
|
||
* Caller(s) : NetIP_RxPktValidateOpt().
|
||
*
|
||
* Note(s) : (3) If Source Route option appends this host's IP address to the source route, the IP
|
||
* header check-sum is NOT re-calculated since the check-sum was previously validated
|
||
* in NetIP_RxPktValidate() & is NOT required for further validation or processing.
|
||
*
|
||
* (4) Default case already invalidated earlier in this function. However, the default
|
||
* case is included as an extra precaution in case any of the IP receive options is
|
||
* incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static CPU_BOOLEAN NetIP_RxPktValidateOptRoute (CPU_INT08U *popts,
|
||
CPU_INT08U opt_list_len_rem,
|
||
CPU_INT08U *popt_len,
|
||
NET_ERR *perr)
|
||
{
|
||
NET_IP_OPT_SRC_ROUTE *popt_route;
|
||
NET_IP_ADDR opt_addr;
|
||
CPU_INT08U opt_ptr;
|
||
CPU_INT08U opt_ix;
|
||
|
||
|
||
popt_route = (NET_IP_OPT_SRC_ROUTE *)popts;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ----------------- VALIDATE OPT TYPE ---------------- */
|
||
switch (popt_route->Type) {
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_LOOSE:
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_STRICT:
|
||
case NET_IP_HDR_OPT_ROUTE_REC:
|
||
break;
|
||
|
||
|
||
default:
|
||
*perr = NET_IP_ERR_INVALID_OPT;
|
||
return (DEF_YES); /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
#endif
|
||
|
||
/* ----------------- VALIDATE OPT LEN ----------------- */
|
||
if (popt_route->Ptr > popt_route->Len) { /* If ptr exceeds opt len, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
if (popt_route->Len > opt_list_len_rem) { /* If opt len exceeds rem opt len, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
if ((popt_route->Len % NET_IP_HDR_OPT_SIZE_WORD) != 0) { /* If opt len NOT multiple of opt size, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
|
||
opt_ptr = NET_IP_OPT_ROUTE_PTR_ROUTE;
|
||
opt_ix = 0;
|
||
|
||
/* --------------- CONVERT TO HOST-ORDER -------------- */
|
||
while (opt_ptr < popt_route->Ptr) { /* Convert ALL src route addrs to host-order. */
|
||
popt_route->Route[opt_ix] = NET_UTIL_NET_TO_HOST_32(popt_route->Route[opt_ix]);
|
||
opt_ptr += NET_IP_HDR_OPT_SIZE_WORD;
|
||
opt_ix++;
|
||
}
|
||
|
||
/* ------------------- INSERT ROUTE ------------------- */
|
||
if (popt_route->Ptr < popt_route->Len) { /* If ptr < len, append this host addr to src route. */
|
||
switch (*popts) {
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_LOOSE:
|
||
case NET_IP_HDR_OPT_ROUTE_REC:
|
||
opt_addr = NetIP_AddrThisHost;
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&popt_route->Route[opt_ix], &opt_addr);
|
||
popt_route->Ptr += NET_IP_HDR_OPT_SIZE_WORD;
|
||
break;
|
||
|
||
|
||
case NET_IP_HDR_OPT_ROUTE_SRC_STRICT:
|
||
break;
|
||
|
||
|
||
default: /* See Note #4. */
|
||
*perr = NET_IP_ERR_INVALID_OPT;
|
||
return (DEF_YES); /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
*popt_len = popt_route->Len; /* Rtn src route opt len. */
|
||
*perr = NET_IP_ERR_NONE;
|
||
|
||
return (DEF_NO);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktValidateOptTS()
|
||
*
|
||
* Description : (1) Validate & process Internet Timestamp options :
|
||
*
|
||
* (a) Convert ALL Internet Timestamps & Source Route IP addresses from network-order
|
||
* to host-order
|
||
* (b) Add current Internet Timestamp & this host's IP address to Internet Timestamp
|
||
*
|
||
* (2) See 'net_ip.h IP INTERNET TIMESTAMP OPTION DATA TYPE' for Internet Timestamp options summary.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to Internet Timestamp option.
|
||
* ----- Argument validated in NetIP_RxPktValidateOpt().
|
||
*
|
||
* opt_list_len_rem Remaining option list length (in octets).
|
||
*
|
||
* popt_len Pointer to variable that will return the Internet Timestamp option length
|
||
* -------- (in octets).
|
||
*
|
||
* Argument validated in NetIP_RxPktValidateOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Internet Timestamp IP option validated
|
||
* & processed.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
*
|
||
* Return(s) : DEF_NO, NO Internet Timestamp option error.
|
||
*
|
||
* DEF_YES, otherwise.
|
||
*
|
||
* Caller(s) : NetIP_RxPktValidateOpt().
|
||
*
|
||
* Note(s) : (3) If Internet Timestamp option appends the current Internet Timestamp &/or this host's
|
||
* IP address to the Internet Timestamp, the IP header check-sum is NOT re-calculated
|
||
* since the check-sum was previously validated in NetIP_RxPktValidate() & is NOT
|
||
* required for further validation or processing.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static CPU_BOOLEAN NetIP_RxPktValidateOptTS (CPU_INT08U *popts,
|
||
CPU_INT08U opt_list_len_rem,
|
||
CPU_INT08U *popt_len,
|
||
NET_ERR *perr)
|
||
{
|
||
NET_IP_OPT_TS *popt_ts;
|
||
NET_IP_OPT_TS_ROUTE *popt_ts_route;
|
||
NET_IP_ROUTE_TS *proute_ts;
|
||
CPU_INT08U opt_ptr;
|
||
CPU_INT08U opt_ix;
|
||
CPU_INT08U opt_ts_flags;
|
||
CPU_INT08U opt_ts_ovf;
|
||
NET_TS opt_ts;
|
||
NET_IP_ADDR opt_addr;
|
||
|
||
|
||
popt_ts = (NET_IP_OPT_TS *)popts;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ----------------- VALIDATE OPT TYPE ---------------- */
|
||
switch (popt_ts->Type) {
|
||
case NET_IP_HDR_OPT_TS:
|
||
break;
|
||
|
||
|
||
default:
|
||
*perr = NET_IP_ERR_INVALID_OPT;
|
||
return (DEF_YES); /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
#endif
|
||
|
||
/* ----------------- VALIDATE OPT LEN ----------------- */
|
||
if (popt_ts->Ptr > popt_ts->Len) { /* If ptr exceeds opt len, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
if (popt_ts->Len > opt_list_len_rem) { /* If opt len exceeds rem opt len, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
opt_ptr = NET_IP_OPT_TS_PTR_TS;
|
||
opt_ix = 0;
|
||
opt_ts_flags = popt_ts->Ovf_Flags & NET_IP_OPT_TS_FLAG_MASK;
|
||
|
||
switch (opt_ts_flags) {
|
||
case NET_IP_OPT_TS_FLAG_TS_ONLY:
|
||
if ((popt_ts->Len % NET_IP_HDR_OPT_SIZE_WORD) != 0) { /* If opt len NOT multiple of opt size, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
/* --------------- CONVERT TO HOST-ORDER -------------- */
|
||
while (opt_ptr < popt_ts->Ptr) { /* Convert ALL TS's to host-order. */
|
||
popt_ts->TS[opt_ix] = NET_UTIL_NET_TO_HOST_32(popt_ts->TS[opt_ix]);
|
||
opt_ptr += NET_IP_HDR_OPT_SIZE_WORD;
|
||
opt_ix++;
|
||
}
|
||
|
||
/* --------------------- INSERT TS -------------------- */
|
||
if (popt_ts->Ptr < popt_ts->Len) { /* If ptr < len, append ts to list. */
|
||
opt_ts = NetUtil_TS_Get();
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&popt_ts->TS[opt_ix], &opt_ts);
|
||
popt_ts->Ptr += NET_IP_HDR_OPT_SIZE_WORD;
|
||
|
||
} else { /* Else inc & chk ovf ctr. */
|
||
opt_ts_ovf = popt_ts->Ovf_Flags & NET_IP_OPT_TS_OVF_MASK;
|
||
opt_ts_ovf >>= NET_IP_OPT_TS_OVF_SHIFT;
|
||
opt_ts_ovf++;
|
||
|
||
if (opt_ts_ovf > NET_IP_OPT_TS_OVF_MAX) { /* If ovf ctr ovfs, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
}
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_TS_FLAG_TS_ROUTE_REC:
|
||
case NET_IP_OPT_TS_FLAG_TS_ROUTE_SPEC:
|
||
/* If opt len NOT multiple of opt size, rtn err. */
|
||
if ((popt_ts->Len % NET_IP_OPT_TS_ROUTE_SIZE) != NET_IP_HDR_OPT_SIZE_WORD) {
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
|
||
popt_ts_route = (NET_IP_OPT_TS_ROUTE *)popts;
|
||
proute_ts = &popt_ts_route->Route_TS[0];
|
||
|
||
/* --------------- CONVERT TO HOST-ORDER -------------- */
|
||
while (opt_ptr < popt_ts_route->Ptr) { /* Convert ALL src route addrs & ts's to host-order. */
|
||
proute_ts->Route[opt_ix] = NET_UTIL_NET_TO_HOST_32(proute_ts->Route[opt_ix]);
|
||
proute_ts->TS[opt_ix] = NET_UTIL_NET_TO_HOST_32(proute_ts->TS[opt_ix]);
|
||
opt_ptr += NET_IP_OPT_TS_ROUTE_SIZE;
|
||
opt_ix++;
|
||
}
|
||
|
||
/* ---------------- INSERT SRC ROUTE/TS --------------- */
|
||
if (popt_ts_route->Ptr < popt_ts_route->Len) { /* If ptr < len, append src route addr & ts to list. */
|
||
opt_addr = NetIP_AddrThisHost;
|
||
opt_ts = NetUtil_TS_Get();
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&proute_ts->Route[opt_ix], &opt_addr);
|
||
NET_UTIL_VAL_COPY_GET_NET_32(&proute_ts->TS[opt_ix], &opt_ts);
|
||
popt_ts_route->Ptr += NET_IP_OPT_TS_ROUTE_SIZE;
|
||
|
||
} else { /* Else inc & chk ovf ctr. */
|
||
opt_ts_ovf = popt_ts->Ovf_Flags & NET_IP_OPT_TS_OVF_MASK;
|
||
opt_ts_ovf >>= NET_IP_OPT_TS_OVF_SHIFT;
|
||
opt_ts_ovf++;
|
||
|
||
if (opt_ts_ovf > NET_IP_OPT_TS_OVF_MAX) { /* If ovf ctr ovfs, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (DEF_YES);
|
||
}
|
||
}
|
||
break;
|
||
|
||
|
||
default: /* If invalid/unknown TS flag, rtn err. */
|
||
*perr = NET_IP_ERR_INVALID_OPT_FLAG;
|
||
return (DEF_YES); /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
*popt_len = popt_ts->Len; /* Rtn TS opt len. */
|
||
*perr = NET_IP_ERR_NONE;
|
||
|
||
return (DEF_NO);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragReasm()
|
||
*
|
||
* Description : (1) Reassemble any IP datagram fragments :
|
||
*
|
||
* (a) Determine if received IP packet is a fragment
|
||
* (b) Reassemble IP fragments, when possible
|
||
*
|
||
* (2) (a) Received fragments are reassembled by sorting datagram fragments into fragment lists
|
||
* (also known as 'Fragmented Datagrams') grouped by the following IP header fields :
|
||
*
|
||
* (1) Source Address
|
||
* (2) Destination Address
|
||
* (3) Identification
|
||
* (4) Protocol
|
||
*
|
||
* See also Note #3a.
|
||
*
|
||
* (b) Fragment lists are linked to form a list of Fragment Lists. In the diagram below,
|
||
* network buffers in vertical columns represent fragments in the same fragment list/
|
||
* Fragmented Datagram. The head fragment of each fragment list/Fragmented Datagram
|
||
* is linked horizontally to form the list of Fragment Lists.
|
||
*
|
||
* (1) 'NetIP_FragReasmListsHead' points to the head of the Fragment Lists;
|
||
* 'NetIP_FragReasmListsTail' points to the tail of the Fragment Lists.
|
||
*
|
||
* (2) Fragment buffers' 'PrevPrimListPtr' & 'NextPrimListPtr' doubly-link each fragment
|
||
* list's head buffer to form the list of Fragment Lists.
|
||
*
|
||
* (3) Fragment buffer's 'PrevBufPtr' & 'NextBufPtr' doubly-link each fragment
|
||
* in a fragment list.
|
||
*
|
||
* (c) For each received fragment, all fragment lists are searched in order to insert the
|
||
* fragment into the appropriate fragment list--i.e. the fragment list with identical
|
||
* fragment list IP header field values (see Note #2a).
|
||
*
|
||
* (d) If a received fragment is the first fragment with its specific fragment list IP header
|
||
* field values, the received fragment starts a new fragment list which is added at the
|
||
* tail of the Fragment Lists.
|
||
*
|
||
* See also Note #3b2.
|
||
*
|
||
* (e) As fragments are received & processed into fragment lists, older fragment lists migrate
|
||
* to the head of the Fragment Lists. Once a fragment list is reassembled or discarded,
|
||
* it is removed from the Fragment Lists.
|
||
*
|
||
* (f) Fragment buffer size is irrelevant & ignored in the fragment reassembly procedure--
|
||
* i.e. the procedure functions correctly regardless of the buffer sizes used for any &
|
||
* all received fragments.
|
||
*
|
||
*
|
||
* | List of |
|
||
* |<----------- Fragmented Datagrams ------------>|
|
||
* | (see Note #2b) |
|
||
*
|
||
* Oldest Fragmented Datagram New fragment lists
|
||
* in Fragment Lists inserted at tail
|
||
* (see Note #2e) (see Note #2d)
|
||
*
|
||
* | NextPrimListPtr |
|
||
* | (see Note #2b2) |
|
||
* v | v
|
||
* |
|
||
* --- Head of ------- ------- v ------- ------- (see Note #2b1)
|
||
* ^ Fragment ---->| |------>| |------>| |------>| |
|
||
* | Lists | | | | | | | | Tail of
|
||
* | | |<------| |<------| |<------| |<---- Fragment
|
||
* | (see Note #2b1) | | | | ^ | | | | Lists
|
||
* | | | | | | | | | |
|
||
* | ------- ------- | ------- -------
|
||
* | | ^ | | ^
|
||
* | | | PrevPrimListPtr | |
|
||
* | v | (see Note #2b2) v |
|
||
* | ------- -------
|
||
* | | | |
|
||
* Fragments in the same | | | |
|
||
* Fragmented Datagram | | | |
|
||
* (see Note #2b) | | | |
|
||
* | | | | Fragments in a fragment
|
||
* | ------- ------- list may use different
|
||
* | | ^ | ^ size network buffers
|
||
* | NextBufPtr ---> | | <--- PrevBufPtr | | (see Note #2f)
|
||
* | (see Note #2b3) v | (see Note #2b3) v |
|
||
* | ------- ------- The last fragment in a
|
||
* | | | | | <--- fragment list may likely
|
||
* | | | | | use a smaller buffer size
|
||
* | | | -------
|
||
* | | |
|
||
* v | |
|
||
* --- -------
|
||
*
|
||
*
|
||
*$PAGE*
|
||
* Argument(s) : pbuf Pointer to network buffer that received IP packet.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* pip_hdr Pointer to received packet's IP header.
|
||
* ------- Argument checked in NetIP_RxPktValidate().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_RX_FRAG_NONE Datagram complete; NOT a fragment (see Note #3b1B).
|
||
*
|
||
* -------- RETURNED BY NetIP_RxPktFragListAdd() : ---------
|
||
* ------- RETURNED BY NetIP_RxPktFragListInsert() : -------
|
||
* NET_IP_ERR_RX_FRAG_REASM Fragments in reassembly progress.
|
||
* NET_IP_ERR_RX_FRAG_DISCARD Fragment &/or datagram discarded.
|
||
* NET_IP_ERR_RX_FRAG_OFFSET Invalid fragment offset.
|
||
* NET_IP_ERR_RX_FRAG_SIZE Invalid fragment size.
|
||
* NET_IP_ERR_RX_FRAG_LEN_TOT Invalid fragment datagram total IP length.
|
||
*
|
||
* ------- RETURNED BY NetIP_RxPktFragListInsert() : -------
|
||
* NET_IP_ERR_RX_FRAG_COMPLETE Datagram complete; fragments reassembled (see Note #3b3).
|
||
* NET_IP_ERR_RX_FRAG_SIZE_TOT Invalid fragmented datagram total size.
|
||
*
|
||
* Return(s) : Pointer to reassembled datagram, if fragment reassembly complete.
|
||
*
|
||
* Pointer to NULL, if fragment reassembly in progress.
|
||
*
|
||
* Pointer to fragment buffer, for any fragment discard error.
|
||
*
|
||
* Caller(s) : NetIP_Rx().
|
||
*
|
||
* Note(s) : (3) (a) RFC #791, Section 3.2 'Fragmentation & Reassembly' states that the following IP header
|
||
* fields are "used together ... to identify datagram fragments for reassembly" :
|
||
*
|
||
* (1) "Internet identification field (ID)", ...
|
||
* (2) "source" address, ...
|
||
* (3) "destination address", & ...
|
||
* (4) "protocol field".
|
||
*
|
||
* (b) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly Procedure'
|
||
* states that :
|
||
*
|
||
* (1) (A) "If ... both [of the following IP header fields] ... are zero" ... :
|
||
* (1) "the fragment offset and" ...
|
||
* (2) "the more fragments"; ...
|
||
*
|
||
* (B) "Then ... this is a whole datagram ... and the datagram is forwarded to the
|
||
* next step in datagram processing."
|
||
*
|
||
* (2) "If no other fragment with [identical] buffer identifier[s] is [available] then
|
||
* [new] reassembly resources are allocated."
|
||
*
|
||
* See also 'NetIP_RxPktFragListAdd() Note #2'.
|
||
*
|
||
* (3) When a "fragment [finally] completes the datagram ... then the datagram is sent
|
||
* to the next step in datagram processing".
|
||
*
|
||
* (4) (a) Fragment lists are accessed by :
|
||
*
|
||
* (1) NetIP_RxPktFragReasm()
|
||
* (2) Fragment list's 'TMR->Obj' pointer during execution of NetIP_RxPktFragTimeout()
|
||
*
|
||
* (b) Since the primary tasks of the network protocol suite are prevented from running
|
||
* concurrently (see 'net.h Note #2'), it is NOT necessary to protect the shared
|
||
* resources of the fragment lists since no asynchronous access from other network
|
||
* tasks is possible.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static NET_BUF *NetIP_RxPktFragReasm (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_HDR *pip_hdr,
|
||
NET_ERR *perr)
|
||
{
|
||
#if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \
|
||
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
CPU_BOOLEAN frag;
|
||
CPU_BOOLEAN frag_done;
|
||
CPU_BOOLEAN ip_flag_frags_more;
|
||
CPU_INT16U ip_flags;
|
||
CPU_INT16U frag_offset;
|
||
CPU_INT16U frag_size;
|
||
NET_BUF *pfrag;
|
||
NET_BUF *pfrag_list;
|
||
NET_BUF_HDR *pfrag_list_buf_hdr;
|
||
NET_IP_HDR *pfrag_list_ip_hdr;
|
||
|
||
|
||
/*$PAGE*/
|
||
/* -------------- CHK FRAG REASM REQUIRED ------------- */
|
||
frag = DEF_NO;
|
||
|
||
ip_flags = pbuf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FLAG_MASK;
|
||
ip_flag_frags_more = DEF_BIT_IS_SET(ip_flags, NET_IP_HDR_FLAG_FRAG_MORE);
|
||
if (ip_flag_frags_more != DEF_NO) { /* If 'More Frags' set (see Note #3b1A2), ... */
|
||
frag = DEF_YES; /* ... mark as frag. */
|
||
}
|
||
|
||
frag_offset = pbuf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FRAG_OFFSET_MASK;
|
||
if (frag_offset != NET_IP_HDR_FRAG_OFFSET_NONE) { /* If frag offset != 0 (see Note #3b1A1), ... */
|
||
frag = DEF_YES; /* ... mark as frag. */
|
||
}
|
||
|
||
if (frag != DEF_YES) { /* If pkt NOT a frag, ... */
|
||
*perr = NET_IP_ERR_RX_FRAG_NONE;
|
||
return (pbuf); /* ... rtn non-frag'd datagram (see Note #3b1B). */
|
||
}
|
||
|
||
|
||
NET_CTR_STAT_INC(NetIP_StatRxFragCtr);
|
||
|
||
|
||
/* ------------------- REASM FRAGS -------------------- */
|
||
frag_size = pbuf_hdr->IP_TotLen - pbuf_hdr->IP_HdrLen;
|
||
pfrag_list = NetIP_FragReasmListsHead;
|
||
frag_done = DEF_NO;
|
||
|
||
while (frag_done == DEF_NO) { /* Insert frag into a frag list. */
|
||
|
||
if (pfrag_list != (NET_BUF *)0) { /* Srch ALL existing frag lists first (see Note #2c). */
|
||
pfrag_list_buf_hdr = &pfrag_list->Hdr;
|
||
pfrag_list_ip_hdr = (NET_IP_HDR *)&pfrag_list->Data[pfrag_list_buf_hdr->IP_HdrIx];
|
||
|
||
/* If frag & this frag list's ... */
|
||
if (pbuf_hdr->IP_AddrSrc == pfrag_list_buf_hdr->IP_AddrSrc) { /* ... src addr (see Note #2a1) ... */
|
||
if (pbuf_hdr->IP_AddrDest == pfrag_list_buf_hdr->IP_AddrDest) { /* ... dest addr (see Note #2a2) ... */
|
||
if (pbuf_hdr->IP_ID == pfrag_list_buf_hdr->IP_ID) { /* ... ID (see Note #2a3) ... */
|
||
if (pip_hdr->Protocol == pfrag_list_ip_hdr->Protocol) { /* ... protocol (see Note #2a4) ... */
|
||
/* ... fields identical, ... */
|
||
pfrag = NetIP_RxPktFragListInsert(pbuf, /* ... insert frag onto frag list. */
|
||
pbuf_hdr,
|
||
ip_flags,
|
||
frag_offset,
|
||
frag_size,
|
||
pfrag_list,
|
||
perr);
|
||
frag_done = DEF_YES;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (frag_done != DEF_YES) { /* If NOT done, adv to next frag list. */
|
||
pfrag_list = (NET_BUF *)pfrag_list_buf_hdr->NextPrimListPtr;
|
||
}
|
||
|
||
} else { /* Else add new frag list (see Note #2d). */
|
||
pfrag = NetIP_RxPktFragListAdd(pbuf,
|
||
pbuf_hdr,
|
||
ip_flags,
|
||
frag_offset,
|
||
frag_size,
|
||
perr);
|
||
frag_done = DEF_YES;
|
||
}
|
||
}
|
||
|
||
return (pfrag);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListAdd()
|
||
*
|
||
* Description : (1) Add fragment as new fragment list at end of Fragment Lists :
|
||
*
|
||
* (a) Get fragment reassembly timer
|
||
* (b) Insert fragment into Fragment Lists
|
||
* (c) Update fragment list reassembly calculations
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer that received fragment.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* frag_ip_flags Fragment IP header flags.
|
||
* ------------- Argument validated in NetIP_RxPktFragReasm().
|
||
*
|
||
* frag_offset Fragment offset.
|
||
*
|
||
* frag_size Fragment size (in octets).
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_RX_FRAG_REASM Fragment reassembly in progress.
|
||
* NET_IP_ERR_RX_FRAG_DISCARD Fragment discarded.
|
||
* NET_IP_ERR_RX_FRAG_OFFSET Invalid fragment offset.
|
||
* NET_IP_ERR_RX_FRAG_SIZE Invalid fragment size.
|
||
*
|
||
* - RETURNED BY NetIP_RxPktFragListUpdate() : -
|
||
* NET_IP_ERR_RX_FRAG_LEN_TOT Invalid fragment datagram total IP length.
|
||
*
|
||
* Return(s) : Pointer to NULL, if fragment added as new fragment list.
|
||
*
|
||
* Pointer to fragment buffer, for any fragment discard error.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragReasm().
|
||
*
|
||
* Note(s) : (2) (a) RFC #791, Section 3.2 'Fragmentation and Reassembly' states that "if an internet
|
||
* datagram is fragmented" :
|
||
*
|
||
* (1) (A) "Fragments are counted in units of 8 octets."
|
||
* (B) "The minimum fragment is 8 octets."
|
||
*
|
||
* (2) (A) However, this CANNOT apply "if this is the last fragment" ...
|
||
* (1) "(that is the more fragments field is zero)"; ...
|
||
* (B) Which may be of ANY size.
|
||
*
|
||
* See also 'net_ip.h IP FRAGMENTATION DEFINES Note #1a'.
|
||
*
|
||
* (b) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly Procedure'
|
||
* states that "if no other fragment with [identical] buffer identifier[s] is [available]
|
||
* then [new] reassembly resources are allocated".
|
||
*
|
||
* (3) During fragment list insertion, some fragment buffer controls were previously initialized
|
||
* in NetBuf_Get() when the packet was received at the network interface layer. These buffer
|
||
* controls do NOT need to be re-initialized but are shown for completeness.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static NET_BUF *NetIP_RxPktFragListAdd (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
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_BOOLEAN ip_flag_frags_more;
|
||
CPU_INT16U frag_size_min;
|
||
NET_ERR tmr_err;
|
||
NET_BUF *pfrag;
|
||
NET_BUF_HDR *pfrag_list_tail_buf_hdr;
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------------- VALIDATE FRAG ------------------ */
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (frag_offset > NET_IP_HDR_FRAG_OFFSET_MAX) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragOffsetCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_OFFSET;
|
||
return (pbuf);
|
||
}
|
||
#endif
|
||
|
||
ip_flag_frags_more = DEF_BIT_IS_SET(frag_ip_flags, NET_IP_HDR_FLAG_FRAG_MORE);
|
||
frag_size_min = (ip_flag_frags_more == DEF_YES) ? NET_IP_FRAG_SIZE_MIN_FRAG_MORE
|
||
: NET_IP_FRAG_SIZE_MIN_FRAG_LAST;
|
||
if (frag_size < frag_size_min) { /* See Note #2a. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragSizeCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_SIZE;
|
||
return (pbuf);
|
||
}
|
||
|
||
if (frag_size > NET_IP_FRAG_SIZE_MAX) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragSizeCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_SIZE;
|
||
return (pbuf);
|
||
}
|
||
|
||
|
||
/* ------------------- GET FRAG TMR ------------------- */
|
||
pbuf_hdr->TmrPtr = NetTmr_Get((void *) pbuf,
|
||
(CPU_FNCT_PTR) NetIP_RxPktFragTimeout,
|
||
(NET_TMR_TICK) NetIP_FragReasmTimeout_tick,
|
||
(CPU_INT16U ) NET_TMR_FLAG_NONE,
|
||
(NET_ERR *)&tmr_err);
|
||
if (tmr_err != NET_TMR_ERR_NONE) { /* If tmr unavail, discard frag. */
|
||
*perr = NET_IP_ERR_RX_FRAG_DISCARD;
|
||
return (pbuf);
|
||
}
|
||
|
||
|
||
/* ------------ INSERT FRAG INTO FRAG LISTS ----------- */
|
||
if (NetIP_FragReasmListsTail != (NET_BUF *)0) { /* If frag lists NOT empty, insert @ tail. */
|
||
pbuf_hdr->PrevPrimListPtr = (void *) NetIP_FragReasmListsTail;
|
||
pfrag_list_tail_buf_hdr = (NET_BUF_HDR *)&NetIP_FragReasmListsTail->Hdr;
|
||
pfrag_list_tail_buf_hdr->NextPrimListPtr = (void *) pbuf;
|
||
NetIP_FragReasmListsTail = (NET_BUF *) pbuf;
|
||
|
||
} else { /* Else add frag as first frag list. */
|
||
NetIP_FragReasmListsHead = (NET_BUF *)pbuf;
|
||
NetIP_FragReasmListsTail = (NET_BUF *)pbuf;
|
||
pbuf_hdr->PrevPrimListPtr = (void *)0;
|
||
}
|
||
|
||
#if 0 /* Init'd in NetBuf_Get() [see Note #3]. */
|
||
pbuf_hdr->NextPrimListPtr = (void *)0;
|
||
pbuf_hdr->PrevBufPtr = (void *)0;
|
||
pbuf_hdr->NextBufPtr = (void *)0;
|
||
pbuf_hdr->IP_FragSizeTot = NET_IP_FRAG_SIZE_NONE;
|
||
pbuf_hdr->IP_FragSizeCur = 0;
|
||
#endif
|
||
|
||
|
||
/* ----------------- UPDATE FRAG CALCS ---------------- */
|
||
NetIP_RxPktFragListUpdate(pbuf,
|
||
pbuf_hdr,
|
||
frag_ip_flags,
|
||
frag_offset,
|
||
frag_size,
|
||
perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return ((NET_BUF *)0);
|
||
}
|
||
|
||
|
||
*perr = NET_IP_ERR_RX_FRAG_REASM;
|
||
pfrag = (NET_BUF *)0;
|
||
|
||
return (pfrag);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListInsert()
|
||
*
|
||
* Description : Insert fragment into corresponding fragment list.
|
||
*
|
||
* (1) (a) Fragments are sorted into fragment lists by fragment offset.
|
||
*
|
||
* See Notes #2a3 & #2b3.
|
||
*
|
||
* (b) Although RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly
|
||
* Procedure' states that "in the case that two or more fragments contain the same data
|
||
* either identically or through a partial overlap ... [the IP fragmentation reassembly
|
||
* algorithm should] use the more recently arrived copy in the data buffer and datagram
|
||
* delivered"; in order to avoid the complexity of sequencing received fragments with
|
||
* duplicate data that overlap multiple previously-received fragments' data, duplicate
|
||
* & overlap fragments are discarded :
|
||
*
|
||
* (1) Duplicate fragments are discarded. A fragment is a duplicate of a fragment already
|
||
* in the fragment list if both fragments have identical fragment offset & size values.
|
||
*
|
||
* (2) Overlap fragments are discarded & the entire Fragmented Datagram is also discarded.
|
||
* A fragment is an overlap fragment if any portion of its fragment data overlaps any
|
||
* other fragment's data :
|
||
*
|
||
* (A) [Fragment offset] < [(Any other fragment offset * FRAG_OFFSET_SIZE) +
|
||
* Any other fragment size ]
|
||
*
|
||
* (B) [(Fragment offset * FRAG_OFFSET_SIZE) + Fragment size] > [Any other fragment offset]
|
||
*
|
||
*
|
||
* See also 'net_tcp.c NetTCP_RxPktConnHandlerRxQ_Conn() Note #2a3'.
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer that received fragment.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Rx().
|
||
*
|
||
* frag_ip_flags Fragment IP header flags.
|
||
* ------------- Argument validated in NetIP_RxPktFragReasm().
|
||
*
|
||
* frag_offset Fragment offset.
|
||
*
|
||
* frag_size Fragment size (in octets).
|
||
*
|
||
* pfrag_list Pointer to fragment list head buffer.
|
||
* ---------- Argument validated in NetIP_RxPktFragReasm().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_RX_FRAG_REASM Fragment reassembly in progress.
|
||
* NET_IP_ERR_RX_FRAG_DISCARD Fragment discarded.
|
||
* NET_IP_ERR_RX_FRAG_OFFSET Invalid fragment offset.
|
||
* NET_IP_ERR_RX_FRAG_SIZE Invalid fragment size.
|
||
*
|
||
* -- RETURNED BY NetIP_RxPktFragListChkComplete() : -
|
||
* NET_IP_ERR_RX_FRAG_COMPLETE Datagram complete; fragments reassembled.
|
||
* NET_IP_ERR_RX_FRAG_SIZE_TOT Invalid fragmented datagram total size.
|
||
*
|
||
* ---- RETURNED BY NetIP_RxPktFragListUpdate() : ----
|
||
* -- RETURNED BY NetIP_RxPktFragListChkComplete() : -
|
||
* NET_IP_ERR_RX_FRAG_LEN_TOT Invalid fragment datagram total IP length.
|
||
*
|
||
* Return(s) : Pointer to reassembled datagram, if fragment reassembly complete.
|
||
*
|
||
* Pointer to NULL, if fragment reassembly in progress.
|
||
*
|
||
* Pointer to fragment buffer, for any fragment discard error.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragReasm().
|
||
*$PAGE*
|
||
* Note(s) : (2) (a) RFC #791, Section 3.2 'Fragmentation and Reassembly' states that "if an internet
|
||
* datagram is fragmented" :
|
||
*
|
||
* (1) (A) (1) "Fragments are counted in units of 8 octets."
|
||
* (2) "The minimum fragment is 8 octets."
|
||
*
|
||
* (B) (1) However, this CANNOT apply "if this is the last fragment" ...
|
||
* (a) "(that is the more fragments field is zero)"; ...
|
||
* (2) Which may be of ANY size.
|
||
*
|
||
* See also 'net_ip.h IP FRAGMENTATION DEFINES Note #1a'.
|
||
*
|
||
* (2) "Fragments ... data portion must be ... on 8 octet boundaries."
|
||
*
|
||
* (3) "The Fragment Offset field identifies the fragment location, relative to the
|
||
* beginning of the original unfragmented datagram."
|
||
*
|
||
* (b) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly Procedure'
|
||
* states that :
|
||
*
|
||
* (1) (A) "If this is the first fragment" ...
|
||
* (1) "(that is the fragment offset is zero)", ...
|
||
* (B) "this header is placed in the header buffer."
|
||
*
|
||
* (2) "Some [IP] options are copied [in every fragment], but others remain with
|
||
* the first fragment only."
|
||
*
|
||
* (3) "The data from the fragment is placed in the data buffer according to its
|
||
* fragment offset and length."
|
||
*
|
||
* See also Note #2a3.
|
||
*
|
||
* (3) Assumes ALL fragments in fragment lists have previously been validated for buffer &
|
||
* IP header fields.
|
||
*
|
||
* (4) During fragment list insertion, some fragment buffer controls were previously
|
||
* initialized in NetBuf_Get() when the packet was received at the network interface
|
||
* layer. These buffer controls do NOT need to be re-initialized but are shown for
|
||
* completeness.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static NET_BUF *NetIP_RxPktFragListInsert (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
NET_BUF *pfrag_list,
|
||
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_BOOLEAN ip_flag_frags_more;
|
||
CPU_BOOLEAN frag_insert_done;
|
||
CPU_BOOLEAN frag_list_discard;
|
||
CPU_INT16U frag_offset_actual;
|
||
CPU_INT16U frag_list_cur_frag_offset;
|
||
CPU_INT16U frag_list_cur_frag_offset_actual;
|
||
CPU_INT16U frag_list_prev_frag_offset;
|
||
CPU_INT16U frag_list_prev_frag_offset_actual;
|
||
CPU_INT16U frag_size_min;
|
||
CPU_INT16U frag_size_cur;
|
||
NET_BUF *pfrag;
|
||
NET_BUF *pfrag_list_prev_buf;
|
||
NET_BUF *pfrag_list_cur_buf;
|
||
NET_BUF *pfrag_list_prev_list;
|
||
NET_BUF *pfrag_list_next_list;
|
||
NET_BUF_HDR *pfrag_list_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_prev_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_cur_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_prev_list_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_next_list_buf_hdr;
|
||
NET_TMR *ptmr;
|
||
NET_ERR err;
|
||
|
||
|
||
/* ------------------- VALIDATE FRAG ------------------ */
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (frag_offset > NET_IP_HDR_FRAG_OFFSET_MAX) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragOffsetCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_OFFSET;
|
||
return (pbuf);
|
||
}
|
||
#endif
|
||
|
||
ip_flag_frags_more = DEF_BIT_IS_SET(frag_ip_flags, NET_IP_HDR_FLAG_FRAG_MORE);
|
||
frag_size_min = (ip_flag_frags_more == DEF_YES) ? NET_IP_FRAG_SIZE_MIN_FRAG_MORE
|
||
: NET_IP_FRAG_SIZE_MIN_FRAG_LAST;
|
||
if (frag_size < frag_size_min) { /* See Note #2a1. */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragSizeCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_SIZE;
|
||
return (pbuf);
|
||
}
|
||
|
||
if (frag_size > NET_IP_FRAG_SIZE_MAX) {
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragSizeCtr);
|
||
*perr = NET_IP_ERR_RX_FRAG_SIZE;
|
||
return (pbuf);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------- INSERT FRAG INTO FRAG LISTS -------- */
|
||
frag_insert_done = DEF_NO;
|
||
|
||
pfrag_list_cur_buf = (NET_BUF *) pfrag_list;
|
||
pfrag_list_cur_buf_hdr = (NET_BUF_HDR *)&pfrag_list_cur_buf->Hdr;
|
||
|
||
while (frag_insert_done == DEF_NO) {
|
||
|
||
frag_list_cur_frag_offset = pfrag_list_cur_buf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FRAG_OFFSET_MASK;
|
||
if (frag_offset > frag_list_cur_frag_offset) { /* While frag offset > cur frag offset, ... */
|
||
|
||
if (pfrag_list_cur_buf_hdr->NextBufPtr != (NET_BUF *)0) { /* ... adv to next frag in list. */
|
||
pfrag_list_cur_buf = (NET_BUF *) pfrag_list_cur_buf_hdr->NextBufPtr;
|
||
pfrag_list_cur_buf_hdr = (NET_BUF_HDR *)&pfrag_list_cur_buf->Hdr;
|
||
|
||
} else { /* If @ last frag in list, append frag @ end. */
|
||
frag_offset_actual = frag_offset * NET_IP_FRAG_SIZE_UNIT;
|
||
frag_list_cur_frag_offset_actual = ( frag_list_cur_frag_offset * NET_IP_FRAG_SIZE_UNIT )
|
||
+ (pfrag_list_cur_buf_hdr->IP_TotLen - pfrag_list_cur_buf_hdr->IP_HdrLen);
|
||
|
||
if (frag_offset_actual >= frag_list_cur_frag_offset_actual) { /* If frag does NOT overlap, ... */
|
||
/* ... append @ end of frag list. */
|
||
pbuf_hdr->PrevBufPtr = (void *)pfrag_list_cur_buf;
|
||
#if 0 /* Init'd in NetBuf_Get() [see Note #4]. */
|
||
pbuf_hdr->NextBufPtr = (void *)0;
|
||
pbuf_hdr->PrevPrimListPtr = (void *)0;
|
||
pbuf_hdr->NextPrimListPtr = (void *)0;
|
||
pbuf_hdr->TmrPtr = (NET_TMR *)0;
|
||
pbuf_hdr->IP_FragSizeTot = NET_IP_FRAG_SIZE_NONE;
|
||
pbuf_hdr->IP_FragSizeCur = 0;
|
||
#endif
|
||
|
||
pfrag_list_cur_buf_hdr->NextBufPtr = (void *)pbuf;
|
||
|
||
|
||
pfrag_list_buf_hdr = &pfrag_list->Hdr;
|
||
NetIP_RxPktFragListUpdate(pfrag_list, /* Update frag list reasm calcs. */
|
||
pfrag_list_buf_hdr,
|
||
frag_ip_flags,
|
||
frag_offset,
|
||
frag_size,
|
||
perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return ((NET_BUF *)0);
|
||
}
|
||
/* Chk frag list reasm complete. */
|
||
pfrag = NetIP_RxPktFragListChkComplete(pfrag_list,
|
||
pfrag_list_buf_hdr,
|
||
perr);
|
||
|
||
} else { /* Else discard overlap frag & datagram. */
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, &err);
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragDiscardedCtr);
|
||
pfrag = pbuf;
|
||
*perr = NET_IP_ERR_RX_FRAG_DISCARD;
|
||
}
|
||
|
||
frag_insert_done = DEF_YES;
|
||
}
|
||
|
||
|
||
} else if (frag_offset < frag_list_cur_frag_offset) { /* If frag offset < cur frag offset, ... */
|
||
/* ... insert frag into frag list. */
|
||
frag_list_discard = DEF_NO;
|
||
|
||
frag_offset_actual = (frag_offset * NET_IP_FRAG_SIZE_UNIT) + frag_size;
|
||
frag_list_cur_frag_offset_actual = frag_list_cur_frag_offset * NET_IP_FRAG_SIZE_UNIT;
|
||
|
||
if (frag_offset_actual > frag_list_cur_frag_offset_actual) {/* If frag overlaps with next frag, ... */
|
||
frag_list_discard = DEF_YES; /* ... discard frag & datagram (see Note #1b2). */
|
||
|
||
} else if (pfrag_list_cur_buf_hdr->PrevBufPtr != (void *)0) {
|
||
pfrag_list_prev_buf = (NET_BUF *) pfrag_list_cur_buf_hdr->PrevBufPtr;
|
||
pfrag_list_prev_buf_hdr = (NET_BUF_HDR *)&pfrag_list_prev_buf->Hdr;
|
||
|
||
frag_offset_actual = frag_offset * NET_IP_FRAG_SIZE_UNIT;
|
||
|
||
frag_list_prev_frag_offset = pfrag_list_prev_buf_hdr->IP_Flags_FragOffset & NET_IP_HDR_FRAG_OFFSET_MASK;
|
||
frag_list_prev_frag_offset_actual = ( frag_list_prev_frag_offset * NET_IP_FRAG_SIZE_UNIT )
|
||
+ (pfrag_list_prev_buf_hdr->IP_TotLen - pfrag_list_prev_buf_hdr->IP_HdrLen);
|
||
/* If frag overlaps with prev frag, ... */
|
||
if (frag_offset_actual < frag_list_prev_frag_offset_actual) {
|
||
frag_list_discard = DEF_YES; /* ... discard frag & datagram (see Note #1b2). */
|
||
}
|
||
}
|
||
/*$PAGE*/
|
||
if (frag_list_discard == DEF_NO) { /* If frag does NOT overlap, ... */
|
||
/* ... insert into frag list. */
|
||
pbuf_hdr->PrevBufPtr = (void *)pfrag_list_cur_buf_hdr->PrevBufPtr;
|
||
pbuf_hdr->NextBufPtr = (void *)pfrag_list_cur_buf;
|
||
|
||
if (pbuf_hdr->PrevBufPtr != (void *)0) { /* Insert pbuf between prev & cur bufs. */
|
||
pfrag_list_prev_buf = (NET_BUF *) pbuf_hdr->PrevBufPtr;
|
||
pfrag_list_prev_buf_hdr = (NET_BUF_HDR *)&pfrag_list_prev_buf->Hdr;
|
||
|
||
pfrag_list_prev_buf_hdr->NextBufPtr = (void *) pbuf;
|
||
pfrag_list_cur_buf_hdr->PrevBufPtr = (void *) pbuf;
|
||
|
||
#if 0 /* Init'd in NetBuf_Get() [see Note #4]. */
|
||
pbuf_hdr->PrevPrimListPtr = (void *)0;
|
||
pbuf_hdr->NextPrimListPtr = (void *)0;
|
||
pbuf_hdr->TmrPtr = (NET_TMR *)0;
|
||
pbuf_hdr->IP_FragSizeTot = NET_IP_FRAG_SIZE_NONE;
|
||
pbuf_hdr->IP_FragSizeCur = 0;
|
||
#endif
|
||
|
||
} else { /* Else pbuf is new frag list head. */
|
||
pfrag_list = pbuf;
|
||
/* Move frag list head info to cur buf ... */
|
||
/* ... (see Note #2b1). */
|
||
pbuf_hdr->PrevPrimListPtr = pfrag_list_cur_buf_hdr->PrevPrimListPtr;
|
||
pbuf_hdr->NextPrimListPtr = pfrag_list_cur_buf_hdr->NextPrimListPtr;
|
||
pbuf_hdr->TmrPtr = pfrag_list_cur_buf_hdr->TmrPtr;
|
||
pbuf_hdr->IP_FragSizeTot = pfrag_list_cur_buf_hdr->IP_FragSizeTot;
|
||
pbuf_hdr->IP_FragSizeCur = pfrag_list_cur_buf_hdr->IP_FragSizeCur;
|
||
|
||
pfrag_list_cur_buf_hdr->PrevBufPtr = (void *)pbuf;
|
||
pfrag_list_cur_buf_hdr->PrevPrimListPtr = (void *)0;
|
||
pfrag_list_cur_buf_hdr->NextPrimListPtr = (void *)0;
|
||
pfrag_list_cur_buf_hdr->TmrPtr = (NET_TMR *)0;
|
||
pfrag_list_cur_buf_hdr->IP_FragSizeTot = NET_IP_FRAG_SIZE_NONE;
|
||
pfrag_list_cur_buf_hdr->IP_FragSizeCur = 0;
|
||
|
||
/* Point tmr to new frag list head. */
|
||
ptmr = (NET_TMR *)pbuf_hdr->TmrPtr;
|
||
ptmr->Obj = (void *)pbuf;
|
||
|
||
/* Point prev frag list to new frag list head. */
|
||
pfrag_list_prev_list = (NET_BUF *)pbuf_hdr->PrevPrimListPtr;
|
||
if (pfrag_list_prev_list != (NET_BUF *)0) {
|
||
pfrag_list_prev_list_buf_hdr = (NET_BUF_HDR *)&pfrag_list_prev_list->Hdr;
|
||
pfrag_list_prev_list_buf_hdr->NextPrimListPtr = (void *) pbuf;
|
||
} else {
|
||
NetIP_FragReasmListsHead = (NET_BUF *) pbuf;
|
||
}
|
||
|
||
/* Point next frag list to new frag list head. */
|
||
pfrag_list_next_list = (NET_BUF *)pbuf_hdr->NextPrimListPtr;
|
||
if (pfrag_list_next_list != (NET_BUF *)0) {
|
||
pfrag_list_next_list_buf_hdr = (NET_BUF_HDR *)&pfrag_list_next_list->Hdr;
|
||
pfrag_list_next_list_buf_hdr->PrevPrimListPtr = (void *) pbuf;
|
||
} else {
|
||
NetIP_FragReasmListsTail = (NET_BUF *) pbuf;
|
||
}
|
||
}
|
||
|
||
pfrag_list_buf_hdr = &pfrag_list->Hdr;
|
||
NetIP_RxPktFragListUpdate(pfrag_list, /* Update frag list reasm calcs. */
|
||
pfrag_list_buf_hdr,
|
||
frag_ip_flags,
|
||
frag_offset,
|
||
frag_size,
|
||
perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return ((NET_BUF *)0);
|
||
}
|
||
/* Chk frag list reasm complete. */
|
||
pfrag = NetIP_RxPktFragListChkComplete(pfrag_list,
|
||
pfrag_list_buf_hdr,
|
||
perr);
|
||
|
||
} else { /* Else discard overlap frag & datagram ... */
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, &err); /* ... (see Note #1b2). */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragDiscardedCtr);
|
||
pfrag = pbuf;
|
||
*perr = NET_IP_ERR_RX_FRAG_DISCARD;
|
||
}
|
||
|
||
frag_insert_done = DEF_YES;
|
||
|
||
/*$PAGE*/
|
||
} else { /* Else if frag offset = cur frag offset, ... */
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragDiscardedCtr);
|
||
pfrag = pbuf;
|
||
*perr = NET_IP_ERR_RX_FRAG_DISCARD; /* ... discard duplicate frag (see Note #1b1). */
|
||
|
||
frag_size_cur = pfrag_list_cur_buf_hdr->IP_TotLen - pfrag_list_cur_buf_hdr->IP_HdrLen;
|
||
if (frag_size != frag_size_cur) { /* If frag size != cur frag size, ... */
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, &err); /* ... discard overlap frag datagram ... */
|
||
/* ... (see Note #1b2). */
|
||
}
|
||
|
||
frag_insert_done = DEF_YES;
|
||
}
|
||
}
|
||
|
||
return (pfrag);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListRemove()
|
||
*
|
||
* Description : (1) Remove fragment list from Fragment Lists :
|
||
*
|
||
* (a) Free fragment reassembly timer
|
||
* (b) Remove fragment list from Fragment Lists
|
||
* (c) Clear buffer's fragment pointers
|
||
*
|
||
*
|
||
* Argument(s) : pfrag_list Pointer to fragment list head buffer.
|
||
* ---------- Argument validated in NetIP_RxPktFragListDiscard(),
|
||
* NetIP_RxPktFragListChkComplete().
|
||
*
|
||
* tmr_free Indicate whether to free network timer :
|
||
*
|
||
* DEF_YES Free network timer for fragment list discard.
|
||
* DEF_NO Do NOT free network timer for fragment list discard
|
||
* [Freed by NetTmr_TaskHandler()
|
||
* via NetIP_RxPktFragListDiscard()].
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragListDiscard(),
|
||
* NetIP_RxPktFragListChkComplete().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_RxPktFragListRemove (NET_BUF *pfrag_list,
|
||
CPU_BOOLEAN tmr_free)
|
||
{
|
||
NET_BUF *pfrag_list_prev_list;
|
||
NET_BUF *pfrag_list_next_list;
|
||
NET_BUF_HDR *pfrag_list_prev_list_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_next_list_buf_hdr;
|
||
NET_BUF_HDR *pfrag_list_buf_hdr;
|
||
NET_TMR *ptmr;
|
||
|
||
|
||
pfrag_list_buf_hdr = &pfrag_list->Hdr;
|
||
|
||
/* ------------------ FREE FRAG TMR ------------------- */
|
||
if (tmr_free == DEF_YES) {
|
||
ptmr = pfrag_list_buf_hdr->TmrPtr;
|
||
if (ptmr != (NET_TMR *)0) {
|
||
NetTmr_Free(ptmr);
|
||
}
|
||
}
|
||
|
||
/* --------- REMOVE FRAG LIST FROM FRAG LISTS --------- */
|
||
pfrag_list_prev_list = (NET_BUF *)pfrag_list_buf_hdr->PrevPrimListPtr;
|
||
pfrag_list_next_list = (NET_BUF *)pfrag_list_buf_hdr->NextPrimListPtr;
|
||
|
||
/* Point prev frag list to next frag list. */
|
||
if (pfrag_list_prev_list != (NET_BUF *)0) {
|
||
pfrag_list_prev_list_buf_hdr = (NET_BUF_HDR *)&pfrag_list_prev_list->Hdr;
|
||
pfrag_list_prev_list_buf_hdr->NextPrimListPtr = (void *) pfrag_list_next_list;
|
||
} else {
|
||
NetIP_FragReasmListsHead = (NET_BUF *) pfrag_list_next_list;
|
||
}
|
||
|
||
/* Point next frag list to prev frag list. */
|
||
if (pfrag_list_next_list != (NET_BUF *)0) {
|
||
pfrag_list_next_list_buf_hdr = (NET_BUF_HDR *)&pfrag_list_next_list->Hdr;
|
||
pfrag_list_next_list_buf_hdr->PrevPrimListPtr = (void *) pfrag_list_prev_list;
|
||
} else {
|
||
NetIP_FragReasmListsTail = (NET_BUF *) pfrag_list_prev_list;
|
||
}
|
||
|
||
/* ---------------- CLR BUF FRAG PTRS ----------------- */
|
||
pfrag_list_buf_hdr->PrevPrimListPtr = (void *)0;
|
||
pfrag_list_buf_hdr->NextPrimListPtr = (void *)0;
|
||
pfrag_list_buf_hdr->TmrPtr = (NET_TMR *)0;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListDiscard()
|
||
*
|
||
* Description : Discard fragment list from Fragment Lists.
|
||
*
|
||
* Argument(s) : pfrag_list Pointer to fragment list head buffer.
|
||
* ---------- Argument validated in NetIP_RxPktFragListInsert(),
|
||
* NetIP_RxPktFragListChkComplete(),
|
||
* NetIP_RxPktFragListDiscard().
|
||
*
|
||
* tmr_free Indicate whether to free network timer :
|
||
*
|
||
* DEF_YES Free network timer for fragment list discard.
|
||
* DEF_NO Do NOT free network timer for fragment list discard
|
||
* [Freed by NetTmr_TaskHandler()].
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_RX_FRAG_DISCARD Fragment list discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragListInsert(),
|
||
* NetIP_RxPktFragListChkComplete(),
|
||
* NetIP_RxPktFragListTimeout().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_RxPktFragListDiscard (NET_BUF *pfrag_list,
|
||
CPU_BOOLEAN tmr_free,
|
||
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
|
||
NET_ERR err;
|
||
|
||
|
||
NetIP_RxPktFragListRemove(pfrag_list, tmr_free); /* Remove frag list from Frag Lists. */
|
||
NetIP_RxPktDiscard(pfrag_list, &err); /* Discard every frag buf in frag list. */
|
||
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragDatagramDiscardedCtr); /* Inc discarded frag'd datagram ctr. */
|
||
|
||
*perr = NET_IP_ERR_RX_FRAG_DISCARD;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListUpdate()
|
||
*
|
||
* Description : Update fragment list reassembly calculations.
|
||
*
|
||
* Argument(s) : pfrag_list_buf_hdr Pointer to fragment list head buffer's header.
|
||
* ------------------ Argument validated in NetIP_RxPktFragListAdd(),
|
||
* NetIP_RxPktFragListInsert().
|
||
*
|
||
* frag_ip_flags Fragment IP header flags.
|
||
* ------------- Argument validated in NetIP_RxPktFragListAdd(),
|
||
* NetIP_RxPktFragListInsert().
|
||
*
|
||
* frag_offset Fragment offset.
|
||
* ----------- Argument validated in NetIP_RxPktFragListAdd(),
|
||
* NetIP_RxPktFragListInsert().
|
||
*
|
||
* frag_size Fragment size (in octets).
|
||
* --------- Argument validated in NetIP_RxPktFragListAdd(),
|
||
* NetIP_RxPktFragListInsert().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Fragment list reassembly calculations
|
||
* successfully updated.
|
||
* NET_IP_ERR_RX_FRAG_LEN_TOT Invalid fragment datagram total IP length.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragListAdd(),
|
||
* NetIP_RxPktFragListInsert().
|
||
*
|
||
* Note(s) : (1) (a) RFC #791, Section 3.2 'Fragmentation and Reassembly' states that "fragments ... data
|
||
* portion ... allows" up to :
|
||
*
|
||
* (1) "2**13 = 8192 fragments" ...
|
||
* (2) "of 8 octets each" ...
|
||
* (3) "for a total of 65,536 [sic] octets."
|
||
*
|
||
* (b) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly Procedure'
|
||
* states that :
|
||
*
|
||
* (1) "If this is the last fragment" ...
|
||
* (A) "(that is the more fragments field is zero)"; ...
|
||
*
|
||
* (2) "The total data length is computed."
|
||
*
|
||
* (2) To avoid possible integer arithmetic overflow, the fragmentation arithmetic result MUST
|
||
* be declared as an integer data type with a greater resolution -- i.e. greater number of
|
||
* bits -- than the fragmentation arithmetic operands' data type(s).
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_RxPktFragListUpdate (NET_BUF *pfrag_list,
|
||
NET_BUF_HDR *pfrag_list_buf_hdr,
|
||
CPU_INT16U frag_ip_flags,
|
||
CPU_INT16U frag_offset,
|
||
CPU_INT16U frag_size,
|
||
NET_ERR *perr)
|
||
{
|
||
CPU_BOOLEAN ip_flag_frags_more;
|
||
CPU_INT32U frag_size_tot; /* See Note #2. */
|
||
NET_ERR err;
|
||
|
||
|
||
pfrag_list_buf_hdr->IP_FragSizeCur += frag_size;
|
||
ip_flag_frags_more = DEF_BIT_IS_SET(frag_ip_flags, NET_IP_HDR_FLAG_FRAG_MORE);
|
||
if (ip_flag_frags_more != DEF_YES) { /* If 'More Frags' NOT set (see Note #1b1A), ... */
|
||
/* ... calc frag tot size (see Note #1b2). */
|
||
frag_size_tot = ((CPU_INT32U)frag_offset * NET_IP_FRAG_SIZE_UNIT) + (CPU_INT32U)frag_size;
|
||
if (frag_size_tot > NET_IP_TOT_LEN_MAX) { /* If frag tot size > IP tot len max, ... */
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, &err); /* ... discard ovf'd frag datagram (see Note #1a3). */
|
||
*perr = NET_IP_ERR_RX_FRAG_LEN_TOT;
|
||
return;
|
||
}
|
||
|
||
pfrag_list_buf_hdr->IP_FragSizeTot = (CPU_INT16U)frag_size_tot;
|
||
}
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragListChkComplete()
|
||
*
|
||
* Description : Check if fragment list complete; i.e. fragmented datagram reassembled.
|
||
*
|
||
* Argument(s) : pfrag_list Pointer to fragment list head buffer.
|
||
* ---------- Argument validated in NetIP_RxPktFragListInsert().
|
||
*
|
||
* pfrag_list_buf_hdr Pointer to fragment list head buffer's header.
|
||
* ------------------ Argument validated in NetIP_RxPktFragListInsert().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_RX_FRAG_COMPLETE Datagram complete; fragments reassembled.
|
||
* NET_IP_ERR_RX_FRAG_REASM Fragments in reassembly progress.
|
||
* NET_IP_ERR_RX_FRAG_SIZE_TOT Invalid fragmented datagram total size.
|
||
* NET_IP_ERR_RX_FRAG_LEN_TOT Invalid fragment datagram total IP length.
|
||
*
|
||
* - RETURNED BY NetIP_RxPktFragListDiscard() : -
|
||
* NET_IP_ERR_RX_FRAG_DISCARD Fragment list discarded.
|
||
*
|
||
* Return(s) : Pointer to reassembled datagram, if fragment reassembly complete.
|
||
*
|
||
* Pointer to NULL, if fragment reassembly in progress.
|
||
* OR
|
||
* for any fragment discard error.
|
||
*
|
||
* Caller(s) : NetIP_RxPktFragListInsert().
|
||
*
|
||
* Note(s) : (1) (a) RFC #791, Section 3.2 'Fragmentation and Reassembly' states that :
|
||
*
|
||
* (1) "Fragments ... data portion ... allows" up to :
|
||
* (A) "2**13 = 8192 fragments" ...
|
||
* (B) "of 8 octets each" ...
|
||
* (C) "for a total of 65,536 [sic] octets."
|
||
*
|
||
* (2) "The header is counted in the total length and not in the fragments."
|
||
*
|
||
* (b) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly
|
||
* Procedure' states that :
|
||
*
|
||
* (1) "If this fragment completes the datagram ... then the datagram is sent to
|
||
* the next step in datagram processing."
|
||
*
|
||
* (2) "Otherwise the timer is set to" :
|
||
* (A) "the maximum of the current timer value" ...
|
||
* (B) "and the value of the time to live field from this fragment."
|
||
* (1) #### However, since IP headers' Time-To-Live (TTL) field does NOT
|
||
* directly correlate to a specific timeout value in seconds, this
|
||
* requirement is NOT implemented.
|
||
*
|
||
* (2) To avoid possible integer arithmetic overflow, the fragmentation arithmetic result
|
||
* MUST be declared as an integer data type with a greater resolution -- i.e. greater
|
||
* number of bits -- than the fragmentation arithmetic operands' data type(s).
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static NET_BUF *NetIP_RxPktFragListChkComplete (NET_BUF *pfrag_list,
|
||
NET_BUF_HDR *pfrag_list_buf_hdr,
|
||
NET_ERR *perr)
|
||
{
|
||
#if ((NET_CTR_CFG_STAT_EN == DEF_ENABLED) && \
|
||
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
CPU_INT32U frag_tot_len; /* See Note #2. */
|
||
NET_BUF *pfrag;
|
||
NET_ERR err;
|
||
|
||
/* If tot frag size complete, ... */
|
||
if (pfrag_list_buf_hdr->IP_FragSizeCur == pfrag_list_buf_hdr->IP_FragSizeTot) {
|
||
/* Calc frag IP tot len (see Note #1a2). */
|
||
frag_tot_len = (CPU_INT32U)pfrag_list_buf_hdr->IP_HdrLen + (CPU_INT32U)pfrag_list_buf_hdr->IP_FragSizeTot;
|
||
if (frag_tot_len > NET_IP_TOT_LEN_MAX) { /* If tot frag len > IP tot len max, ... */
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, &err); /* ... discard ovf'd frag datagram (see Note #1a1C).*/
|
||
*perr = NET_IP_ERR_RX_FRAG_LEN_TOT;
|
||
return ((NET_BUF *)0);
|
||
}
|
||
|
||
NetIP_RxPktFragListRemove(pfrag_list, DEF_YES);
|
||
NET_CTR_STAT_INC(NetIP_StatRxFragDatagramReasmCtr);
|
||
pfrag = pfrag_list; /* ... rtn reasm'd datagram (see Note #1b1). */
|
||
*perr = NET_IP_ERR_RX_FRAG_COMPLETE;
|
||
|
||
/* If cur frag size > tot frag size, ... */
|
||
} else if (pfrag_list_buf_hdr->IP_FragSizeCur > pfrag_list_buf_hdr->IP_FragSizeTot) {
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, perr); /* ... discard ovf'd frag datagram. */
|
||
*perr = NET_IP_ERR_RX_FRAG_SIZE_TOT;
|
||
return ((NET_BUF *)0);
|
||
|
||
|
||
} else { /* Else reset frag tmr (see Note #1b2A). */
|
||
NetTmr_Set((NET_TMR *) pfrag_list_buf_hdr->TmrPtr,
|
||
(CPU_FNCT_PTR) NetIP_RxPktFragTimeout,
|
||
(NET_TMR_TICK) NetIP_FragReasmTimeout_tick,
|
||
(NET_ERR *)&err);
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (err != NET_TMR_ERR_NONE) {
|
||
NetIP_RxPktFragListDiscard(pfrag_list, DEF_YES, perr);
|
||
return ((NET_BUF *)0);
|
||
}
|
||
#endif
|
||
|
||
*perr = NET_IP_ERR_RX_FRAG_REASM;
|
||
pfrag = (NET_BUF *)0;
|
||
}
|
||
|
||
|
||
return (pfrag);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktFragTimeout()
|
||
*
|
||
* Description : Discard fragment list on fragment reassembly timeout.
|
||
*
|
||
* Argument(s) : pfrag_list_timeout Pointer to network buffer fragment reassembly list (see Note #1b).
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : Referenced in NetIP_RxPktFragListAdd().
|
||
*
|
||
* Note(s) : (1) RFC #791, Section 3.2 'Fragmentation and Reassembly : An Example Reassembly Procedure'
|
||
* states that :
|
||
*
|
||
* (a) "If the [IP fragments' reassembly] timer runs out," ...
|
||
* (b) "the [sic] all reassembly resources for this buffer identifier are released."
|
||
*
|
||
* (2) Ideally, network timer expiration functions could be defined as '[(void) (OBJECT *)]'
|
||
* type functions -- even though network timer API functions cast expiration functions
|
||
* to generic 'CPU_FNCT_PTR' type (i.e. '[(void) (void *)]').
|
||
*
|
||
* (a) (1) Unfortunately, ISO-IEC 9899-1999 ANSI-C, Section 6.3.2.3.7 states that "a
|
||
* pointer to an object ... may be converted to a pointer to a different object
|
||
* ... [but] if the resulting pointer is not correctly aligned ... the behavior
|
||
* is undefined".
|
||
*
|
||
* And since compilers may NOT correctly convert 'void' pointers to non-'void'
|
||
* pointer arguments, network timer expiration functions MUST avoid incorrect
|
||
* pointer conversion behavior between 'void' pointer parameters & non-'void'
|
||
* pointer arguments & therefore CANNOT be defined as '[(void) (OBJECT *)]'.
|
||
*
|
||
* (2) However, Section 6.3.2.3.1 states that "a pointer to void may be converted
|
||
* to or from a pointer to any ... object ... A pointer to any ... object ...
|
||
* may be converted to a pointer to void and back again; the result shall
|
||
* compare equal to the original pointer".
|
||
*
|
||
* (b) Therefore, to correctly convert 'void' pointer objects back to appropriate
|
||
* network object pointer objects, network timer expiration functions MUST :
|
||
*
|
||
* (1) Be defined as 'CPU_FNCT_PTR' type (i.e. '[(void) (void *)]'); & ...
|
||
* (2) Explicitly cast 'void' pointer arguments to specific object pointers; ...
|
||
* (A) ... in this case, a 'NET_BUF' pointer.
|
||
*
|
||
* See also 'net_tmr.c NetTmr_Get() Note #3'.
|
||
*
|
||
* (3) This function is a network timer expiration function :
|
||
*
|
||
* (a) Clear the timer pointer; ...
|
||
* (1) Cleared in NetIP_RxPktFragListRemove() via NetIP_RxPktFragListDiscard().
|
||
*
|
||
* (b) but do NOT re-free the timer.
|
||
*
|
||
* (4) (a) RFC #792, Section 'Time Exceeded Message' states that :
|
||
*
|
||
* (1) "if a host reassembling a fragmented datagram cannot complete the reassembly
|
||
* due to missing fragments within its time limit" ...
|
||
* (2) (A) "it discards the datagram," ...
|
||
* (B) "and it may send a time exceeded message."
|
||
*
|
||
* (b) MUST send ICMP 'Time Exceeded' error message BEFORE NetIP_RxPktFragListDiscard()
|
||
* frees fragment buffers.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_RxPktFragTimeout (void *pfrag_list_timeout)
|
||
{
|
||
#if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \
|
||
(CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL))
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
CPU_BOOLEAN used;
|
||
#endif
|
||
NET_BUF *pfrag_list;
|
||
NET_ERR err;
|
||
|
||
|
||
pfrag_list = (NET_BUF *)pfrag_list_timeout; /* See Note #2b2A. */
|
||
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
/* ------------------ VALIDATE PTR -------------------- */
|
||
if (pfrag_list == (NET_BUF *)0) {
|
||
NET_CTR_ERR_INC(NetIP_ErrNullPtrCtr);
|
||
return;
|
||
}
|
||
/* ---------------- VALIDATE BUF USED ----------------- */
|
||
used = NetBuf_IsUsed(pfrag_list);
|
||
if (used != DEF_YES) {
|
||
NET_CTR_ERR_INC(NetIP_ErrNullPtrCtr);
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
|
||
NetICMP_TxMsgErr((NET_BUF *) pfrag_list, /* Send ICMP 'Time Exceeded' err msg (see Note #4). */
|
||
(CPU_INT08U) NET_ICMP_MSG_TYPE_TIME_EXCEED,
|
||
(CPU_INT08U) NET_ICMP_MSG_CODE_TIME_EXCEED_FRAG_REASM,
|
||
(CPU_INT08U) NET_ICMP_MSG_PTR_NONE,
|
||
(NET_ERR *)&err);
|
||
/* Discard frag list (see Note #1b). */
|
||
NetIP_RxPktFragListDiscard((NET_BUF *) pfrag_list,
|
||
(CPU_BOOLEAN) DEF_NO, /* Clr but do NOT free tmr (see Note #3). */
|
||
(NET_ERR *)&err);
|
||
|
||
|
||
NET_CTR_ERR_INC(NetIP_ErrRxFragDatagramTimeoutCtr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktDemuxDatagram()
|
||
*
|
||
* Description : Demultiplex IP datagram to appropriate ICMP, TCP, or UDP queue.
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer that received IP datagram.
|
||
* ---- Argument checked in NetIP_Rx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_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_INVALID_PROTOCOL Invalid/unknown protocol type.
|
||
* NET_ERR_RX Receive error; packet discarded.
|
||
*
|
||
* ------ RETURNED BY NetICMP_Rx() : ------
|
||
* NET_ICMP_ERR_NONE ICMP message successfully demultiplexed.
|
||
*
|
||
* ------ RETURNED BY NetTCP_Rx() : -------
|
||
* NET_TCP_ERR_NONE TCP segment successfully demultiplexed.
|
||
*
|
||
* ------ RETURNED BY NetUDP_Rx() : -------
|
||
* NET_UDP_ERR_NONE UDP datagram successfully demultiplexed.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Rx().
|
||
*
|
||
* Note(s) : (1) When network buffer is demultiplexed to higher-layer protocol receive, buffer's reference
|
||
* counter is NOT incremented since the IP layer does NOT maintain a reference to the buffer.
|
||
*
|
||
* (2) Default case already invalidated in NetIP_RxPktValidate(). However, the default case
|
||
* is included as an extra precaution in case 'ProtocolHdrType' is incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_RxPktDemuxDatagram (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
|
||
|
||
|
||
switch (pbuf_hdr->ProtocolHdrType) { /* Demux buf to appropriate protocol Q (see Note #1). */
|
||
case NET_PROTOCOL_TYPE_ICMP:
|
||
NetICMP_Rx(pbuf, perr);
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_UDP:
|
||
NetUDP_Rx(pbuf, perr);
|
||
break;
|
||
|
||
|
||
#ifdef NET_TCP_MODULE_PRESENT
|
||
case NET_PROTOCOL_TYPE_TCP:
|
||
NetTCP_Rx(pbuf, perr);
|
||
break;
|
||
#endif
|
||
|
||
case NET_PROTOCOL_TYPE_NONE:
|
||
default: /* See Note #2. */
|
||
NET_CTR_ERR_INC(Net_ErrInvalidProtocolCtr);
|
||
*perr = NET_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_RxPktDiscard()
|
||
*
|
||
* Description : On any IP Receive errors, discard IP packet(s) & buffer(s).
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer.
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_ERR_RX Receive error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Rx(),
|
||
* NetIP_RxPktFragListDiscard().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_RxPktDiscard (NET_BUF *pbuf,
|
||
NET_ERR *perr)
|
||
{
|
||
NET_CTR *pctr;
|
||
|
||
|
||
#if (NET_CTR_CFG_ERR_EN == DEF_ENABLED)
|
||
pctr = (NET_CTR *)&NetIP_ErrRxPktDiscardedCtr;
|
||
#else
|
||
pctr = (NET_CTR *) 0;
|
||
#endif
|
||
NetBuf_FreeBufList((NET_BUF *)pbuf,
|
||
(NET_CTR *)pctr);
|
||
|
||
*perr = NET_ERR_RX;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktValidate()
|
||
*
|
||
* Description : (1) Validate IP transmit packet parameters & options :
|
||
*
|
||
* (a) Packets with the following invalid parameters will be "silently discarded" :
|
||
*
|
||
* (1) Protocols other than supported protocols :
|
||
* (A) ICMP
|
||
* (B) TCP
|
||
* (C) UDP
|
||
*
|
||
* (2) Total Length
|
||
* (3) Type of Service (TOS) See 'net_ip.h IP HEADER TYPE OF SERVICE (TOS) DEFINES'
|
||
*
|
||
* (4) Source Address
|
||
* (A) MUST be one of the following :
|
||
* (1) This host's RFC #1122, Section 3.2.1.3
|
||
* (2) This Host RFC #1122, Section 3.2.1.3.(a)
|
||
* (3) Specified Host RFC #1122, Section 3.2.1.3.(b)
|
||
* (B) MUST NOT be one of the following :
|
||
* (1) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (2) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
* (3) Subnet Broadcast RFC #1122, Section 3.2.1.3.(e)
|
||
* (4) Multicast RFC #1122, Section 3.2.1.3
|
||
* (C) SHOULD NOT be one of the following :
|
||
* (1) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
*
|
||
* (5) Destination Address
|
||
* (A) MAY be one of the following :
|
||
* (1) Localhost RFC #1122, Section 3.2.1.3.(g)
|
||
* (2) Limited Broadcast RFC #1122, Section 3.2.1.3.(c)
|
||
* (3) Directed Broadcast RFC #1122, Section 3.2.1.3.(d)
|
||
* (4) Subnet Broadcast RFC #1122, Section 3.2.1.3.(e)
|
||
* (B) MUST NOT be one of the following :
|
||
* (1) This Host RFC #1122, Section 3.2.1.3.(a)
|
||
* (2) Specified Host RFC #1122, Section 3.2.1.3.(b)
|
||
*
|
||
* (6) Flags
|
||
*
|
||
* (b) The following parameters are inherently assumed to be valid :
|
||
*
|
||
* (1) Time-to-Live (TTL)
|
||
*
|
||
*$PAGE*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
* ---- Argument checked in NetIP_Tx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Tx().
|
||
*
|
||
* addr_src Source IP address.
|
||
*
|
||
* addr_dest Destination IP address.
|
||
*
|
||
* TOS Specific TOS to transmit IP packet
|
||
* (see 'net_ip.h IP HEADER TYPE OF SERVICE (TOS) DEFINES').
|
||
*
|
||
* TTL Specific TTL to transmit IP packet (see RFC #1122, Section 3.2.1.7) :
|
||
*
|
||
* NET_IP_HDR_TTL_MIN 1 minimum TTL transmit value
|
||
* NET_IP_HDR_TTL_MAX 255 maximum TTL transmit value
|
||
* NET_IP_HDR_TTL_DFLT default TTL transmit value
|
||
* NET_IP_HDR_TTL_NONE 0 replace with default TTL
|
||
*
|
||
* flags Flags to select transmit options; bit-field flags logically OR'd :
|
||
*
|
||
* NET_IP_FLAG_NONE No IP transmit flags selected.
|
||
* NET_IP_FLAG_TX_DONT_FRAG Set IP 'Don't Frag' flag.
|
||
*
|
||
* popts Pointer to one or more IP options configuration data structures :
|
||
*
|
||
* NULL NO IP transmit options configuration.
|
||
* NET_IP_OPT_CFG_ROUTE_TS Route &/or Internet Timestamp options configuration.
|
||
* NET_IP_OPT_CFG_SECURITY Security options configuration
|
||
* (see 'net_ip.h Note #1f').
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Transmit packet validated.
|
||
* NET_ERR_INVALID_PROTOCOL Invalid/unknown protocol type.
|
||
* NET_BUF_ERR_INVALID_IX Invalid or insufficient buffer index.
|
||
* NET_IP_ERR_INVALID_LEN_DATA Invalid protocol/data length.
|
||
* NET_IP_ERR_INVALID_TOS Invalid TOS.
|
||
* NET_IP_ERR_INVALID_ADDR_SRC Invalid IP source address.
|
||
* NET_IP_ERR_INVALID_ADDR_DEST Invalid IP destination address.
|
||
* NET_IP_ERR_INVALID_FLAG Invalid IP flag(s).
|
||
*
|
||
* -- RETURNED BY NetIP_TxPktValidateOpt() : --
|
||
* NET_IP_ERR_NONE IP transmit option configurations validated.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP options length.
|
||
* NET_IP_ERR_INVALID_OPT_CFG Invalid IP options configuration.
|
||
* NET_IP_ERR_INVALID_OPT_ROUTE Invalid IP route address(s).
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Tx().
|
||
*
|
||
* Note(s) : (2) See 'net_ip.h IP ADDRESS DEFINES Notes #2, #3, & #4' for supported IP addresses.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_TxPktValidate (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
void *popts,
|
||
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;
|
||
CPU_INT16U flag_mask;
|
||
CPU_BOOLEAN tos_mbz;
|
||
|
||
|
||
/* ----------------- VALIDATE PROTOCOL ---------------- */
|
||
switch (pbuf_hdr->ProtocolHdrType) {
|
||
case NET_PROTOCOL_TYPE_ICMP:
|
||
ix = pbuf_hdr->ICMP_MsgIx;
|
||
len = pbuf_hdr->ICMP_MsgLen;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_UDP:
|
||
case NET_PROTOCOL_TYPE_TCP:
|
||
ix = pbuf_hdr->TCP_UDP_HdrDataIx;
|
||
len = pbuf_hdr->TCP_UDP_HdrLen + (CPU_INT16U)pbuf_hdr->DataLen;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_NONE:
|
||
default:
|
||
NET_CTR_ERR_INC(NetIP_ErrTxProtocolCtr);
|
||
*perr = NET_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
if (ix == NET_BUF_IX_NONE) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxInvalidBufIxCtr);
|
||
*perr = NET_BUF_ERR_INVALID_IX;
|
||
return;
|
||
}
|
||
|
||
if (ix < NET_IP_HDR_SIZE_MAX) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxInvalidBufIxCtr);
|
||
*perr = NET_BUF_ERR_INVALID_IX;
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/* -------------- VALIDATE TOT DATA LEN --------------- */
|
||
if (len != pbuf_hdr->TotLen) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrDataLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_LEN_DATA;
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/* ----------------- VALIDATE IP TOS ------------------ */
|
||
tos_mbz = DEF_BIT_IS_SET(TOS, NET_IP_HDR_TOS_MBZ_MASK);
|
||
if (tos_mbz != DEF_NO) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrTOS_Ctr);
|
||
*perr = NET_IP_ERR_INVALID_TOS;
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------- VALIDATE IP SRC ADDR ------------- */
|
||
/* See Note #1a4. */
|
||
if (addr_src != NetIP_AddrThisHost) { /* Chk this host's addr (see Note #1a4A1). */
|
||
|
||
if (addr_src != NET_IP_ADDR_THIS_HOST) { /* Chk 'This Host' (see Note #1a4A2). */
|
||
|
||
if ((addr_src & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
/* Chk Class-A specified host (see Note #1a4A3). */
|
||
if ((addr_src & NET_IP_ADDR_CLASS_A_MASK_HOST) !=
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else if ((addr_src & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
/* Chk Class-B specified host (see Note #1a4A3). */
|
||
if ((addr_src & NET_IP_ADDR_CLASS_B_MASK_HOST) !=
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else if ((addr_src & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
/* Chk Class-C specified host (see Note #1a4A3). */
|
||
if ((addr_src & NET_IP_ADDR_CLASS_C_MASK_HOST) !=
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
|
||
} else { /* Discard invalid addr class (see Note #2). */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrSrcCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_SRC;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------- VALIDATE IP DEST ADDR ------------ */
|
||
/* See Note #1a5. */
|
||
/* Chk localhost (see Note #1a5A1). */
|
||
if ((addr_dest & NET_IP_ADDR_LOCAL_HOST_MASK) == NET_IP_ADDR_LOCAL_HOST) {
|
||
/* Chk localhost invalid addrs. */
|
||
if ((addr_dest & NET_IP_ADDR_LOCAL_HOST_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_LOCAL_HOST_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
if ((addr_dest & NET_IP_ADDR_LOCAL_HOST_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_LOCAL_HOST_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
} else {
|
||
/* Chk invalid 'This Host' (see Note #1a5B1). */
|
||
if (addr_dest == NET_IP_ADDR_THIS_HOST) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/* Chk limited broadcast (see Note #1a5B2). */
|
||
if (addr_dest != NET_IP_ADDR_BROADCAST) {
|
||
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
/* Chk Class-A specified host (see Note #1a5B2). */
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
} else if ((addr_dest & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
/* Chk Class-B specified host (see Note #1a5B2). */
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
} else if ((addr_dest & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
/* Chk Class-C specified host (see Note #1a5B2). */
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_THIS_HOST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
|
||
} else { /* Discard invalid addr class (see Note #2). */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
/* Chk subnet specified host (see Note #1a5B2). */
|
||
if (NetIP_AddrThisHostSubnetMask != NET_IP_ADDR_NONE) {
|
||
if ((addr_dest & NetIP_AddrThisHostSubnetMask) ==
|
||
NetIP_AddrThisHostSubnetNet ) {
|
||
if ((addr_dest & NetIP_AddrThisHostSubnetMaskHost) ==
|
||
(NET_IP_ADDR_THIS_HOST & NetIP_AddrThisHostSubnetMaskHost)) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrAddrDestCtr);
|
||
*perr = NET_IP_ERR_INVALID_ADDR_DEST;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ---------------- VALIDATE IP FLAGS ----------------- */
|
||
flag_mask = NET_IP_FLAG_NONE |
|
||
NET_IP_FLAG_TX_DONT_FRAG;
|
||
|
||
if ((flags & ~flag_mask) != NET_IP_FLAG_NONE) { /* If any invalid flags req'd, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrFlagsCtr);
|
||
*perr = NET_IP_ERR_INVALID_FLAG;
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/* ----------------- VALIDATE IP OPTS ----------------- */
|
||
if (popts != (void *)0) {
|
||
NetIP_TxPktValidateOpt(popts, perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* -------------- IGNORE VALID IP FIELDS -------------- */
|
||
(void)&TTL; /* Prevent compiler warning. */
|
||
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktValidateOpt()
|
||
*
|
||
* Description : (1) Validate IP transmit option configurations :
|
||
*
|
||
* (a) IP transmit options MUST be configured by appropriate transmit options configuration
|
||
* data structure(s) passed via 'popts'; see 'net_ip.h IP HEADER OPTION CONFIGURATION
|
||
* DATA TYPES' for IP options configuration.
|
||
*
|
||
* (b) IP header allows for a maximum option size of 40 octets (see 'net_ip.h IP HEADER
|
||
* OPTIONS DEFINES Note #3').
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to one or more IP options configuration data structures (see Note #1a) :
|
||
*
|
||
* NET_IP_OPT_CFG_ROUTE_TS IP Route &/or Internet Timestamp options configuration.
|
||
* NET_IP_OPT_CFG_SECURITY Security options configuration
|
||
* (see 'net_ip.c Note #1f').
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP transmit option configurations validated.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Total options length exceeds maximum IP
|
||
* options length (see Note #1b).
|
||
* NET_IP_ERR_INVALID_OPT_CFG Invalid number of exclusive IP options
|
||
* (see Note #3).
|
||
*
|
||
* - RETURNED BY NetIP_TxPktValidateOptRouteTS() : -
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid number of Route &/or Internet
|
||
* Timestamp entries configured.
|
||
* NET_IP_ERR_INVALID_OPT_ROUTE Invalid route address(s).
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktValidate().
|
||
*
|
||
* Note(s) : (2) (a) See 'net_ip.h IP HEADER OPTIONS DEFINES' for supported IP options' summary.
|
||
*
|
||
* (b) See 'net_ip.c Note #5' for unsupported IP options.
|
||
*
|
||
* (3) The following IP transmit options MUST be configured exclusively--i.e. only a single IP Route
|
||
* or Internet Timestamp option may be configured for any one IP datagram :
|
||
*
|
||
* (a) NET_IP_OPT_CFG_TYPE_ROUTE_STRICT
|
||
* (b) NET_IP_OPT_CFG_TYPE_ROUTE_LOOSE
|
||
* (c) NET_IP_OPT_CFG_TYPE_ROUTE_REC
|
||
* (d) NET_IP_OPT_CFG_TYPE_TS_ONLY
|
||
* (e) NET_IP_OPT_CFG_TYPE_TS_ROUTE_REC
|
||
* (f) NET_IP_OPT_CFG_TYPE_TS_ROUTE_SPEC
|
||
*
|
||
* (A) RFC #1122, Section 3.2.1.8.(c) prohibits "an IP header" from transmitting
|
||
* with "more than one Source Route option".
|
||
*
|
||
* (4) RFC #791, Section 3.1 'Options : Internet Timestamp' states that "each timestamp"
|
||
* may be "preceded with [an] internet address".
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_TxPktValidateOpt (void *popts,
|
||
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_INT08U opt_len_size;
|
||
CPU_INT08U opt_len;
|
||
CPU_INT08U opt_nbr_route_ts;
|
||
NET_TYPE *popt_cfg_type;
|
||
void *popt_cfg;
|
||
void *popt_next;
|
||
|
||
|
||
opt_len_size = 0;
|
||
opt_nbr_route_ts = 0;
|
||
popt_cfg = popts;
|
||
|
||
while (popt_cfg != (void *)0) {
|
||
popt_cfg_type = (NET_TYPE *)popt_cfg;
|
||
switch (*popt_cfg_type) {
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_STRICT:
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_LOOSE:
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_REC:
|
||
case NET_IP_OPT_CFG_TYPE_TS_ONLY:
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_REC:
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_SPEC:
|
||
if (opt_nbr_route_ts > 0) { /* If > 1 exclusive IP opt, rtn err (see Note #3A). */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptCfgCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_CFG;
|
||
return;
|
||
}
|
||
opt_nbr_route_ts++;
|
||
|
||
NetIP_TxPktValidateOptRouteTS(popt_cfg, &opt_len, &popt_next, perr);
|
||
break;
|
||
|
||
#if 0 /* --------------- UNSUPPORTED IP OPTS ---------------- */
|
||
/* See Note #2b. */
|
||
case NET_IP_OPT_CFG_TYPE_SECURITY:
|
||
case NET_IP_OPT_CFG_TYPE_SECURITY_EXTENDED:
|
||
/* 'break' intentionally omitted; do NOT move from the */
|
||
/* ... following case : 'NET_IP_OPT_CFG_TYPE_NONE'. */
|
||
#endif
|
||
|
||
case NET_IP_OPT_CFG_TYPE_NONE: /* ----------------- INVALID IP OPTS ------------------ */
|
||
default:
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
|
||
opt_len_size += opt_len;
|
||
if (opt_len_size > NET_IP_HDR_OPT_SIZE_MAX) { /* If tot opt len exceeds max opt len, rtn err. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return;
|
||
}
|
||
|
||
popt_cfg = popt_next; /* Validate next cfg opt. */
|
||
}
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktValidateOptRouteTS()
|
||
*
|
||
* Description : (1) Validate IP Route &/or Internet Timestamp option configuration :
|
||
*
|
||
* (a) See 'net_ip.h IP ROUTE & INTERNET TIMESTAMP OPTIONS CONFIGURATION DATA TYPE' for
|
||
* valid IP Route &/or Internet Timestamp option configuration.
|
||
*
|
||
* (b) Packets with the following invalid options configuration will be "silently discarded" :
|
||
*
|
||
* (1) Type
|
||
* (2) Number
|
||
* * Less than minimum
|
||
* * Greater than maximum
|
||
* (3) IP Route addresses
|
||
* * MUST be IP Class A, B, or C address See 'net_ip.h IP ADDRESS DEFINES Note #2'
|
||
* (4) Internet Timestamps
|
||
* * Timestamp values are NOT validated
|
||
*
|
||
* (c) Return option values.
|
||
*
|
||
*
|
||
* Argument(s) : popt_route_ts Pointer to IP Route &/or Internet Timestamp option configuration data structure.
|
||
* ------------- Argument checked in NetIP_TxPktValidateOpt().
|
||
*
|
||
* popt_len Pointer to variable that will receive the Route/Internet Timestamp option length
|
||
* -------- (in octets).
|
||
*
|
||
* Argument validated in NetIP_TxPktValidateOpt().
|
||
*
|
||
* popt_next Pointer to variable that will receive the pointer to the next IP transmit option.
|
||
* --------- Argument validated in NetIP_TxPktValidateOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Route &/or Internet Timestamp option
|
||
* configuration validated.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid number of Route &/or Internet
|
||
* Timestamp entries configured.
|
||
* NET_IP_ERR_INVALID_OPT_ROUTE Invalid route address(s).
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktValidateOpt().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
static void NetIP_TxPktValidateOptRouteTS (void *popt_route_ts,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
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
|
||
NET_IP_OPT_CFG_ROUTE_TS *popt_cfg_route_ts;
|
||
CPU_INT08U opt_nbr_min;
|
||
CPU_INT08U opt_nbr_max;
|
||
CPU_INT08U opt_len;
|
||
CPU_INT08U opt_len_opt;
|
||
CPU_INT08U opt_len_param;
|
||
CPU_INT08U opt_route_ix;
|
||
CPU_BOOLEAN opt_route_spec;
|
||
NET_IP_ADDR opt_route_addr;
|
||
|
||
|
||
popt_cfg_route_ts = (NET_IP_OPT_CFG_ROUTE_TS *)popt_route_ts;
|
||
|
||
/* ------------------ VALIDATE TYPE ------------------- */
|
||
switch (popt_cfg_route_ts->Type) {
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_STRICT:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_ROUTE;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_ROUTE;
|
||
opt_len_param = sizeof(NET_IP_ADDR);
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_LOOSE:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_ROUTE;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_ROUTE;
|
||
opt_len_param = sizeof(NET_IP_ADDR);
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_REC:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_ROUTE;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_ROUTE;
|
||
opt_len_param = sizeof(NET_IP_ADDR);
|
||
opt_route_spec = DEF_NO;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ONLY:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_TS_ONLY;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_TS;
|
||
opt_len_param = sizeof(NET_TS);
|
||
opt_route_spec = DEF_NO;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_REC:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_TS_ROUTE;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_TS;
|
||
opt_len_param = sizeof(NET_IP_ADDR) + sizeof(NET_TS);
|
||
opt_route_spec = DEF_NO;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_SPEC:
|
||
opt_nbr_min = NET_IP_OPT_PARAM_NBR_MIN;
|
||
opt_nbr_max = NET_IP_OPT_PARAM_NBR_MAX_TS_ROUTE;
|
||
opt_len_opt = NET_IP_HDR_OPT_SIZE_TS;
|
||
opt_len_param = sizeof(NET_IP_ADDR) + sizeof(NET_TS);
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_NONE:
|
||
default:
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
/*$PAGE*/
|
||
/* ------------------- VALIDATE NBR ------------------- */
|
||
if (popt_cfg_route_ts->Nbr < opt_nbr_min) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return;
|
||
}
|
||
if (popt_cfg_route_ts->Nbr > opt_nbr_max) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return;
|
||
}
|
||
|
||
/* ------------------ VALIDATE ROUTE ------------------ */
|
||
if (opt_route_spec == DEF_YES) { /* For specified routes ... */
|
||
/* ... validate all route addrs (see Note #1b3). */
|
||
for (opt_route_ix = 0; opt_route_ix < popt_cfg_route_ts->Nbr; opt_route_ix++) {
|
||
|
||
opt_route_addr = popt_cfg_route_ts->Route[opt_route_ix];
|
||
|
||
if ((opt_route_addr & NET_IP_ADDR_CLASS_A_MASK) != NET_IP_ADDR_CLASS_A) {
|
||
if ((opt_route_addr & NET_IP_ADDR_CLASS_B_MASK) != NET_IP_ADDR_CLASS_B) {
|
||
if ((opt_route_addr & NET_IP_ADDR_CLASS_C_MASK) != NET_IP_ADDR_CLASS_C) {
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptCfgCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_ROUTE;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/* ------------------- VALIDATE TS -------------------- */
|
||
/* See Note #1b4. */
|
||
|
||
|
||
/* ------------------- RTN OPT VALS ------------------- */
|
||
opt_len = opt_len_opt + (popt_cfg_route_ts->Nbr * opt_len_param);
|
||
*popt_len = opt_len;
|
||
*popt_next = popt_cfg_route_ts->NextOptPtr;
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPkt()
|
||
*
|
||
* Description : (1) Prepare IP header & transmit IP packet :
|
||
*
|
||
* (a) Prepare IP options (if any)
|
||
* (b) Calculate IP header buffer controls
|
||
* (c) Check for transmit fragmentation See Note #2
|
||
* (d) Prepare IP header
|
||
* (e) Transmit IP packet datagram
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
* ---- Argument checked in NetIP_Tx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Tx().
|
||
*
|
||
* addr_src Source IP address.
|
||
* -------- Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* addr_dest Destination IP address.
|
||
* --------- Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* TOS Specific TOS to transmit IP packet
|
||
* --- (see 'net_ip.h IP HEADER TYPE OF SERVICE (TOS) DEFINES').
|
||
* Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* TTL Specific TTL to transmit IP packet (see RFC #1122, Section 3.2.1.7) :
|
||
* ---
|
||
* NET_IP_HDR_TTL_MIN 1 minimum TTL transmit value
|
||
* NET_IP_HDR_TTL_MAX 255 maximum TTL transmit value
|
||
* NET_IP_HDR_TTL_DFLT default TTL transmit value
|
||
* NET_IP_HDR_TTL_NONE 0 replace with default TTL
|
||
*
|
||
* Argument validated in NetIP_TxPktValidate().
|
||
*
|
||
* flags Flags to select transmit options; bit-field flags logically OR'd :
|
||
* -----
|
||
* NET_IP_FLAG_NONE No IP transmit flags selected.
|
||
* NET_IP_FLAG_TX_DONT_FRAG Set IP 'Don't Frag' flag.
|
||
*
|
||
* Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* popts Pointer to one or more IP options configuration data structures :
|
||
* -----
|
||
* NULL NO IP transmit options configuration.
|
||
* NET_IP_OPT_CFG_ROUTE_TS Route &/or Internet Timestamp options configuration.
|
||
* NET_IP_OPT_CFG_SECURITY Security options configuration
|
||
* (see 'net_ip.h Note #1f').
|
||
*
|
||
* Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_INVALID_LEN_HDR Invalid IP header length.
|
||
* NET_IP_ERR_INVALID_FRAG Invalid IP fragmentation.
|
||
* NET_ERR_INVALID_PROTOCOL Invalid/unknown protocol type.
|
||
*
|
||
* --- RETURNED BY NetIP_TxPktPrepareOpt() : ----
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
*
|
||
* --- RETURNED BY NetIP_TxPktPrepareHdr() : ----
|
||
* NET_BUF_ERR_INVALID_IX Invalid/insufficient buffer index.
|
||
* NET_BUF_ERR_INVALID_LEN Invalid buffer length.
|
||
* NET_UTIL_ERR_NULL_PTR Check-sum passed a NULL pointer.
|
||
* NET_UTIL_ERR_NULL_SIZE Check-sum passed a zero size.
|
||
*
|
||
* ---- RETURNED BY NetIP_TxPktDatagram() : -----
|
||
* NET_IP_ERR_NONE IP datagram successfully received & processed.
|
||
* NET_IF_ERR_NONE Packet successfully transmitted.
|
||
* NET_ERR_RX Receive error; packet discarded.
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
* NET_IP_ERR_TX_DEST_INVALID Invalid transmit destination.
|
||
* NET_IP_ERR_INVALID_ADDR_HOST Invalid IP host address.
|
||
* NET_IP_ERR_INVALID_ADDR_NET Invalid IP net address.
|
||
* NET_IP_ERR_INVALID_ADDR_GATEWAY Invalid IP gateway address.
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Tx().
|
||
*
|
||
* Note(s) : (2) IP transmit fragmentation NOT currently supported (see 'net_ip.c Note #1e').
|
||
*
|
||
* (3) Default case already invalidated in NetIP_TxPktValidate(). However, the default case
|
||
* is included as an extra precaution in case 'ProtocolHdrType' is incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_TxPkt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
void *popts,
|
||
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
|
||
#if 0 /* #### NOT currently implemented (see Note #2). */
|
||
CPU_BOOLEAN flag_dont_frag;
|
||
#endif
|
||
CPU_INT08U ip_opt_len_size;
|
||
CPU_INT16U ip_hdr_len_size;
|
||
CPU_INT16U protocol_ix;
|
||
CPU_INT16U ip_mtu;
|
||
NET_IP_OPT_SIZE ip_hdr_opts[NET_IP_HDR_OPT_NBR_MAX];
|
||
CPU_BOOLEAN ip_tx_frag;
|
||
|
||
|
||
/* ----------------- PREPARE IP OPTS ------------------ */
|
||
if (popts != (void *)0) {
|
||
ip_opt_len_size = NetIP_TxPktPrepareOpt((void *) popts,
|
||
(CPU_INT08U *)&ip_hdr_opts[0],
|
||
(NET_ERR *) perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
} else {
|
||
ip_opt_len_size = 0;
|
||
}
|
||
|
||
|
||
/* ---------------- CALC IP HDR CTRLS ----------------- */
|
||
/* Calc tot IP hdr len (in octets). */
|
||
ip_hdr_len_size = (CPU_INT16U)(NET_IP_HDR_SIZE_MIN + ip_opt_len_size);
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (ip_hdr_len_size > NET_IP_HDR_SIZE_MAX) {
|
||
*perr = NET_IP_ERR_INVALID_LEN_HDR;
|
||
return;
|
||
}
|
||
#endif
|
||
|
||
switch (pbuf_hdr->ProtocolHdrType) {
|
||
case NET_PROTOCOL_TYPE_ICMP:
|
||
protocol_ix = pbuf_hdr->ICMP_MsgIx;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_UDP:
|
||
case NET_PROTOCOL_TYPE_TCP:
|
||
protocol_ix = pbuf_hdr->TCP_UDP_HdrDataIx;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_NONE:
|
||
default: /* See Note #3. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxProtocolCtr);
|
||
*perr = NET_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
/*$PAGE*/
|
||
/* ----------------- CHK FRAG REQUIRED ---------------- */
|
||
ip_tx_frag = DEF_NO;
|
||
if (protocol_ix < ip_hdr_len_size) { /* If hdr len > allowed rem ix, tx frag req'd. */
|
||
ip_tx_frag = DEF_YES;
|
||
}
|
||
|
||
ip_mtu = NET_IF_MTU - ip_hdr_len_size;
|
||
if (pbuf_hdr->TotLen > ip_mtu) { /* If tot len > MTU, tx frag req'd. */
|
||
ip_tx_frag = DEF_YES;
|
||
}
|
||
|
||
|
||
if (ip_tx_frag == DEF_NO) { /* If tx frag NOT required, ... */
|
||
|
||
NetIP_TxPktPrepareHdr(pbuf, /* ... prepare IP hdr ... */
|
||
pbuf_hdr,
|
||
ip_hdr_len_size,
|
||
ip_opt_len_size,
|
||
protocol_ix,
|
||
addr_src,
|
||
addr_dest,
|
||
TOS,
|
||
TTL,
|
||
flags,
|
||
&ip_hdr_opts[0],
|
||
perr);
|
||
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
|
||
NetIP_TxPktDatagram(pbuf, pbuf_hdr, perr); /* ... & tx IP datagram. */
|
||
|
||
} else {
|
||
#if 0 /* #### NOT currently implemented (see Note #2). */
|
||
flag_dont_frag = DEF_BIT_IS_SET(flags, NET_IP_FLAG_TX_DONT_FRAG);
|
||
if (flag_dont_frag != DEF_NO) {
|
||
*perr = NET_IP_ERR_INVALID_FRAG;
|
||
return;
|
||
}
|
||
#else
|
||
*perr = NET_IP_ERR_INVALID_FRAG;
|
||
return;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktPrepareOpt()
|
||
*
|
||
* Description : (1) Prepare IP header with IP transmit options :
|
||
*
|
||
* (a) Prepare ALL IP options from configuration
|
||
* data structure(s)
|
||
* (b) Pad remaining IP header octets See RFC #791, Section 3.1 'Padding'
|
||
*
|
||
* (2) IP transmit options MUST be configured by appropriate options configuration data structure(s)
|
||
* passed via 'popts'; see 'net_ip.h IP HEADER OPTION CONFIGURATION DATA TYPES' for IP options
|
||
* configuration.
|
||
*
|
||
* (3) Convert ALL IP options' multi-octet words from host-order to network-order.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to one or more IP options configuration data structures (see Note #2) :
|
||
* -----
|
||
* NULL NO IP transmit options configuration.
|
||
* NET_IP_OPT_CFG_ROUTE_TS Route &/or Internet Timestamp options configuration.
|
||
* NET_IP_OPT_CFG_SECURITY Security options configuration
|
||
* (see 'net_ip.h Note #1f').
|
||
*
|
||
* Argument checked in NetIP_TxPkt().
|
||
*
|
||
* popt_hdr Pointer to IP transmit option buffer to prepare IP options.
|
||
* -------- Argument validated in NetIP_TxPkt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP header options successfully prepared.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
* NET_IP_ERR_INVALID_OPT_LEN Invalid IP option length.
|
||
*
|
||
* Return(s) : Total IP option length (in octets), if NO errors.
|
||
*
|
||
* 0, otherwise.
|
||
*
|
||
* Caller(s) : NetIP_TxPkt().
|
||
*
|
||
* Note(s) : (4) Transmit arguments & options validated in NetIP_TxPktValidate()/NetIP_TxPktValidateOpt() :
|
||
*
|
||
* (a) Assumes ALL transmit arguments & options are valid
|
||
* (b) Assumes total transmit options' lengths are valid
|
||
*
|
||
* (5) IP header allows for a maximum option size of 40 octets (see 'net_ip.h IP HEADER OPTIONS
|
||
* DEFINES Note #3').
|
||
*
|
||
* (6) Default case already invalidated in NetIP_TxPktValidateOpt(). However, the default
|
||
* case is included as an extra precaution in case any of the IP transmit options types
|
||
* are incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static CPU_INT08U NetIP_TxPktPrepareOpt (void *popts,
|
||
CPU_INT08U *popt_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_INT08U ip_opt_len_tot;
|
||
CPU_INT08U ip_opt_len;
|
||
CPU_INT08U *popt_cfg_hdr;
|
||
NET_TYPE *popt_cfg_type;
|
||
void *popt_next;
|
||
void *popt_cfg;
|
||
|
||
|
||
ip_opt_len_tot = 0;
|
||
popt_cfg = popts;
|
||
popt_cfg_hdr = popt_hdr;
|
||
/* ----------------- PREPARE IP OPTS ------------------ */
|
||
while (popt_cfg != (void *)0) { /* Prepare ALL cfg'd IP opts (see Note #1a). */
|
||
popt_cfg_type = (NET_TYPE *)popt_cfg;
|
||
switch (*popt_cfg_type) {
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_STRICT:
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_LOOSE:
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_REC:
|
||
NetIP_TxPktPrepareOptRoute(popt_cfg, popt_cfg_hdr, &ip_opt_len, &popt_next, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ONLY:
|
||
NetIP_TxPktPrepareOptTS(popt_cfg, popt_cfg_hdr, &ip_opt_len, &popt_next, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_REC:
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_SPEC:
|
||
NetIP_TxPktPrepareOptTSRoute(popt_cfg, popt_cfg_hdr, &ip_opt_len, &popt_next, perr);
|
||
break;
|
||
|
||
#if 0 /* --------------- UNSUPPORTED IP OPTS ---------------- */
|
||
case NET_IP_OPT_CFG_TYPE_SECURITY:
|
||
case NET_IP_OPT_CFG_TYPE_SECURITY_EXTENDED:
|
||
break;
|
||
#endif
|
||
/* ----------------- INVALID IP OPTS ------------------ */
|
||
case NET_IP_OPT_CFG_TYPE_NONE:
|
||
default: /* See Note #6. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return (0); /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (*perr != NET_IP_ERR_NONE) { /* See Note #4a. */
|
||
return (0);
|
||
}
|
||
if (ip_opt_len_tot > NET_IP_HDR_OPT_SIZE_MAX) { /* See Note #4b. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (0);
|
||
}
|
||
#endif
|
||
|
||
ip_opt_len_tot += ip_opt_len;
|
||
popt_cfg_hdr += ip_opt_len;
|
||
|
||
popt_cfg = popt_next; /* Prepare next cfg opt. */
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/* -------------------- PAD IP HDR -------------------- */
|
||
if (ip_opt_len_tot > 0) {
|
||
/* Pad rem'ing IP hdr octets (see Note #1b). */
|
||
while ((ip_opt_len_tot % NET_IP_HDR_OPT_SIZE_WORD) &&
|
||
(ip_opt_len_tot <= NET_IP_HDR_OPT_SIZE_MAX )) {
|
||
*popt_cfg_hdr = NET_IP_HDR_OPT_PAD;
|
||
popt_cfg_hdr++;
|
||
ip_opt_len_tot++;
|
||
}
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (ip_opt_len_tot > NET_IP_HDR_OPT_SIZE_MAX) { /* See Note #4b. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxHdrOptLenCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_LEN;
|
||
return (0);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
|
||
return (ip_opt_len_tot);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktPrepareOptRoute()
|
||
*
|
||
* Description : (1) Prepare IP header with IP Route transmit options :
|
||
*
|
||
* (a) Prepare IP Route option header
|
||
* (b) Prepare IP Route
|
||
*
|
||
* (2) See RFC #791, Section 3.1 'Options : Loose/Strict Source & Record Route'.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to IP Route option configuration data structure.
|
||
* ----- Argument checked in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* popt_hdr Pointer to IP transmit option buffer to prepare IP Route option.
|
||
* -------- Argument validated in NetIP_TxPkt().
|
||
*
|
||
* popt_len Pointer to variable that will receive the Route option length (in octets).
|
||
* -------- Argument validated in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* popt_next Pointer to variable that will receive the pointer to the next IP transmit option.
|
||
* -------- Argument validated in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP Route option successfully prepared.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktPrepareOpt().
|
||
*
|
||
* Note(s) : (3) Transmit arguments & options validated in NetIP_TxPktValidate()/NetIP_TxPktValidateOpt() :
|
||
*
|
||
* (a) Assumes ALL transmit arguments & options are valid
|
||
* (b) Assumes total transmit options' lengths are valid
|
||
*
|
||
* (4) Default case already invalidated in NetIP_TxPktValidateOpt(). However, the default
|
||
* case is included as an extra precaution in case any of the IP transmit options types
|
||
* are incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_TxPktPrepareOptRoute (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
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
|
||
NET_IP_OPT_CFG_ROUTE_TS *popt_cfg_route_ts;
|
||
NET_IP_OPT_SRC_ROUTE *popt_route;
|
||
CPU_BOOLEAN opt_route_spec;
|
||
CPU_INT08U opt_route_ix;
|
||
NET_IP_ADDR opt_route_addr;
|
||
|
||
|
||
/* -------------- PREPARE ROUTE OPT HDR --------------- */
|
||
popt_cfg_route_ts = (NET_IP_OPT_CFG_ROUTE_TS *)popts;
|
||
popt_route = (NET_IP_OPT_SRC_ROUTE *)popt_hdr;
|
||
popt_route->Len = NET_IP_HDR_OPT_SIZE_ROUTE + (popt_cfg_route_ts->Nbr * sizeof(NET_IP_ADDR));
|
||
popt_route->Ptr = NET_IP_OPT_ROUTE_PTR_ROUTE;
|
||
popt_route->Pad = NET_IP_HDR_OPT_PAD; /* ???? PAD &/or NOP val? */
|
||
|
||
switch (popt_cfg_route_ts->Type) {
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_STRICT:
|
||
popt_route->Type = NET_IP_HDR_OPT_ROUTE_SRC_STRICT;
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_LOOSE:
|
||
popt_route->Type = NET_IP_HDR_OPT_ROUTE_SRC_LOOSE;
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_ROUTE_REC:
|
||
popt_route->Type = NET_IP_HDR_OPT_ROUTE_REC;
|
||
opt_route_spec = DEF_NO;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_NONE:
|
||
default: /* See Note #4. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
/* ------------------ PREPARE ROUTE ------------------- */
|
||
for (opt_route_ix = 0; opt_route_ix < popt_cfg_route_ts->Nbr; opt_route_ix++) {
|
||
/* Cfg specified or rec route addrs. */
|
||
if (opt_route_spec == DEF_YES) {
|
||
opt_route_addr = popt_cfg_route_ts->Route[opt_route_ix];
|
||
} else {
|
||
opt_route_addr = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
}
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&popt_route->Route[opt_route_ix], &opt_route_addr);
|
||
}
|
||
|
||
|
||
*popt_len = popt_route->Len;
|
||
*popt_next = popt_cfg_route_ts->NextOptPtr;
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktPrepareOptTS()
|
||
*
|
||
* Description : (1) Prepare IP header with Internet Timestamp option :
|
||
*
|
||
* (a) Prepare Internet Timestamp option header
|
||
* (b) Prepare Internet Timestamps
|
||
*
|
||
* (2) See RFC #791, Section 3.1 'Options : Internet Timestamp'.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to Internet Timestamp option configuration data structure.
|
||
* ----- Argument checked in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* popt_hdr Pointer to IP transmit option buffer to prepare Internet Timestamp option.
|
||
* -------- Argument validated in NetIP_TxPkt().
|
||
*
|
||
* popt_len Pointer to variable that will receive the Internet Timestamp option length
|
||
* -------- (in octets).
|
||
*
|
||
* Argument validated in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* popt_next Pointer to variable that will receive the pointer to the next IP transmit option.
|
||
* -------- Argument validated in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Internet Timestamp option successfully prepared.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktPrepareOpt().
|
||
*
|
||
* Note(s) : (3) Transmit arguments & options validated in NetIP_TxPktValidate()/NetIP_TxPktValidateOpt() :
|
||
*
|
||
* (a) Assumes ALL transmit arguments & options are valid
|
||
* (b) Assumes total transmit options' lengths are valid
|
||
*
|
||
* (4) Default case already invalidated in NetIP_TxPktValidateOpt(). However, the default
|
||
* case is included as an extra precaution in case any of the IP transmit options types
|
||
* are incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_TxPktPrepareOptTS (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
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
|
||
NET_IP_OPT_CFG_ROUTE_TS *popt_cfg_route_ts;
|
||
NET_IP_OPT_TS *popt_ts;
|
||
CPU_INT08U opt_ts_ovf;
|
||
CPU_INT08U opt_ts_flags;
|
||
CPU_INT08U opt_ts_ix;
|
||
NET_TS opt_ts;
|
||
|
||
|
||
/* ---------------- PREPARE TS OPT HDR ---------------- */
|
||
popt_cfg_route_ts = (NET_IP_OPT_CFG_ROUTE_TS *)popts;
|
||
|
||
switch (popt_cfg_route_ts->Type) {
|
||
case NET_IP_OPT_CFG_TYPE_TS_ONLY:
|
||
popt_ts = (NET_IP_OPT_TS *)popt_hdr;
|
||
popt_ts->Type = NET_IP_HDR_OPT_TS;
|
||
popt_ts->Len = NET_IP_HDR_OPT_SIZE_TS + (popt_cfg_route_ts->Nbr * sizeof(NET_TS));
|
||
popt_ts->Ptr = NET_IP_OPT_TS_PTR_TS;
|
||
|
||
opt_ts_ovf = 0;
|
||
opt_ts_flags = NET_IP_OPT_TS_FLAG_TS_ONLY;
|
||
popt_ts->Ovf_Flags = opt_ts_ovf | opt_ts_flags;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_NONE:
|
||
default: /* See Note #4. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
/* -------------------- PREPARE TS -------------------- */
|
||
for (opt_ts_ix = 0; opt_ts_ix < popt_cfg_route_ts->Nbr; opt_ts_ix++) {
|
||
opt_ts = popt_cfg_route_ts->TS[opt_ts_ix];
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&popt_ts->TS[opt_ts_ix], &opt_ts);
|
||
}
|
||
|
||
|
||
*popt_len = popt_ts->Len;
|
||
*popt_next = popt_cfg_route_ts->NextOptPtr;
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktPrepareOptTSRoute()
|
||
*
|
||
* Description : (1) Prepare IP header with Internet Timestamp with IP Route option :
|
||
*
|
||
* (a) Prepare Internet Timestamp option header
|
||
* (b) Prepare Internet Timestamps
|
||
*
|
||
* (2) See RFC #791, Section 3.1 'Options : Internet Timestamp'.
|
||
*
|
||
*
|
||
* Argument(s) : popts Pointer to Internet Timestamp option configuration data structure.
|
||
* ----- Argument checked in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* popt_hdr Pointer to IP transmit option buffer to prepare Internet Timestamp option.
|
||
* -------- Argument validated in NetIP_TxPkt().
|
||
*
|
||
* popt_len Pointer to variable that will receive the Internet Timestamp option length
|
||
* -------- Argument validated in NetIP_TxPktPrepareOpt().
|
||
* (in octets).
|
||
*
|
||
* popt_next Pointer to variable that will receive the pointer to the next IP transmit option.
|
||
* -------- Argument validated in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE Internet Timestamp with IP Route option
|
||
* successfully prepared.
|
||
* NET_IP_ERR_INVALID_OPT_TYPE Invalid IP option type.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktPrepareOpt().
|
||
*
|
||
* Note(s) : (3) Transmit arguments & options validated in NetIP_TxPktValidate()/NetIP_TxPktValidateOpt() :
|
||
*
|
||
* (a) Assumes ALL transmit arguments & options are valid
|
||
* (b) Assumes total transmit options' lengths are valid
|
||
*
|
||
* (4) Default case already invalidated in NetIP_TxPktValidateOpt(). However, the default
|
||
* case is included as an extra precaution in case any of the IP transmit options types
|
||
* are incorrectly modified.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_TxPktPrepareOptTSRoute (void *popts,
|
||
CPU_INT08U *popt_hdr,
|
||
CPU_INT08U *popt_len,
|
||
void **popt_next,
|
||
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
|
||
NET_IP_OPT_CFG_ROUTE_TS *popt_cfg_route_ts;
|
||
NET_IP_OPT_TS_ROUTE *popt_ts_route;
|
||
NET_IP_ROUTE_TS *proute_ts;
|
||
CPU_INT08U opt_ts_ovf;
|
||
CPU_INT08U opt_ts_flags;
|
||
CPU_INT08U opt_ts_ix;
|
||
NET_TS opt_ts;
|
||
CPU_BOOLEAN opt_route_spec;
|
||
NET_IP_ADDR opt_route_addr;
|
||
|
||
|
||
/* ---------------- PREPARE TS OPT HDR ---------------- */
|
||
popt_cfg_route_ts = (NET_IP_OPT_CFG_ROUTE_TS *)popts;
|
||
popt_ts_route = (NET_IP_OPT_TS_ROUTE *)popt_hdr;
|
||
popt_ts_route->Type = NET_IP_HDR_OPT_TS;
|
||
popt_ts_route->Len = NET_IP_HDR_OPT_SIZE_TS + (popt_cfg_route_ts->Nbr * (sizeof(NET_IP_ADDR) + sizeof(NET_TS)));
|
||
popt_ts_route->Ptr = NET_IP_OPT_TS_PTR_TS;
|
||
opt_ts_ovf = 0;
|
||
|
||
switch (popt_cfg_route_ts->Type) {
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_REC:
|
||
opt_ts_flags = NET_IP_OPT_TS_FLAG_TS_ROUTE_REC;
|
||
popt_ts_route->Ovf_Flags = opt_ts_ovf | opt_ts_flags;
|
||
opt_route_spec = DEF_NO;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_TS_ROUTE_SPEC:
|
||
opt_ts_flags = NET_IP_OPT_TS_FLAG_TS_ROUTE_SPEC;
|
||
popt_ts_route->Ovf_Flags = opt_ts_ovf | opt_ts_flags;
|
||
opt_route_spec = DEF_YES;
|
||
break;
|
||
|
||
|
||
case NET_IP_OPT_CFG_TYPE_NONE:
|
||
default: /* See Note #4. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxOptTypeCtr);
|
||
*perr = NET_IP_ERR_INVALID_OPT_TYPE;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
|
||
/* ----------------- PREPARE ROUTE/TS ----------------- */
|
||
proute_ts = &popt_ts_route->Route_TS[0];
|
||
for (opt_ts_ix = 0; opt_ts_ix < popt_cfg_route_ts->Nbr; opt_ts_ix++) {
|
||
/* Cfg specified or rec route addrs. */
|
||
if (opt_route_spec == DEF_YES) {
|
||
opt_route_addr = popt_cfg_route_ts->Route[opt_ts_ix];
|
||
} else {
|
||
opt_route_addr = (NET_IP_ADDR)NET_IP_ADDR_NONE;
|
||
}
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&proute_ts->Route[opt_ts_ix], &opt_route_addr);
|
||
|
||
opt_ts = popt_cfg_route_ts->TS[opt_ts_ix];
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&proute_ts->TS[opt_ts_ix], &opt_ts);
|
||
}
|
||
|
||
|
||
*popt_len = popt_ts_route->Len;
|
||
*popt_next = popt_cfg_route_ts->NextOptPtr;
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktPrepareHdr()
|
||
*
|
||
* Description : (1) Prepare IP header :
|
||
*
|
||
* (a) Update network buffer's protocol index & length controls.
|
||
*
|
||
* (b) Prepare the transmit packet's following IP header fields :
|
||
*
|
||
* (1) Version
|
||
* (2) Header Length
|
||
* (3) Type of Service (TOS)
|
||
* (4) Total Length
|
||
* (5) Identification (ID)
|
||
* (6) Flags
|
||
* (7) Fragment Offset
|
||
* (8) Time-to-Live (TTL)
|
||
* (9) Protocol
|
||
* (10) Check-Sum See Note #6
|
||
* (11) Source Address
|
||
* (12) Destination Address
|
||
* (13) Options
|
||
*
|
||
* (c) Convert the following IP header fields from host-order to network-order :
|
||
*
|
||
* (1) Total Length
|
||
* (2) Identification (ID)
|
||
* (3) Flags/Fragment Offset
|
||
* (4) Source Address
|
||
* (5) Destination Address
|
||
* (6) Check-Sum See Note #6c
|
||
* (7) Options See Note #5
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
* ---- Argument checked in NetIP_Tx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Tx().
|
||
*
|
||
* ip_hdr_len_tot Total IP header length.
|
||
* -------------- Argument checked in NetIP_TxPkt().
|
||
*
|
||
* ip_opt_len_tot Total IP header options' length.
|
||
* -------------- Argument checked in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* protocol_ix Index to higher-layer protocol header.
|
||
*
|
||
* addr_src Source IP address.
|
||
* -------- Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* addr_dest Destination IP address.
|
||
* --------- Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* TOS Specific TOS to transmit IP packet
|
||
* --- (see 'net_ip.h IP HEADER TYPE OF SERVICE (TOS) DEFINES').
|
||
* Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* TTL Specific TTL to transmit IP packet (see RFC #1122, Section 3.2.1.7) :
|
||
* ---
|
||
* NET_IP_HDR_TTL_MIN 1 minimum TTL transmit value
|
||
* NET_IP_HDR_TTL_MAX 255 maximum TTL transmit value
|
||
* NET_IP_HDR_TTL_DFLT default TTL transmit value
|
||
* NET_IP_HDR_TTL_NONE 0 replace with default TTL
|
||
*
|
||
* Argument validated in NetIP_TxPktValidate().
|
||
*
|
||
* flags Flags to select transmit options; bit-field flags logically OR'd :
|
||
* -----
|
||
* NET_IP_FLAG_NONE No IP transmit flags selected.
|
||
* NET_IP_FLAG_TX_DONT_FRAG Set IP 'Don't Frag' flag.
|
||
*
|
||
* Argument checked in NetIP_TxPktValidate().
|
||
*
|
||
* pip_hdr_opts Pointer to IP options buffer.
|
||
* ------------ Argument checked in NetIP_TxPktPrepareOpt().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP header successfully prepared.
|
||
* NET_ERR_INVALID_PROTOCOL Invalid/unknown protocol type.
|
||
*
|
||
* ----------- RETURNED BY NetBuf_DataWr() : -----------
|
||
* NET_BUF_ERR_INVALID_IX Invalid buffer index for transmit options.
|
||
* NET_BUF_ERR_INVALID_LEN Invalid buffer length for transmit options.
|
||
*
|
||
* - RETURNED BY NetUtil_16BitOnesCplChkSumHdrCalc() : -
|
||
* NET_UTIL_ERR_NULL_PTR Check-sum passed a NULL pointer.
|
||
* NET_UTIL_ERR_NULL_SIZE Check-sum passed a zero size.
|
||
*
|
||
*$PAGE*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPkt().
|
||
*
|
||
* Note(s) : (2) See 'net_ip.h IP HEADER' for IP header format.
|
||
*
|
||
* (3) Supports ONLY the following protocols :
|
||
*
|
||
* (a) ICMP
|
||
* (b) UDP
|
||
* (c) TCP
|
||
*
|
||
* See also 'net.h Note #1a'.
|
||
*
|
||
* (4) Default case already invalidated in NetIP_TxPktValidate(). However, the default case is
|
||
* included as an extra precaution in case 'ProtocolHdrType' is incorrectly modified.
|
||
*
|
||
* (5) Assumes ALL IP options' multi-octet words previously converted from host-order to
|
||
* network-order.
|
||
*
|
||
* (6) (a) IP header Check-Sum MUST be calculated AFTER the entire IP header 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) IP header Check-Sum field MUST be cleared to '0' BEFORE the IP header Check-Sum is
|
||
* calculated (see RFC #791, Section 3.1 'Header Checksum').
|
||
*
|
||
* (c) The IP header 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').
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_TxPktPrepareHdr (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
CPU_INT16U ip_hdr_len_tot,
|
||
CPU_INT08U ip_opt_len_tot,
|
||
CPU_INT16U protocol_ix,
|
||
NET_IP_ADDR addr_src,
|
||
NET_IP_ADDR addr_dest,
|
||
NET_IP_TOS TOS,
|
||
NET_IP_TTL TTL,
|
||
CPU_INT16U flags,
|
||
CPU_INT32U *pip_hdr_opts,
|
||
NET_ERR *perr)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
NET_IP_HDR *pip_hdr;
|
||
CPU_INT08U ip_ver;
|
||
CPU_INT08U ip_hdr_len;
|
||
CPU_INT16U ip_id;
|
||
CPU_INT16U ip_flags;
|
||
CPU_INT16U ip_frag_offset;
|
||
CPU_INT16U ip_opt_ix;
|
||
CPU_INT16U ip_flags_frag_offset;
|
||
CPU_INT16U ip_chk_sum;
|
||
|
||
|
||
/* ----------------- UPDATE BUF CTRLS ----------------- */
|
||
pbuf_hdr->IP_HdrLen = ip_hdr_len_tot;
|
||
pbuf_hdr->IP_HdrIx = protocol_ix - pbuf_hdr->IP_HdrLen;
|
||
|
||
pbuf_hdr->IP_DataLen = (CPU_INT16U ) pbuf_hdr->TotLen;
|
||
pbuf_hdr->IP_DatagramLen = (CPU_INT16U ) pbuf_hdr->TotLen;
|
||
pbuf_hdr->TotLen += (NET_BUF_SIZE) pbuf_hdr->IP_HdrLen;
|
||
pbuf_hdr->IP_TotLen = (CPU_INT16U ) pbuf_hdr->TotLen;
|
||
|
||
|
||
|
||
/* ------------------ PREPARE IP HDR ------------------ */
|
||
pip_hdr = (NET_IP_HDR *)&pbuf->Data[pbuf_hdr->IP_HdrIx];
|
||
|
||
|
||
|
||
/* -------------- PREPARE IP VER/HDR LEN -------------- */
|
||
ip_ver = NET_IP_HDR_VER;
|
||
ip_ver <<= NET_IP_HDR_VER_SHIFT;
|
||
|
||
ip_hdr_len = pbuf_hdr->IP_HdrLen / NET_IP_HDR_LEN_WORD_SIZE;
|
||
ip_hdr_len &= NET_IP_HDR_LEN_MASK;
|
||
|
||
pip_hdr->Ver_HdrLen = ip_ver | ip_hdr_len;
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ------------------ PREPARE IP TOS ------------------ */
|
||
pip_hdr->TOS = TOS;
|
||
|
||
|
||
|
||
/* ---------------- PREPARE IP TOT LEN ---------------- */
|
||
NET_UTIL_VAL_COPY_SET_NET_16(&pip_hdr->TotLen, &pbuf_hdr->TotLen);
|
||
|
||
|
||
|
||
/* ------------------ PREPARE IP ID ------------------- */
|
||
NET_IP_TX_GET_ID(ip_id);
|
||
NET_UTIL_VAL_COPY_SET_NET_16(&pip_hdr->ID, &ip_id);
|
||
|
||
|
||
|
||
/* --------------- PREPARE IP FLAGS/FRAG -------------- */
|
||
ip_flags = NET_IP_HDR_FLAG_NONE;
|
||
ip_flags |= flags;
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
ip_flags &= NET_IP_HDR_FLAG_MASK;
|
||
#endif
|
||
|
||
ip_frag_offset = NET_IP_HDR_FRAG_OFFSET_NONE;
|
||
|
||
ip_flags_frag_offset = ip_flags | ip_frag_offset;
|
||
NET_UTIL_VAL_COPY_SET_NET_16(&pip_hdr->Flags_FragOffset, &ip_flags_frag_offset);
|
||
|
||
|
||
|
||
/* ------------------ PREPARE IP TTL ------------------ */
|
||
if (TTL != NET_IP_HDR_TTL_NONE) {
|
||
pip_hdr->TTL = TTL;
|
||
} else {
|
||
pip_hdr->TTL = NET_IP_HDR_TTL_DFLT;
|
||
}
|
||
|
||
|
||
|
||
/* --------------- PREPARE IP PROTOCOL ---------------- */
|
||
switch (pbuf_hdr->ProtocolHdrType) { /* Demux IP protocol (see Note #3). */
|
||
case NET_PROTOCOL_TYPE_ICMP:
|
||
pip_hdr->Protocol = NET_IP_HDR_PROTOCOL_ICMP;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_UDP:
|
||
pip_hdr->Protocol = NET_IP_HDR_PROTOCOL_UDP;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_TCP:
|
||
pip_hdr->Protocol = NET_IP_HDR_PROTOCOL_TCP;
|
||
break;
|
||
|
||
|
||
case NET_PROTOCOL_TYPE_NONE:
|
||
default: /* See Note #4. */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxProtocolCtr);
|
||
*perr = NET_ERR_INVALID_PROTOCOL;
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
|
||
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_IP; /* Update buf protocol for IP. */
|
||
|
||
|
||
|
||
/* ----------------- PREPARE IP ADDRS ----------------- */
|
||
pbuf_hdr->IP_AddrSrc = addr_src;
|
||
pbuf_hdr->IP_AddrDest = addr_dest;
|
||
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&pip_hdr->AddrSrc, &addr_src);
|
||
NET_UTIL_VAL_COPY_SET_NET_32(&pip_hdr->AddrDest, &addr_dest);
|
||
|
||
|
||
|
||
/*$PAGE*/
|
||
/* ----------------- PREPARE IP OPTS ------------------ */
|
||
if (ip_opt_len_tot > 0) {
|
||
ip_opt_ix = pbuf_hdr->IP_HdrIx + NET_IP_HDR_OPT_IX;
|
||
NetBuf_DataWr((NET_BUF *)pbuf, /* See Note #5. */
|
||
(NET_BUF_SIZE)ip_opt_ix,
|
||
(NET_BUF_SIZE)ip_opt_len_tot,
|
||
(CPU_INT08U *)pip_hdr_opts,
|
||
(NET_ERR *)perr);
|
||
#if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED)
|
||
if (*perr != NET_BUF_ERR_NONE) {
|
||
return;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
/* ---------------- PREPARE IP CHK SUM ---------------- */
|
||
/* See Note #6. */
|
||
NET_UTIL_VAL_SET_NET_16(&pip_hdr->ChkSum, 0x0000); /* Clr chk sum (see Note #6b). */
|
||
/* Calc chk sum. */
|
||
ip_chk_sum = NetUtil_16BitOnesCplChkSumHdrCalc((void *)pip_hdr,
|
||
(CPU_INT16U)ip_hdr_len_tot,
|
||
(NET_ERR *)perr);
|
||
if (*perr != NET_UTIL_ERR_NONE) {
|
||
return;
|
||
}
|
||
|
||
NET_UTIL_VAL_COPY_16(&pip_hdr->ChkSum, &ip_chk_sum); /* Copy chk sum in net order (see Note #6c). */
|
||
|
||
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktDatagram()
|
||
*
|
||
* Description : (1) Transmit IP packet datagram :
|
||
*
|
||
* (a) Select next-hop IP address
|
||
* (b) Post IP packet datagram to next queue :
|
||
*
|
||
* (1) Destination is this host Reflect back to IP Receive
|
||
* (A) This host's address
|
||
* (B) Localhost address
|
||
* (2) Limited Broadcast Send to Network Interface Transmit
|
||
* ???? Reflect back to IP Receive
|
||
* (3) Local Host Send to Network Interface Transmit
|
||
* (4) Remote Host Send to Network Interface Transmit
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
* ---- Argument checked in NetIP_Tx(),
|
||
* NetIP_ReTx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Tx(),
|
||
* NetIP_ReTx().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* ----------- RETURNED BY NetIP_Rx() : ------------
|
||
* NET_IP_ERR_NONE IP datagram successfully received & processed.
|
||
*
|
||
* ----------- RETURNED BY NetIF_Tx() : ------------
|
||
* NET_IF_ERR_NONE Packet successfully transmitted.
|
||
*
|
||
* - RETURNED BY NetIP_TxPktDatagramNextHopSel() : -
|
||
* NET_IP_ERR_TX_DEST_INVALID Invalid transmit destination.
|
||
* NET_IP_ERR_INVALID_ADDR_HOST Invalid IP host address.
|
||
* NET_IP_ERR_INVALID_ADDR_NET Invalid IP net address.
|
||
* NET_IP_ERR_INVALID_ADDR_GATEWAY Invalid IP gateway address.
|
||
*
|
||
*
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPkt(),
|
||
* NetIP_ReTxPkt().
|
||
*
|
||
* Note(s) : (2) Since ALL fields in the transmit datagram's IP header have been converted from host-order
|
||
* to network-order, 'addr_dest' is passed to avoid re-conversion back to host-order.
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_TxPktDatagram (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr)
|
||
{
|
||
/* ---------------- SEL NEXT-HOP ADDR ----------------- */
|
||
NetIP_TxPktDatagramNextHopSel(pbuf_hdr, perr);
|
||
|
||
|
||
switch (*perr) { /* --------------- POST IP PKT DATAGRAM --------------- */
|
||
case NET_IP_ERR_TX_DEST_THIS_HOST:
|
||
case NET_IP_ERR_TX_DEST_LOCALHOST:
|
||
/* Cfg valid rx len ctrls. */
|
||
pbuf_hdr->IF_DataLenMin = (CPU_INT16U )0;
|
||
pbuf_hdr->DataLen = (NET_BUF_SIZE)pbuf_hdr->IP_TotLen;
|
||
|
||
NetIP_Rx(pbuf, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_ERR_TX_DEST_BROADCAST:
|
||
NetIF_Tx(pbuf, perr);
|
||
#if 0 /* #### NOT yet implemented (see Note #1b2). */
|
||
/* Cfg valid rx len ctrls. */
|
||
pbuf_hdr->IF_DataLenMin = (CPU_INT16U )0;
|
||
pbuf_hdr->DataLen = (NET_BUF_SIZE)pbuf_hdr->IP_TotLen;
|
||
|
||
pbuf_hdr->RefCtr++;
|
||
|
||
NetIP_Rx(pbuf, perr);
|
||
#endif
|
||
break;
|
||
|
||
|
||
case NET_IP_ERR_TX_DEST_HOST_THIS_NET:
|
||
case NET_IP_ERR_TX_DEST_DFLT_GATEWAY:
|
||
NetIF_Tx(pbuf, perr);
|
||
break;
|
||
|
||
|
||
case NET_IP_ERR_TX_DEST_INVALID:
|
||
case NET_IP_ERR_INVALID_ADDR_HOST:
|
||
case NET_IP_ERR_INVALID_ADDR_NET:
|
||
case NET_IP_ERR_INVALID_ADDR_GATEWAY:
|
||
default:
|
||
return; /* Prevent 'break NOT reachable' compiler warning. */
|
||
}
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktDatagramNextHopSel()
|
||
*
|
||
* Description : (1) Select next-hop address for transmit IP packet datagram (see RFC #1122, Section 3.3.1) :
|
||
*
|
||
* (a) Destination is this host :
|
||
* (1) This host's address See 'net_ip.c Note #1a'
|
||
* (2) Localhost address See RFC #1122, Section 3.2.1.3.(g)
|
||
* (b) Limited Broadcast See RFC #1122, Section 3.3.1.1
|
||
* 'Special Case : Limited Broadcast'
|
||
* (c) Local Broadcast See RFC #1122, Section 3.3.1.1
|
||
* 'Special Case : Limited Broadcast'
|
||
* (d) Local Host See RFC #1122, Section 3.3.1.1.(b)
|
||
* (e) Remote Host See RFC #1122, Section 3.3.1.1.(c)
|
||
*
|
||
* (1) Destinations located on remote networks are sent directly to this host's
|
||
* default gateway (see 'net_ip.c Note #1c').
|
||
*
|
||
* (2) Configure next-hop address in network-order.
|
||
*
|
||
*
|
||
* Argument(s) : pbuf_hdr Pointer to network buffer header of IP transmit packet.
|
||
* -------- Argument validated in NetIP_Tx(),
|
||
* NetIP_ReTx().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_TX_DEST_THIS_HOST Destination is this host's IP address.
|
||
* NET_IP_ERR_TX_DEST_LOCALHOST Destination is localhost.
|
||
* NET_IP_ERR_TX_DEST_BROADCAST Limited broadcast on local network.
|
||
* NET_IP_ERR_TX_DEST_HOST_THIS_NET Destination host on local network.
|
||
* NET_IP_ERR_TX_DEST_DFLT_GATEWAY Destination host on remote network.
|
||
* NET_IP_ERR_TX_DEST_INVALID Invalid IP destination address.
|
||
*
|
||
* NET_IP_ERR_INVALID_ADDR_HOST Invalid IP host address.
|
||
* NET_IP_ERR_INVALID_ADDR_NET Invalid IP net address.
|
||
* NET_IP_ERR_INVALID_ADDR_GATEWAY Invalid IP gateway address.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_TxPktDatagram().
|
||
*
|
||
* Note(s) : (3) See 'net_ip.h IP ADDRESS DEFINES Notes #2, #3, & #4' for supported IP addresses.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_TxPktDatagramNextHopSel (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_IP_ADDR addr_dest;
|
||
|
||
|
||
/* -------------- GET IP PKT'S DEST ADDR -------------- */
|
||
addr_dest = pbuf_hdr->IP_AddrDest;
|
||
|
||
|
||
/*$PAGE*/
|
||
/* --------------- CHK THIS HOST'S ADDR --------------- */
|
||
if (addr_dest == NetIP_AddrThisHost) {
|
||
if (NetIP_AddrThisHost != NET_IP_ADDR_NONE) { /* If valid host addr cfg'd, tx via host's addr. */
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)addr_dest;
|
||
*perr = NET_IP_ERR_TX_DEST_THIS_HOST;
|
||
|
||
} else {
|
||
*perr = NET_IP_ERR_INVALID_ADDR_HOST;
|
||
return;
|
||
}
|
||
|
||
/* ---------------- CHK LOCALHOST ADDR ---------------- */
|
||
} else if ((addr_dest & NET_IP_ADDR_LOCAL_HOST_MASK) == NET_IP_ADDR_LOCAL_HOST) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestLocalCtr);
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)addr_dest;
|
||
*perr = NET_IP_ERR_TX_DEST_LOCALHOST;
|
||
|
||
/* --------------- CHK LIMITED BROADCAST -------------- */
|
||
} else if (addr_dest == NET_IP_ADDR_BROADCAST) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestBroadcastCtr);
|
||
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_TX);
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)addr_dest;
|
||
*perr = NET_IP_ERR_TX_DEST_BROADCAST;
|
||
|
||
/* ------------------ CHK LOCAL NET ------------------- */
|
||
} else if ((addr_dest & NetIP_AddrThisHostSubnetMask) == NetIP_AddrThisHostSubnetNet) {
|
||
/* If valid subnet cfg'd, tx via subnet. */
|
||
if ((NetIP_AddrThisHostSubnetMask != NET_IP_ADDR_NONE) &&
|
||
(NetIP_AddrThisHostSubnetNet != NET_IP_ADDR_NONE)) {
|
||
/* Chk local subnet broadcast (see #1c). */
|
||
if ((addr_dest & NetIP_AddrThisHostSubnetMaskHost) ==
|
||
(NET_IP_ADDR_BROADCAST & NetIP_AddrThisHostSubnetMaskHost)) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestBroadcastCtr);
|
||
DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_TX);
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)addr_dest;
|
||
*perr = NET_IP_ERR_TX_DEST_BROADCAST;
|
||
|
||
} else {
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)addr_dest;
|
||
*perr = NET_IP_ERR_TX_DEST_HOST_THIS_NET;
|
||
}
|
||
|
||
} else {
|
||
*perr = NET_IP_ERR_INVALID_ADDR_NET;
|
||
return;
|
||
}
|
||
|
||
/* ------------------ TX REMOTE NET ------------------- */
|
||
} else {
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_A_MASK) == NET_IP_ADDR_CLASS_A) {
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_A_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_A_MASK_HOST)) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestBroadcastCtr);
|
||
}
|
||
|
||
} else if ((addr_dest & NET_IP_ADDR_CLASS_B_MASK) == NET_IP_ADDR_CLASS_B) {
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_B_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_B_MASK_HOST)) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestBroadcastCtr);
|
||
}
|
||
|
||
} else if ((addr_dest & NET_IP_ADDR_CLASS_C_MASK) == NET_IP_ADDR_CLASS_C) {
|
||
if ((addr_dest & NET_IP_ADDR_CLASS_C_MASK_HOST) ==
|
||
(NET_IP_ADDR_BROADCAST & NET_IP_ADDR_CLASS_C_MASK_HOST)) {
|
||
NET_CTR_STAT_INC(NetIP_StatTxDestBroadcastCtr);
|
||
}
|
||
|
||
} else { /* Discard invalid addr class (see Note #3). */
|
||
NET_CTR_ERR_INC(NetIP_ErrTxDestCtr);
|
||
*perr = NET_IP_ERR_TX_DEST_INVALID;
|
||
return;
|
||
}
|
||
|
||
|
||
if (NetIP_AddrDfltGateway != NET_IP_ADDR_NONE) { /* If valid dflt gateway cfg'd, tx via dflt gateway. */
|
||
pbuf_hdr->IP_AddrNextHop = (CPU_INT32U)NetIP_AddrDfltGateway;
|
||
*perr = NET_IP_ERR_TX_DEST_DFLT_GATEWAY;
|
||
|
||
} else {
|
||
*perr = NET_IP_ERR_INVALID_ADDR_GATEWAY;
|
||
return;
|
||
}
|
||
}
|
||
|
||
|
||
/* ---------- CFG IP NEXT HOP NET-ORDER ADDR ---------- */
|
||
pbuf_hdr->IP_AddrNextHopNetOrder = NET_UTIL_HOST_TO_NET_32(pbuf_hdr->IP_AddrNextHop);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_TxPktDiscard()
|
||
*
|
||
* Description : On any Transmit packet errors, discard packet & buffer.
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer.
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_Tx().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_TxPktDiscard (NET_BUF *pbuf,
|
||
NET_ERR *perr)
|
||
{
|
||
NET_CTR *pctr;
|
||
|
||
|
||
#if (NET_CTR_CFG_ERR_EN == DEF_ENABLED)
|
||
pctr = (NET_CTR *)&NetIP_ErrTxPktDiscardedCtr;
|
||
#else
|
||
pctr = (NET_CTR *) 0;
|
||
#endif
|
||
NetBuf_FreeBuf((NET_BUF *)pbuf,
|
||
(NET_CTR *)pctr);
|
||
|
||
*perr = NET_ERR_TX;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_ReTxPkt()
|
||
*
|
||
* Description : (1) Prepare & re-transmit IP packet :
|
||
*
|
||
* (a) Prepare IP header
|
||
* (b) Re-transmit IP packet datagram
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to re-transmit IP packet.
|
||
* ---- Argument checked in NetIP_ReTx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_ReTx().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* -- RETURNED BY NetIP_ReTxPktPrepareHdr() : ---
|
||
* NET_UTIL_ERR_NULL_PTR Check-sum passed a NULL pointer.
|
||
* NET_UTIL_ERR_NULL_SIZE Check-sum passed a zero size.
|
||
*
|
||
* ---- RETURNED BY NetIP_TxPktDatagram() : -----
|
||
* NET_IP_ERR_NONE IP datagram successfully received & processed.
|
||
* NET_IF_ERR_NONE Packet successfully transmitted.
|
||
* NET_ERR_RX Receive error; packet discarded.
|
||
* NET_ERR_TX Transmit error; packet discarded.
|
||
* NET_IP_ERR_TX_DEST_INVALID Invalid transmit destination.
|
||
* NET_IP_ERR_INVALID_ADDR_HOST Invalid IP host address.
|
||
* NET_IP_ERR_INVALID_ADDR_NET Invalid IP net address.
|
||
* NET_IP_ERR_INVALID_ADDR_GATEWAY Invalid IP gateway address.
|
||
* NET_ERR_INIT_INCOMPLETE Network initialization NOT complete.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_ReTx().
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
static void NetIP_ReTxPkt (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr)
|
||
{
|
||
/* ------------------ PREPARE IP HDR ------------------ */
|
||
NetIP_ReTxPktPrepareHdr(pbuf,
|
||
pbuf_hdr,
|
||
perr);
|
||
if (*perr != NET_IP_ERR_NONE) {
|
||
return;
|
||
}
|
||
|
||
/* -------------- RE-TX IP PKT DATAGRAM --------------- */
|
||
NetIP_TxPktDatagram(pbuf, pbuf_hdr, perr);
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetIP_ReTxPktPrepareHdr()
|
||
*
|
||
* Description : (1) Prepare IP header for re-transmit IP packet :
|
||
*
|
||
* (a) Update network buffer's protocol & length controls.
|
||
*
|
||
* (b) (1) Prepare the re-transmit packet's following IP header fields :
|
||
*
|
||
* (A) Identification (ID) See Note #2
|
||
* (B) Check-Sum See Note #3
|
||
*
|
||
* (2) Assumes the following IP header fields are already validated/prepared &
|
||
* have NOT been modified :
|
||
*
|
||
* (A) Version
|
||
* (B) Header Length
|
||
* (C) Type of Service (TOS)
|
||
* (D) Total Length
|
||
* (E) Flags
|
||
* (F) Fragment Offset
|
||
* (G) Time-to-Live (TTL)
|
||
* (H) Protocol
|
||
* (I) Source Address
|
||
* (J) Destination Address
|
||
* (K) Options
|
||
*
|
||
* (c) Convert the following IP header fields from host-order to network-order :
|
||
*
|
||
* (1) Identification (ID)
|
||
* (2) Check-Sum See Note #3c
|
||
*
|
||
*
|
||
* Argument(s) : pbuf Pointer to network buffer to transmit IP packet.
|
||
* ---- Argument checked in NetIP_Tx().
|
||
*
|
||
* pbuf_hdr Pointer to network buffer header.
|
||
* -------- Argument validated in NetIP_Tx().
|
||
*
|
||
* perr Pointer to variable that will receive the return error code from this function :
|
||
*
|
||
* NET_IP_ERR_NONE IP header successfully prepared.
|
||
*
|
||
* - RETURNED BY NetUtil_16BitOnesCplChkSumHdrCalc() : -
|
||
* NET_UTIL_ERR_NULL_PTR Check-sum passed a NULL pointer.
|
||
* NET_UTIL_ERR_NULL_SIZE Check-sum passed a zero size.
|
||
*
|
||
* Return(s) : none.
|
||
*
|
||
* Caller(s) : NetIP_ReTxPkt().
|
||
*
|
||
* Note(s) : (2) RFC #1122, Section 3.2.1.5 states that "some Internet protocol experts have maintained
|
||
* that when a host sends an identical copy of an earlier datagram, the new copy should
|
||
* contain the same Identification value as the original ... However, ... we believe that
|
||
* retransmitting the same Identification field is not useful".
|
||
*
|
||
* (3) (a) IP header Check-Sum MUST be calculated AFTER the entire IP header 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) IP header Check-Sum field MUST be cleared to '0' BEFORE the IP header Check-Sum is
|
||
* calculated (see RFC #791, Section 3.1 'Header Checksum').
|
||
*
|
||
* (c) The IP header 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').
|
||
*********************************************************************************************************
|
||
*/
|
||
/*$PAGE*/
|
||
static void NetIP_ReTxPktPrepareHdr (NET_BUF *pbuf,
|
||
NET_BUF_HDR *pbuf_hdr,
|
||
NET_ERR *perr)
|
||
{
|
||
#if (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)
|
||
CPU_SR cpu_sr;
|
||
#endif
|
||
NET_IP_HDR *pip_hdr;
|
||
CPU_INT16U ip_id;
|
||
CPU_INT16U ip_hdr_len_tot;
|
||
CPU_INT16U ip_chk_sum;
|
||
|
||
|
||
/* ----------------- UPDATE BUF CTRLS ----------------- */
|
||
pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_IP; /* Update buf protocol for IP. */
|
||
/* Reset tot len for re-tx. */
|
||
pbuf_hdr->TotLen = (NET_BUF_SIZE)pbuf_hdr->IP_TotLen;
|
||
|
||
|
||
/* ------------------ PREPARE IP HDR ------------------ */
|
||
pip_hdr = (NET_IP_HDR *)&pbuf->Data[pbuf_hdr->IP_HdrIx];
|
||
|
||
|
||
/* ------------------ PREPARE IP ID ------------------- */
|
||
NET_IP_TX_GET_ID(ip_id); /* Get new IP ID (see Note #2). */
|
||
NET_UTIL_VAL_COPY_SET_NET_16(&pip_hdr->ID, &ip_id);
|
||
|
||
/* ---------------- PREPARE IP CHK SUM ---------------- */
|
||
/* See Note #3. */
|
||
NET_UTIL_VAL_SET_NET_16(&pip_hdr->ChkSum, 0x0000); /* Clr chk sum (see Note #3b). */
|
||
/* Calc chk sum. */
|
||
ip_hdr_len_tot = pbuf_hdr->IP_HdrLen;
|
||
ip_chk_sum = NetUtil_16BitOnesCplChkSumHdrCalc((void *)pip_hdr,
|
||
(CPU_INT16U)ip_hdr_len_tot,
|
||
(NET_ERR *)perr);
|
||
if (*perr != NET_UTIL_ERR_NONE) {
|
||
return;
|
||
}
|
||
|
||
NET_UTIL_VAL_COPY_16(&pip_hdr->ChkSum, &ip_chk_sum); /* Copy chk sum in net order (see Note #3c). */
|
||
|
||
|
||
|
||
*perr = NET_IP_ERR_NONE;
|
||
}
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
*********************************************************************************************************
|
||
* LAYER INTERFACE FUNCTIONS
|
||
*********************************************************************************************************
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetARP_GetHostAddrPtrProtocol()
|
||
*
|
||
* Description : Get pointer to this host's internet protocol address.
|
||
*
|
||
* Argument(s) : none.
|
||
*
|
||
* Return(s) : Pointer to internet protocol address.
|
||
*
|
||
* Caller(s) : NetARP_Init().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & MUST NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : (1) ARP protocol address MUST be in network-order (see 'net_arp.c NetARP_CacheHandler()
|
||
* Note #2e3').
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#ifdef NET_ARP_MODULE_PRESENT
|
||
CPU_INT08U *NetARP_GetHostAddrPtrProtocol (void)
|
||
{
|
||
CPU_INT08U *paddr;
|
||
|
||
|
||
paddr = (CPU_INT08U *)&NetIP_AddrThisHostNetOrder;
|
||
|
||
return (paddr);
|
||
}
|
||
#endif
|
||
|
||
|
||
/*$PAGE*/
|
||
/*
|
||
*********************************************************************************************************
|
||
* NetARP_IsValidAddrProtocol()
|
||
*
|
||
* Description : Validate an ARP protocol address.
|
||
*
|
||
* Argument(s) : paddr_protocol Pointer to an ARP protocol address.
|
||
* -------------- Argument validated in NetARP_RxPktValidate().
|
||
*
|
||
* Return(s) : DEF_YES, if protocol address valid.
|
||
*
|
||
* DEF_NO, otherwise.
|
||
*
|
||
* Caller(s) : NetARP_RxPktValidate().
|
||
*
|
||
* This function is an INTERNAL network protocol suite function & SHOULD NOT be called by
|
||
* application function(s).
|
||
*
|
||
* Note(s) : none.
|
||
*********************************************************************************************************
|
||
*/
|
||
|
||
#ifdef NET_ARP_MODULE_PRESENT
|
||
CPU_BOOLEAN NetARP_IsValidAddrProtocol (CPU_INT08U *paddr_protocol)
|
||
{
|
||
NET_IP_ADDR addr;
|
||
CPU_BOOLEAN valid;
|
||
|
||
|
||
Mem_Copy((void *)&addr,
|
||
(void *)paddr_protocol,
|
||
(CPU_SIZE_T)NET_ARP_CFG_PROTOCOL_ADDR_LEN);
|
||
|
||
addr = NET_UTIL_NET_TO_HOST_32(addr);
|
||
valid = NetIP_IsValidAddrHost(addr);
|
||
|
||
return (valid);
|
||
}
|
||
#endif
|
||
|