/* ********************************************************************************************************* * uC/TCP-IP * The Embedded TCP/IP Suite * * (c) Copyright 2003-2006; Micrium, Inc.; Weston, FL * * All rights reserved. Protected by international copyright laws. * Knowledge of the source code may not be used to write a similar * product. This file may only be used in accordance with a license * and should not be redistributed in any way. ********************************************************************************************************* */ /* ********************************************************************************************************* * * NETWORK INTERFACE LAYER * * ETHERNET * * Filename : net_if.c * Version : V1.86 * Programmer(s) : ITJ ********************************************************************************************************* * Note(s) : (1) Supports Ethernet as described in RFC #894; supports IEEE 802 as described in RFC #1042. * * (2) Ethernet implementation conforms to RFC #1122, Section 2.3.3, bullets (a) & (b), but * does NOT implement bullet (c) : * * RFC #1122 LINK LAYER October 1989 * * 2.3.3 ETHERNET (RFC-894) and IEEE 802 (RFC-1042) ENCAPSULATION * * Every Internet host connected to a 10Mbps Ethernet cable : * * (a) MUST be able to send and receive packets using RFC-894 encapsulation; * * (b) SHOULD be able to receive RFC-1042 packets, intermixed with RFC-894 packets; and * * (c) MAY be able to send packets using RFC-1042 encapsulation. * * (3) REQUIREs the following network protocol files in network directories : * * where * directory path for network protocol suite * * (a) Packet-based Network Interface Layer located in the following network directory : * * \\IF\ * * (b) Address Resolution Protocol Layer located in the following network directory : * * \\ * * See also 'net_arp.h Note #1'. ********************************************************************************************************* */ /* ********************************************************************************************************* * INCLUDE FILES ********************************************************************************************************* */ #define NET_IF_MODULE #include /*$PAGE*/ /* ********************************************************************************************************* * LOCAL DEFINES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL CONSTANTS ********************************************************************************************************* */ /* --------------- ETHER BROADCAST ADDR --------------- */ static const CPU_INT08U NetIF_AddrBroadcast[NET_IF_ADDR_SIZE] = { NET_IF_ADDR_BROADCAST_00, NET_IF_ADDR_BROADCAST_01, NET_IF_ADDR_BROADCAST_02, NET_IF_ADDR_BROADCAST_03, NET_IF_ADDR_BROADCAST_04, NET_IF_ADDR_BROADCAST_05 }; /* ********************************************************************************************************* * LOCAL DATA TYPES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL TABLES ********************************************************************************************************* */ /* ********************************************************************************************************* * LOCAL GLOBAL VARIABLES ********************************************************************************************************* */ /*$PAGE*/ /* ********************************************************************************************************* * LOCAL FUNCTION PROTOTYPES ********************************************************************************************************* */ /* ------------------- RX FCNTS ------------------- */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetIF_RxPktValidateBuf (NET_BUF_HDR *pbuf_hdr, NET_ERR *perr); #endif static void NetIF_RxPktFrameDemux (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_hdr, NET_ERR *perr); static void NetIF_RxPktFrameDemuxEther (NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_hdr, NET_ERR *perr); static void NetIF_RxPktFrameDemuxIEEE802(NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_hdr, NET_ERR *perr); static void NetIF_RxPktDiscard (NET_BUF *pbuf, NET_ERR *perr); /* ------------------- TX FNCTS ------------------- */ static void NetIF_TxPktHandler (NET_BUF *pbuf_q); #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetIF_TxPktValidate (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_ERR *perr); #endif static void NetIF_TxPktPrepareFrame (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_ERR *perr); /* ********************************************************************************************************* * LOCAL CONFIGURATION ERRORS ********************************************************************************************************* */ /*$PAGE*/ /* ********************************************************************************************************* * NetIF_Init() * * Description : (1) Initialize Network Interface Layer : * * (a) Initialize network interface statistics & error counters * (b) Initialize Packet-based Network Interface Layer * (see this 'net_if_.c Note #3a') * (c) Initialize Address Resolution Protocol Layer * (see this 'net_if_.c Note #3b') * * * Argument(s) : perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Network interface layer successfully * initialized. * * --- RETURNED BY NetIF_Pkt_Init() : --- * NET_OS_ERR_INIT_IF_RX_Q Network interface receive queue signal * NOT successfully initialized. * NET_OS_ERR_INIT_IF_RX_Q_NAME Network interface receive queue name * NOT successfully configured. * NET_OS_ERR_INIT_IF_RX_TASK Network interface receive task * NOT successfully initialized. * NET_OS_ERR_INIT_IF_RX_TASK_NAME Network interface receive task name * NOT successfully configured. * * Return(s) : none. * * Caller(s) : Net_Init(). * * Note(s) : (2) MAC address MUST be initialized & validated in NIC driver initialization. ********************************************************************************************************* */ void NetIF_Init (NET_ERR *perr) { /* ----------- INIT NET IF STAT & ERR CTRS ------------ */ #if (NET_CTR_CFG_STAT_EN == DEF_ENABLED) NetIF_StatRxPktCtr = 0; NetIF_StatRxPktProcessedCtr = 0; NetIF_StatRxPktBroadcastCtr = 0; NetIF_StatTxPktCtr = 0; NetIF_StatTxPktBroadcastCtr = 0; #endif #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) NetIF_ErrNullPtrCtr = 0; NetIF_ErrInvalidProtocolCtr = 0; NetIF_ErrRxInvalidFrameCtr = 0; NetIF_ErrRxInvalidAddrDestCtr = 0; NetIF_ErrRxInvalidAddrSrcCtr = 0; NetIF_ErrRxPktDiscardedCtr = 0; NetIF_ErrTxInvalidBufLenCtr = 0; NetIF_ErrTxPktDiscardedCtr = 0; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NetIF_ErrRxInvalidBufIxCtr = 0; NetIF_ErrTxProtocolCtr = 0; NetIF_ErrTxInvalidBufIxCtr = 0; NetIF_ErrTxHdrDataLenCtr = 0; #endif #endif /* ---------------- INIT PKT IF MODULE ---------------- */ NetIF_Pkt_Init(perr); if (*perr != NET_IF_ERR_NONE) { return; } /* ----------------- INIT ARP MODULE ------------------ */ NetARP_Init(); *perr = NET_IF_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_MAC_AddrGet() * * Description : Get NIC's hardware (MAC) address. * * Argument(s) : paddr Pointer to memory buffer to receive NIC's hardware address (see Note #2). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE NIC's hardware address successfully returned. * NET_IF_ERR_INVALID_MAC Invalid or uninitialized hardware address. * * Return(s) : none. * * Caller(s) : NetIF_InitDrv(). * * Note(s) : (1) NIC's hardware address also known as MAC (Media Access Control) or physical address. * * (2) (a) The size of the memory buffer that will receive the return NIC hardware address * MUST be greater than or equal to NET_IF_ADDR_SIZE. * * (b) NIC's hardware address accessed by octets in memory buffer array. * * (c) NIC's hardware address memory array cleared in case of any error(s). ********************************************************************************************************* */ void NetIF_MAC_AddrGet (CPU_INT08U *paddr, NET_ERR *perr) { if (NetIF_MAC_AddrValid != DEF_YES) { Mem_Clr((void *)paddr, (CPU_SIZE_T)NET_IF_ADDR_SIZE); *perr = NET_IF_ERR_INVALID_MAC; return; } Mem_Copy((void *) paddr, (void *)&NetIF_MAC_Addr[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); *perr = NET_IF_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_MAC_AddrSet() * * Description : Set NIC's hardware (MAC) address. * * Argument(s) : paddr Pointer to a memory buffer that contains the NIC's hardware address (see Note #2). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE NIC's hardware address successfully configured. * NET_IF_ERR_NULL_PTR Argument 'paddr' passed a NULL pointer. * * Return(s) : none. * * Caller(s) : NetIF_InitDrv(). * * Note(s) : (1) NIC's hardware address also known as MAC (Media Access Control) or physical address. * * (2) (a) The size of the memory buffer that contains the NIC hardware address MUST be greater * than or equal to NET_IF_ADDR_SIZE. * * (b) NIC's hardware address accessed by octets in memory buffer array. ********************************************************************************************************* */ void NetIF_MAC_AddrSet (CPU_INT08U *paddr, NET_ERR *perr) { #if (NET_ERR_CFG_ARG_CHK_EXT_EN == DEF_ENABLED) if (paddr == (CPU_INT08U *)0) { *perr = NET_IF_ERR_NULL_PTR; return; } #endif Mem_Copy((void *)&NetIF_MAC_Addr[0], (void *) paddr, (CPU_SIZE_T) NET_IF_ADDR_SIZE); NetIF_MAC_AddrValid = DEF_YES; *perr = NET_IF_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_IsValidPktSize() * * Description : Validate an Ethernet packet size. * * Argument(s) : size Number of Ethernet packet frame octets. * * Return(s) : DEF_YES, if NIC packet size valid. * * DEF_NO, otherwise. * * Caller(s) : NetIF_RxTaskHandler(). * * Note(s) : none. ********************************************************************************************************* */ CPU_BOOLEAN NetIF_IsValidPktSize (CPU_INT16U size) { CPU_BOOLEAN valid; valid = DEF_YES; if (size < NET_IF_FRAME_MIN_SIZE) { valid = DEF_NO; } if (size > NET_IF_FRAME_MAX_CRC_SIZE) { valid = DEF_NO; } return (valid); } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_IsValidAddrSrc() * * Description : (1) Validate an Ethernet hardware address which MUST NOT be one of the following : * * (a) Ethernet broadcast address See RFC #894, Section 'Address Mappings : * Broadcast Address' * * * Argument(s) : paddr_src Pointer to an Ethernet hardware address. * * Return(s) : DEF_YES, if Ethernet hardware address valid. * * DEF_NO, otherwise. * * Caller(s) : NetIF_RxPktFrameDemux(), * NetARP_IsValidAddrHW(). * * Note(s) : none. ********************************************************************************************************* */ CPU_BOOLEAN NetIF_IsValidAddrSrc (CPU_INT08U *paddr_src) { #if ((NET_CTR_CFG_ERR_EN == DEF_ENABLED) && \ (CPU_CFG_CRITICAL_METHOD == CPU_CRITICAL_METHOD_STATUS_LOCAL)) CPU_SR cpu_sr; #endif CPU_BOOLEAN broadcast; CPU_BOOLEAN valid; /* ----------------- VALIDATE PTR ----------------- */ if (paddr_src == (CPU_INT08U *)0) { NET_CTR_ERR_INC(NetIF_ErrNullPtrCtr); return (DEF_NO); } /* -------------- VALIDATE SRC ADDR --------------- */ broadcast = Mem_Cmp((void *) paddr_src, (void *)&NetIF_AddrBroadcast[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); valid = (broadcast == DEF_NO) ? DEF_YES : DEF_NO; return (valid); } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_Rx() * * Description : (1) Process received data packets from packet-based network interface layer & forward to * network protocol layers : * * (a) Validate & demultiplex packet to higher-layer protocols * (b) Update receive statistics * * * Argument(s) : pbuf Pointer to network buffer that received IF packet. * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE IF packet successfully received & processed. * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * * ---- RETURNED BY NetIF_RxPktDiscard() : ---- * NET_ERR_RX Receive error; packet discarded. * * Return(s) : none. * * Caller(s) : NetIF_RxTaskHandler() [see Note #2]. * * Note(s) : (2) Network Interface Receive Task Handler implemented in Packet-based Network Interface * [see '\\IF\net_if_pkt.c NetIF_RxTaskHandler()']. * * (3) NetIF_Rx() blocked until network initialization completes; perform NO action. * * (4) Network buffer already freed by higher layer; only increment error counter. ********************************************************************************************************* */ /*$PAGE*/ void NetIF_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_IF_HDR *pif_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). */ NetIF_RxPktDiscard(pbuf, perr); *perr = NET_ERR_INIT_INCOMPLETE; return; } #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------- */ if (pbuf == (NET_BUF *)0) { NetIF_RxPktDiscard(pbuf, perr); NET_CTR_ERR_INC(NetIF_ErrNullPtrCtr); return; } #endif NET_CTR_STAT_INC(NetIF_StatRxPktCtr); /* ------------- VALIDATE / DEMUX IF PKT -------------- */ pbuf_hdr = &pbuf->Hdr; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NetIF_RxPktValidateBuf(pbuf_hdr, perr); /* Validate rx'd buf. */ switch (*perr) { case NET_IF_ERR_NONE: break; case NET_ERR_INVALID_PROTOCOL: case NET_BUF_ERR_INVALID_IX: default: NetIF_RxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif pif_hdr = (NET_IF_HDR *)&pbuf->Data[pbuf_hdr->IF_HdrIx]; NetIF_RxPktFrameDemux(pbuf, pbuf_hdr, pif_hdr, perr); /* Validate & demux pkt to appropriate net Q. */ /* ----------------- UPDATE RX STATS ------------------ */ switch (*perr) { case NET_ARP_ERR_NONE: case NET_IP_ERR_NONE: NET_CTR_STAT_INC(NetIF_StatRxPktProcessedCtr); *perr = NET_IF_ERR_NONE; break; case NET_ERR_INIT_INCOMPLETE: case NET_ERR_RX: NET_CTR_ERR_INC(NetIF_ErrRxPktDiscardedCtr); /* See Note #4. */ break; case NET_ERR_INVALID_PROTOCOL: case NET_IF_ERR_INVALID_ADDR_DEST: case NET_IF_ERR_INVALID_ADDR_SRC: case NET_IF_ERR_INVALID_ETHER_TYPE: case NET_IF_ERR_INVALID_LEN_FRAME: case NET_IF_ERR_INVALID_LLC_DSAP: case NET_IF_ERR_INVALID_LLC_SSAP: case NET_IF_ERR_INVALID_LLC_CTRL: case NET_IF_ERR_INVALID_SNAP_CODE: case NET_IF_ERR_INVALID_SNAP_TYPE: default: NetIF_RxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_Tx() * * Description : (1) Prepare & transmit data packets from network protocol layers to packet-based network * interface layer : * * (a) Prepare data packets with appropriate Ethernet frame format * (b) Transmit packet via : * (1) Broadcast * (2) Bind hardware address * * * Argument(s) : pbuf Pointer to network buffer with data packet to transmit. * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Packet successfully transmitted OR * buffered for later transmission. * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * * - RETURNED BY NetIF_TxPktDiscard() : - * NET_ERR_TX Transmit error; packet discarded. * * Return(s) : none. * * Caller(s) : NetIP_TxPktDatagram(), * NetARP_Tx(). * * Note(s) : (2) NetIF_Tx() blocked until network initialization completes; perform NO action. ********************************************************************************************************* */ void NetIF_Tx (NET_BUF *pbuf, NET_ERR *perr) { #if ((NET_ERR_CFG_ARG_CHK_DBG_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). */ NetIF_TxPktDiscard(pbuf, perr); *perr = NET_ERR_INIT_INCOMPLETE; return; } #endif #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------------- VALIDATE PTR ------------------- */ if (pbuf == (NET_BUF *)0) { NetIF_TxPktDiscard(pbuf, perr); NET_CTR_ERR_INC(NetIF_ErrNullPtrCtr); return; } #endif /* ----------------- VALIDATE IF PKT ------------------ */ pbuf_hdr = &pbuf->Hdr; #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) NetIF_TxPktValidate(pbuf, pbuf_hdr, perr); switch (*perr) { case NET_IF_ERR_NONE: break; case NET_ERR_INVALID_PROTOCOL: case NET_BUF_ERR_INVALID_IX: case NET_IF_ERR_INVALID_LEN_DATA: default: NetIF_TxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } #endif /*$PAGE*/ /* ----------------- PREPARE TX FRAME ----------------- */ NetIF_TxPktPrepareFrame(pbuf, pbuf_hdr, perr); /* Prepare Ethernet frame. */ switch (*perr) { case NET_IF_ERR_TX_BROADCAST: break; case NET_IF_ERR_TX_ARP: NetARP_CacheHandler(pbuf, perr); /* Bind dest hw addr & transmit data pkt. */ break; case NET_ERR_INVALID_PROTOCOL: case NET_BUF_ERR_INVALID_IX: case NET_BUF_ERR_INVALID_LEN: default: NetIF_TxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } /* -------------------- TX IF PKTS -------------------- */ switch (*perr) { /* Chk err from ... */ case NET_IF_ERR_TX_BROADCAST: /* ... NetIF_TxPktPrepareFrame(). */ case NET_ARP_ERR_CACHE_RESOLVED: /* ... NetARP_CacheHandler(). */ NetIF_TxPktHandler(pbuf); *perr = NET_IF_ERR_NONE; break; case NET_ARP_ERR_CACHE_PEND: *perr = NET_IF_ERR_NONE; return; /* Prevent 'break NOT reachable' compiler warning. */ case NET_ARP_ERR_NULL_PTR: case NET_ARP_ERR_CACHE_NONE_AVAIL: case NET_ARP_ERR_CACHE_INVALID_TYPE: case NET_TMR_ERR_NULL_OBJ: case NET_TMR_ERR_NULL_FNCT: case NET_TMR_ERR_NONE_AVAIL: case NET_TMR_ERR_INVALID_TYPE: default: NetIF_TxPktDiscard(pbuf, perr); return; /* Prevent 'break NOT reachable' compiler warning. */ } } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_TxPkt() * * Description : (1) Transmit data packet to packet-based network interface layer : * * (a) Transmit data packet * (b) Update transmit statistics * * * Argument(s) : pbuf Pointer to network buffer with data packet to transmit. * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Packet buffer(s) transmitted to driver. * NET_ERR_TX Transmit error (see Note #2); packet discarded. * * Return(s) : none. * * Caller(s) : NetIF_TxPktHandler(), * NetARP_CacheTxPktHandler(). * * Note(s) : (2) Since the network interface layer & the packet interface layer return the same error * codes, error code(s) do NOT need to be re-cast. * * (3) Network buffer already freed by lower layer; only increment error counter. ********************************************************************************************************* */ void NetIF_TxPkt (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 /* --------------------- TX PKT ----------------------- */ NetIF_Pkt_Tx(pbuf, perr); /* Tx pkt to pkt IF. */ /* ----------------- UPDATE TX STATS ------------------ */ switch (*perr) { /* See Note #2. */ case NET_IF_ERR_NONE: NET_CTR_STAT_INC(NetIF_StatTxPktCtr); break; case NET_ERR_INIT_INCOMPLETE: case NET_ERR_TX: default: NET_CTR_ERR_INC(NetIF_ErrTxPktDiscardedCtr); /* See Note #3. */ *perr = NET_ERR_TX; break; } } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_TxPktDiscard() * * Description : On any transmit handler 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) : NetIF_Tx(), * NetARP_CacheFree(). * * Note(s) : none. ********************************************************************************************************* */ void NetIF_TxPktDiscard (NET_BUF *pbuf, NET_ERR *perr) { NET_CTR *pctr; #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) pctr = (NET_CTR *)&NetIF_ErrTxPktDiscardedCtr; #else pctr = (NET_CTR *) 0; #endif NetBuf_FreeBuf((NET_BUF *)pbuf, (NET_CTR *)pctr); *perr = NET_ERR_TX; } /*$PAGE*/ /* ********************************************************************************************************* ********************************************************************************************************* * LOCAL FUNCTIONS ********************************************************************************************************* ********************************************************************************************************* */ /* ********************************************************************************************************* * NetIF_RxPktValidateBuf() * * Description : Validate received buffer header as IF protocol. * * Argument(s) : pbuf_hdr Pointer to network buffer header that received IF packet. * -------- Argument validated in NetIF_Rx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Received buffer's IF header validated. * NET_ERR_INVALID_PROTOCOL Buffer's protocol type is NOT IF. * NET_BUF_ERR_INVALID_IX Invalid buffer index. * * Return(s) : none. * * Caller(s) : NetIF_Rx(). * * Note(s) : none. ********************************************************************************************************* */ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetIF_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_FRAME) { NET_CTR_ERR_INC(Net_ErrInvalidProtocolCtr); *perr = NET_ERR_INVALID_PROTOCOL; return; } if (pbuf_hdr->IF_HdrIx == NET_BUF_IX_NONE) { NET_CTR_ERR_INC(NetIF_ErrRxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } *perr = NET_IF_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetIF_RxPktFrameDemux() * * Description : (1) Validate received packet frame & demultiplex to appropriate queue : * * (a) Validate destination address : * (1) Check for broadcast address See RFC #1122, Section 2.4 * (2) Check for this host's hardware address * (b) Validate source address See 'NetIF_IsValidAddrSrc() Note #1' * (c) Demultiplex & validate frame : * (1) Ethernet frame type * (2) IEEE 802.3 frame length * (d) Demultiplex packet to appropriate queue : * (1) IP receive queue * (2) ARP receive queue * * * Argument(s) : pbuf Pointer to network buffer that received data packet. * ---- Argument validated in NetIF_Rx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_INVALID_ADDR_DEST Invalid destination address. * NET_IF_ERR_INVALID_ADDR_SRC Invalid source address. * NET_ERR_INVALID_PROTOCOL Invalid network protocol. * * -- RETURNED BY NetIF_RxPktFrameDemuxEther() : -- * NET_IF_ERR_INVALID_ETHER_TYPE Invalid Ethernet Frame Type value. * * - RETURNED BY NetIF_RxPktFrameDemuxIEEE802() : - * NET_IF_ERR_INVALID_LEN_FRAME Invalid IEEE 802.3 frame length. * NET_IF_ERR_INVALID_LLC_DSAP Invalid IEEE 802.2 LLC DSAP value. * NET_IF_ERR_INVALID_LLC_SSAP Invalid IEEE 802.2 LLC SSAP value. * NET_IF_ERR_INVALID_LLC_CTRL Invalid IEEE 802.2 LLC Control value. * NET_IF_ERR_INVALID_SNAP_CODE Invalid IEEE 802.2 SNAP OUI value. * NET_IF_ERR_INVALID_SNAP_TYPE Invalid IEEE 802.2 SNAP Type value. * * ----------- RETURNED BY NetARP_Rx() : ---------- * NET_ARP_ERR_NONE ARP message successfully demultiplexed. * * ----------- RETURNED BY NetIP_Rx() : ----------- * NET_IP_ERR_NONE IP datagram successfully demultiplexed. * * * NET_ERR_INIT_INCOMPLETE Network initialization NOT complete. * NET_ERR_RX Receive error; packet discarded. * * Return(s) : none. * * Caller(s) : NetIF_Rx(). * * Note(s) : (2) When network buffer is demultiplexed to higher-layer protocol receive, the buffer's reference * counter is NOT incremented since the network interface layer does NOT maintain a reference to * the buffer. ********************************************************************************************************* */ /*$PAGE*/ static void NetIF_RxPktFrameDemux (NET_BUF *pbuf, NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_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 #if (NET_IF_CFG_ADDR_FLTR_EN == DEF_ENABLED) CPU_BOOLEAN dest_this_host; CPU_BOOLEAN valid; #endif CPU_BOOLEAN dest_broadcast; CPU_INT16U frame_type_len; /* ---------------- VALIDATE DEST ADDR ---------------- */ dest_broadcast = Mem_Cmp((void *)&pif_hdr->AddrDest[0], (void *)&NetIF_AddrBroadcast[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); if (dest_broadcast == DEF_YES) { NET_CTR_STAT_INC(NetIF_StatRxPktBroadcastCtr); DEF_BIT_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_RX);/* Flag rx'd broadcast pkt (see Note #1a1). */ } else { #if (NET_IF_CFG_ADDR_FLTR_EN == DEF_ENABLED) dest_this_host = Mem_Cmp((void *)&pif_hdr->AddrDest[0], (void *)&NetIF_MAC_Addr[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); if (dest_this_host != DEF_YES) { /* Discard invalid dest addr (see Note #1a2). */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidAddrDestCtr); *perr = NET_IF_ERR_INVALID_ADDR_DEST; return; } #endif } #if (NET_IF_CFG_ADDR_FLTR_EN == DEF_ENABLED) /* ---------------- VALIDATE SRC ADDR ---------------- */ valid = NetIF_IsValidAddrSrc(&pif_hdr->AddrSrc[0]); if (valid != DEF_YES) { /* Discard invalid src addr (see Note #1b). */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidAddrSrcCtr); *perr = NET_IF_ERR_INVALID_ADDR_SRC; return; } #endif /*$PAGE*/ /* --------------- DEMUX/VALIDATE FRAME --------------- */ frame_type_len = NET_UTIL_VAL_GET_NET_16(&pif_hdr->FrameType_Len); if (frame_type_len <= NET_IF_IEEE_802_FRAME_LEN_MAX) { NetIF_RxPktFrameDemuxIEEE802(pbuf_hdr, pif_hdr, perr); } else { NetIF_RxPktFrameDemuxEther(pbuf_hdr, pif_hdr, perr); } /* -------------------- DEMUX PKT --------------------- */ switch (*perr) { /* See Note #2. */ case NET_IF_ERR_NONE: switch (pbuf_hdr->ProtocolHdrType) { /* Demux buf to appropriate protocol Q. */ case NET_PROTOCOL_TYPE_ARP: NetARP_Rx(pbuf, perr); break; case NET_PROTOCOL_TYPE_IP: NetIP_Rx(pbuf, perr); break; case NET_PROTOCOL_TYPE_NONE: default: NET_CTR_ERR_INC(NetIF_ErrInvalidProtocolCtr); *perr = NET_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } break; case NET_IF_ERR_INVALID_ETHER_TYPE: case NET_IF_ERR_INVALID_LEN_FRAME: case NET_IF_ERR_INVALID_LLC_DSAP: case NET_IF_ERR_INVALID_LLC_SSAP: case NET_IF_ERR_INVALID_LLC_CTRL: case NET_IF_ERR_INVALID_SNAP_CODE: case NET_IF_ERR_INVALID_SNAP_TYPE: default: return; /* Prevent 'break NOT reachable' compiler warning. */ } } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_RxPktFrameDemuxEther() * * Description : (1) Validate & demultiplex Ethernet packet frame : * * (a) Validate & demultiplex Ethernet packet frame * (b) Update buffer controls * * * Argument(s) : pbuf_hdr Pointer to received packet frame's network buffer header. * -------- Argument validated in NetIF_RxPktFrameDemux(). * * pif_hdr Pointer to packet frame header. * ------- Argument validated in NetIF_RxPktFrameDemux(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Valid Ethernet packet frame. * NET_IF_ERR_INVALID_ETHER_TYPE Invalid Ethernet Frame Type value. * * Return(s) : none. * * Caller(s) : NetIF_RxPktFrameDemux(). * * Note(s) : none. ********************************************************************************************************* */ static void NetIF_RxPktFrameDemuxEther (NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_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 NET_IF_HDR_ETHER *pif_hdr_ether; CPU_INT16U frame_type; CPU_INT16U ix; pif_hdr_ether = (NET_IF_HDR_ETHER *)pif_hdr; /* --------------- VALIDATE/DEMUX FRAME --------------- */ frame_type = NET_UTIL_VAL_GET_NET_16(&pif_hdr_ether->FrameType); ix = NET_IF_RX_IX + NET_IF_FRAME_HDR_SIZE_ETHER; switch (frame_type) { /* Validate & demux Ethernet frame type. */ case NET_IF_FRAME_ETHER_TYPE_IP: pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_IP; pbuf_hdr->IP_HdrIx = (NET_BUF_SIZE)ix; break; case NET_IF_FRAME_ETHER_TYPE_ARP: pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_ARP; pbuf_hdr->ARP_MsgIx = (NET_BUF_SIZE)ix; break; default: NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_ETHER_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } /* ----------------- UPDATE BUF CTRLS ----------------- */ pbuf_hdr->IF_HdrLen = NET_IF_FRAME_HDR_SIZE_ETHER; pbuf_hdr->DataLen -= (NET_BUF_SIZE)pbuf_hdr->IF_HdrLen; if (pbuf_hdr->IF_HdrLen <= NET_IF_FRAME_MIN_SIZE) { pbuf_hdr->IF_DataLenMin = NET_IF_FRAME_MIN_SIZE - pbuf_hdr->IF_HdrLen; } else { pbuf_hdr->IF_DataLenMin = 0; } *perr = NET_IF_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_RxPktFrameDemuxIEEE802() * * Description : (1) Validate & demultiplex IEEE 802 packet frame : * * (a) Validate & demultiplex IEEE 802 packet frame * (1) IEEE 802.2 LLC * (2) IEEE 802.2 SNAP Organization Code * (3) IEEE 802.2 SNAP Frame Type * (b) Update buffer controls * * * Argument(s) : pbuf_hdr Pointer to received packet frame's network buffer header. * -------- Argument validated in NetIF_RxPktFrameDemux(). * * pif_hdr Pointer to packet frame header. * ------- Argument validated in NetIF_RxPktFrameDemux(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Valid IEEE 802 packet frame. * NET_IF_ERR_INVALID_LEN_FRAME Invalid IEEE 802.3 frame length. * NET_IF_ERR_INVALID_LLC_DSAP Invalid IEEE 802.2 LLC DSAP value. * NET_IF_ERR_INVALID_LLC_SSAP Invalid IEEE 802.2 LLC SSAP value. * NET_IF_ERR_INVALID_LLC_CTRL Invalid IEEE 802.2 LLC Control value. * NET_IF_ERR_INVALID_SNAP_CODE Invalid IEEE 802.2 SNAP OUI value. * NET_IF_ERR_INVALID_SNAP_TYPE Invalid IEEE 802.2 SNAP Type value. * * Return(s) : none. * * Caller(s) : NetIF_RxPktFrameDemux(). * * Note(s) : (2) The IEEE 802.3 Frame Length field specifies the number of frame data octets & does NOT * include the trailing frame CRC field octets. However, since some NICs MAY append the * CRC field as part of a received packet frame, any validation of the minimum frame size * MUST assume that the CRC field may be present. Therefore, the minimum frame packet size * for comparison MUST include the number of CRC field octets. ********************************************************************************************************* */ static void NetIF_RxPktFrameDemuxIEEE802 (NET_BUF_HDR *pbuf_hdr, NET_IF_HDR *pif_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 NET_IF_HDR_IEEE_802 *pif_hdr_ieee_802; CPU_INT16U frame_len; CPU_INT16U frame_len_actual; CPU_INT16U frame_type; CPU_INT16U ix; /*$PAGE*/ pif_hdr_ieee_802 = (NET_IF_HDR_IEEE_802 *)pif_hdr; /* ------------- VALIDATE FRAME SIZE -------------- */ if (pbuf_hdr->TotLen >= NET_IF_FRAME_MIN_CRC_SIZE) { /* If pkt size >= min frame pkt size (see Note #2) */ frame_len = NET_UTIL_VAL_GET_NET_16(&pif_hdr_ieee_802->FrameLen); frame_len_actual = (CPU_INT16U)(pbuf_hdr->TotLen - NET_IF_FRAME_HDR_SIZE - NET_IF_FRAME_CRC_SIZE); if (frame_len != frame_len_actual) { /* ... & frame len != rem pkt len, rtn err. */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_LEN_FRAME; return; } } /* ------------ VALIDATE IEEE 802.2 LLC ----------- */ if (pif_hdr_ieee_802->LLC_DSAP != NET_IF_IEEE_802_LLC_DSAP) { /* Validate IEEE 802.2 LLC DSAP. */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_LLC_DSAP; return; } if (pif_hdr_ieee_802->LLC_SSAP != NET_IF_IEEE_802_LLC_SSAP) { /* Validate IEEE 802.2 LLC SSAP. */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_LLC_SSAP; return; } if (pif_hdr_ieee_802->LLC_Ctrl != NET_IF_IEEE_802_LLC_CTRL) { /* Validate IEEE 802.2 LLC Ctrl. */ NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_LLC_CTRL; return; } /* ----------- VALIDATE IEEE 802.2 SNAP ----------- */ /* Validate IEEE 802.2 SNAP OUI. */ if (pif_hdr_ieee_802->SNAP_OrgCode[0] != NET_IF_IEEE_802_SNAP_CODE_00) { NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_SNAP_CODE; return; } if (pif_hdr_ieee_802->SNAP_OrgCode[1] != NET_IF_IEEE_802_SNAP_CODE_01) { NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_SNAP_CODE; return; } if (pif_hdr_ieee_802->SNAP_OrgCode[2] != NET_IF_IEEE_802_SNAP_CODE_02) { NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_SNAP_CODE; return; } frame_type = NET_UTIL_VAL_GET_NET_16(&pif_hdr_ieee_802->SNAP_FrameType); ix = NET_IF_RX_IX + NET_IF_FRAME_HDR_SIZE_IEEE_802; switch (frame_type) { /* Validate & demux IEEE 802.2 SNAP Frame Type. */ case NET_IF_IEEE_802_SNAP_TYPE_IP: pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_IP; pbuf_hdr->IP_HdrIx = (NET_BUF_SIZE)ix; break; case NET_IF_IEEE_802_SNAP_TYPE_ARP: pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_ARP; pbuf_hdr->ARP_MsgIx = (NET_BUF_SIZE)ix; break; default: NET_CTR_ERR_INC(NetIF_ErrRxInvalidFrameCtr); *perr = NET_IF_ERR_INVALID_SNAP_TYPE; return; /* Prevent 'break NOT reachable' compiler warning. */ } /* --------------- UPDATE BUF CTRLS --------------- */ pbuf_hdr->IF_HdrLen = NET_IF_FRAME_HDR_SIZE_IEEE_802; pbuf_hdr->DataLen -= (NET_BUF_SIZE)pbuf_hdr->IF_HdrLen; if (pbuf_hdr->IF_HdrLen <= NET_IF_FRAME_MIN_SIZE) { pbuf_hdr->IF_DataLenMin = NET_IF_FRAME_MIN_SIZE - pbuf_hdr->IF_HdrLen; } else { pbuf_hdr->IF_DataLenMin = 0; } *perr = NET_IF_ERR_NONE; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_RxPktDiscard() * * Description : On any Network Interface Receive 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_RX Receive error; packet discarded. * * Return(s) : none. * * Caller(s) : NetIF_Rx(). * * Note(s) : none. ********************************************************************************************************* */ static void NetIF_RxPktDiscard (NET_BUF *pbuf, NET_ERR *perr) { NET_CTR *pctr; #if (NET_CTR_CFG_ERR_EN == DEF_ENABLED) pctr = (NET_CTR *)&NetIF_ErrRxPktDiscardedCtr; #else pctr = (NET_CTR *) 0; #endif NetBuf_FreeBuf((NET_BUF *)pbuf, (NET_CTR *)pctr); *perr = NET_ERR_RX; } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_TxPktHandler() * * Description : Transmit data packets via network interface layer. * * Argument(s) : pbuf_q Pointer to network buffer list with data packet(s) to transmit. * * Return(s) : none. * * Caller(s) : NetIF_Tx(), * NetARP_RxPktCacheUpdate(). * * Note(s) : none. ********************************************************************************************************* */ static void NetIF_TxPktHandler (NET_BUF *pbuf_q) { NET_BUF *pbuf_list; NET_BUF *pbuf_list_next; NET_BUF *pbuf; NET_BUF *pbuf_next; NET_BUF_HDR *pbuf_hdr; NET_ERR err; pbuf_list = pbuf_q; while (pbuf_list != (NET_BUF *)0) { /* Tx ALL buf lists in Q. */ pbuf_hdr = &pbuf_list->Hdr; pbuf_list_next = (NET_BUF *)pbuf_hdr->NextSecListPtr; pbuf = (NET_BUF *)pbuf_list; while (pbuf != (NET_BUF *)0) { /* Tx ALL bufs in buf list. */ pbuf_hdr = &pbuf->Hdr; pbuf_next = (NET_BUF *)pbuf_hdr->NextBufPtr; NetIF_TxPkt(pbuf, &err); /* Tx pkt to IF. */ pbuf = pbuf_next; } pbuf_list = pbuf_list_next; } } /*$PAGE*/ /* ********************************************************************************************************* * NetIF_TxPktValidate() * * Description : (1) Validate IF transmit packet parameters : * * (a) Packets with the following invalid parameters will be "silently discarded" : * * (1) Protocols other than supported protocols : * (A) ARP * (B) IP * * (2) Total Length * * * Argument(s) : pbuf Pointer to network buffer to transmit IF packet. * ---- Argument checked in NetIF_Tx(). * * pbuf_hdr Pointer to network buffer header. * -------- Argument validated in NetIF_Tx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_NONE Transmit packet validated. * NET_ERR_INVALID_PROTOCOL Invalid/unknown protocol type. * NET_BUF_ERR_INVALID_IX Invalid or insufficient buffer index. * NET_IF_ERR_INVALID_LEN_DATA Invalid protocol/data length. * * Return(s) : none. * * Caller(s) : NetIF_Tx(). * * Note(s) : none. ********************************************************************************************************* */ /*$PAGE*/ #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) static void NetIF_TxPktValidate (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 CPU_INT16U ix; CPU_INT16U len; /* ----------------- VALIDATE PROTOCOL ---------------- */ switch (pbuf_hdr->ProtocolHdrType) { case NET_PROTOCOL_TYPE_ARP: ix = pbuf_hdr->ARP_MsgIx; len = pbuf_hdr->ARP_MsgLen; break; case NET_PROTOCOL_TYPE_IP: ix = pbuf_hdr->IP_HdrIx; len = pbuf_hdr->IP_TotLen; break; case NET_PROTOCOL_TYPE_NONE: default: NET_CTR_ERR_INC(NetIF_ErrTxProtocolCtr); *perr = NET_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } if (ix == NET_BUF_IX_NONE) { NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } if (ix < NET_IF_HDR_SIZE_MAX) { NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } /* -------------- VALIDATE TOT DATA LEN --------------- */ if (len != pbuf_hdr->TotLen) { NET_CTR_ERR_INC(NetIF_ErrTxHdrDataLenCtr); *perr = NET_IF_ERR_INVALID_LEN_DATA; return; } *perr = NET_IF_ERR_NONE; } #endif /*$PAGE*/ /* ********************************************************************************************************* * NetIF_TxPktPrepareFrame() * * Description : (1) Prepare data packet with Ethernet frame format : * * (a) Demultiplex Ethernet frame type * (b) Update buffer controls * (c) Write Ethernet values into packet frame * (1) Ethernet destination broadcast address, if necessary * (2) Ethernet source MAC address * (3) Ethernet frame type * (d) Clear Ethernet frame pad octets, if any * * * Argument(s) : pbuf Pointer to network buffer with data packet to encapsulate. * ---- Argument checked in NetIF_Tx(). * * pbuf_hdr Pointer to network buffer header. * -------- Argument validated in NetIF_Tx(). * * perr Pointer to variable that will receive the return error code from this function : * * NET_IF_ERR_TX_BROADCAST Ethernet frame successfully prepared for * Ethernet broadcast on local network. * NET_IF_ERR_TX_ARP Ethernet frame successfully prepared & * requires ARP hardware address binding. * NET_ERR_INVALID_PROTOCOL Invalid network protocol. * NET_BUF_ERR_INVALID_IX Invalid or insufficient buffer index. * NET_BUF_ERR_INVALID_LEN Insufficient buffer length. * * Return(s) : none. * * Caller(s) : NetIF_Tx(). * * Note(s) : (2) Supports ONLY Ethernet frame format for network transmit (see 'net_if.c Note #2a'). * * (3) Supports ONLY ARP & IP protocols (see 'net.h Note #1a'). * * (4) To prepare the packet buffer for ARP resolution, the buffer's ARP protocol address * pointer needs to be configured to the appropriate outbound address : * * (a) For ARP packets, the ARP layer will configure the ARP protocol address pointer * (see 'net_arp.c NetARP_TxPktPrepareHdr() Note #1d'). * * (b) For IP packets, configure the ARP protocol address pointer to the IP's next- * hop address. * * (5) RFC #894, Section 'Frame Format' states : * * (a) "The minimum length of the data field of a packet sent over an Ethernet is 46 * octets." * * (b) (1) "If necessary, the data field should be padded (with octets of zero) to * meet the Ethernet minimum frame size." * (2) "This padding is not part of the IP packet and is not included in the * total length field of the IP header." ********************************************************************************************************* */ static void NetIF_TxPktPrepareFrame (NET_BUF *pbuf, 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_IF_HDR_ETHER *pif_hdr_ether; CPU_INT16U protocol_ix; CPU_INT16U frame_type; CPU_INT16U clr_ix; CPU_INT16U clr_len; CPU_INT16U clr_size; CPU_BOOLEAN clr_buf_mem; CPU_BOOLEAN tx_broadcast; /*$PAGE*/ /* ----------------- DEMUX FRAME TYPE ----------------- */ switch (pbuf_hdr->ProtocolHdrType) { /* Demux protocol for frame type (see Note #3). */ case NET_PROTOCOL_TYPE_ARP: protocol_ix = pbuf_hdr->ARP_MsgIx; frame_type = NET_IF_FRAME_ETHER_TYPE_ARP; break; case NET_PROTOCOL_TYPE_IP: protocol_ix = pbuf_hdr->IP_HdrIx; frame_type = NET_IF_FRAME_ETHER_TYPE_IP; /* Cfg ARP addr ptr (see Note #4b). */ pbuf_hdr->ARP_AddrProtocolPtr = (CPU_INT08U *)&pbuf_hdr->IP_AddrNextHopNetOrder; break; case NET_PROTOCOL_TYPE_NONE: default: NET_CTR_ERR_INC(NetIF_ErrInvalidProtocolCtr); *perr = NET_ERR_INVALID_PROTOCOL; return; /* Prevent 'break NOT reachable' compiler warning. */ } #if (NET_ERR_CFG_ARG_CHK_DBG_EN == DEF_ENABLED) /* ------------- VALIDATE IX -------------- */ if (protocol_ix == NET_BUF_IX_NONE) { NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } if (protocol_ix < NET_IF_HDR_SIZE_MAX) { NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufIxCtr); *perr = NET_BUF_ERR_INVALID_IX; return; } #endif /* ----------- UPDATE BUF CTRLS ----------- */ pbuf_hdr->IF_HdrLen = NET_IF_FRAME_HDR_SIZE_ETHER; pbuf_hdr->IF_HdrIx = protocol_ix - pbuf_hdr->IF_HdrLen; pbuf_hdr->TotLen += (NET_BUF_SIZE) pbuf_hdr->IF_HdrLen; pbuf_hdr->ProtocolHdrType = NET_PROTOCOL_TYPE_FRAME; /* --------- PREPARE ETHER FRAME ---------- */ pif_hdr_ether = (NET_IF_HDR_ETHER *)&pbuf->Data[pbuf_hdr->IF_HdrIx]; /* --------- PREPARE FRAME ADDRS ---------- */ tx_broadcast = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_BROADCAST_TX); if (tx_broadcast == DEF_YES) { /* If dest addr broadcast, ... */ Mem_Copy((void *)&pif_hdr_ether->AddrDest[0], /* .. wr broadcast addr into frame. */ (void *)&NetIF_AddrBroadcast[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); NET_CTR_STAT_INC(NetIF_StatTxPktBroadcastCtr); *perr = NET_IF_ERR_TX_BROADCAST; } else { /* Else req ARP hw addr binding. */ pbuf_hdr->ARP_AddrHW_Ptr = (void *)&pif_hdr_ether->AddrDest[0]; *perr = NET_IF_ERR_TX_ARP; } Mem_Copy((void *)&pif_hdr_ether->AddrSrc[0], /* Wr src addr into frame. */ (void *)&NetIF_MAC_Addr[0], (CPU_SIZE_T) NET_IF_ADDR_SIZE); /* ---------- PREPARE FRAME TYPE ---------- */ NET_UTIL_VAL_COPY_SET_NET_16(&pif_hdr_ether->FrameType, &frame_type); /* --------- CLR/PAD FRAME OCTETS --------- */ if (pbuf_hdr->TotLen < NET_IF_FRAME_MIN_SIZE) { /* If tot len < min frame len (see Note #5a)*/ clr_buf_mem = DEF_BIT_IS_SET(pbuf_hdr->Flags, NET_BUF_FLAG_CLR_MEM); if (clr_buf_mem != DEF_YES) { /* ... & buf mem NOT clr, ... */ clr_ix = pbuf_hdr->IF_HdrIx + (CPU_INT16U)pbuf_hdr->TotLen; clr_len = NET_IF_FRAME_MIN_SIZE - (CPU_INT16U)pbuf_hdr->TotLen; clr_size = clr_ix + clr_len; if (clr_size > pbuf_hdr->Size) { NET_CTR_ERR_INC(NetIF_ErrTxInvalidBufLenCtr); *perr = NET_BUF_ERR_INVALID_LEN; return; } Mem_Clr((void *)&pbuf->Data[clr_ix], /* ... clr rem'ing octets (see Note #5b1). */ (CPU_SIZE_T) clr_len); } pbuf_hdr->TotLen = NET_IF_FRAME_MIN_SIZE; /* Update tot frame len. */ } } /*$PAGE*/ /* ********************************************************************************************************* ********************************************************************************************************* * LAYER INTERFACE FUNCTIONS ********************************************************************************************************* ********************************************************************************************************* */ /* ********************************************************************************************************* * NetARP_GetHostAddrPtrHW() * * Description : Get pointer to this host's network interface hardware address. * * Argument(s) : none. * * Return(s) : Pointer to network interface hardware address. * * Caller(s) : NetARP_Init(). * * Note(s) : (1) ARP hardware address MUST be in network-order (see 'net_arp.c NetARP_CacheHandler() * Note #2e3'). ********************************************************************************************************* */ CPU_INT08U *NetARP_GetHostAddrPtrHW (void) { CPU_INT08U *paddr; paddr = (CPU_INT08U *)&NetIF_MAC_Addr[0]; return (paddr); } /*$PAGE*/ /* ********************************************************************************************************* * NetARP_IsValidAddrHW() * * Description : Validate an ARP hardware address. * * Argument(s) : paddr_hw Pointer to an ARP hardware address. * -------- Argument validated in NetARP_RxPktValidate(). * * Return(s) : DEF_YES, if hardware address valid. * * DEF_NO, otherwise. * * Caller(s) : NetARP_RxPktValidate(). * * Note(s) : none. ********************************************************************************************************* */ CPU_BOOLEAN NetARP_IsValidAddrHW (CPU_INT08U *paddr_hw) { CPU_BOOLEAN valid; valid = NetIF_IsValidAddrSrc(paddr_hw); return (valid); }