diff options
author | Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> | 2020-07-29 13:56:57 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-29 13:56:57 -0700 |
commit | ae4d4d38d9b2685bae159b4c87619cdb157c0bf7 (patch) | |
tree | b9430444c5b96fc0dc9f5c58ef649d6abd83234e | |
parent | a457f43c66eb0f4be9d8f8678c0e3fb8d7ebd57b (diff) | |
download | freertos-git-ae4d4d38d9b2685bae159b4c87619cdb157c0bf7.tar.gz |
MISRA compliance changes for FreeRTOS_TCP_IP.c (#160)
* MISRA tcp-ip changes
* Changes after Hein's comments on original PR
* Update FreeRTOS_TCP_IP.c
Co-authored-by: Yuhui Zheng <10982575+yuhui-zheng@users.noreply.github.com>
-rw-r--r-- | FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c | 587 | ||||
-rw-r--r-- | FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h | 1 |
2 files changed, 321 insertions, 267 deletions
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c index b2aa187e8..754c26a7f 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c @@ -703,7 +703,7 @@ BaseType_t xDoRelease = xReleaseAfterSend; EthernetHeader_t *pxEthernetHeader; uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize; const TCPWindow_t *pxTCPWindow; -NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor; /* To avoid error: "function parameter modified [MISRA 2012 Rule 17.8, advisory]" */ +NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor; NetworkBufferDescriptor_t xTempBuffer; /* For sending, a pseudo network buffer will be used, as explained above. */ @@ -713,11 +713,11 @@ NetworkBufferDescriptor_t xTempBuffer; #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 ) { - xTempBuffer.pxNextBuffer = NULL; + pxNetworkBuffer->pxNextBuffer = NULL; } #endif - xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket; - xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ); + pxNetworkBuffer->pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket; + pxNetworkBuffer->xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ); xDoRelease = pdFALSE; } @@ -739,6 +739,7 @@ NetworkBufferDescriptor_t xTempBuffer; if( pxNetworkBuffer != NULL ) #endif { + /* Map the ethernet buffer onto a TCPPacket_t struct for easy access to the fields. */ pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer ); pxIPHeader = &pxTCPPacket->xIPHeader; pxEthernetHeader = &pxTCPPacket->xEthernetHeader; @@ -1045,7 +1046,8 @@ uint32_t ulInitialSequenceNumber = 0; uint16_t usLength; /* The MAC-address of the peer (or gateway) has been found, - now prepare the initial TCP packet and some fields in the socket. */ + * now prepare the initial TCP packet and some fields in the socket. Map + * the buffer onto the TCPPacket_t struct to easily access it's field. */ pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxSocket->u.xTCP.xPacket.u.ucLastPacket ); pxIPHeader = &pxTCPPacket->xIPHeader; @@ -1159,43 +1161,47 @@ uint8_t ucLength; if( pxTCPHeader->ucTCPOffset <= ( 5U << 4U ) ) { /* Avoid integer underflow in computation of ucLength. */ - return; } - ucLength = ( ( ( pxTCPHeader->ucTCPOffset >> 4U ) - 5U ) << 2U ); - uxOptionsLength = ( size_t ) ucLength; - if( pxNetworkBuffer->xDataLength > uxOptionOffset ) + else { - /* Validate options size calculation. */ - if( ( pxNetworkBuffer->xDataLength > uxOptionOffset ) && - ( uxOptionsLength <= ( pxNetworkBuffer->xDataLength - uxOptionOffset ) ) ) + ucLength = ( ( ( pxTCPHeader->ucTCPOffset >> 4U ) - 5U ) << 2U ); + uxOptionsLength = ( size_t ) ucLength; + if( pxNetworkBuffer->xDataLength > uxOptionOffset ) { - if( ( pxTCPHeader->ucTCPFlags & tcpTCP_FLAG_SYN ) != ( uint8_t ) 0U ) - { - xHasSYNFlag = pdTRUE; - } - else - { - xHasSYNFlag = pdFALSE; - } - /* The length check is only necessary in case the option data are - corrupted, we don't like to run into invalid memory and crash. */ - for( ;; ) + /* Validate options size calculation. */ + if( ( pxNetworkBuffer->xDataLength > uxOptionOffset ) && + ( uxOptionsLength <= ( pxNetworkBuffer->xDataLength - uxOptionOffset ) ) ) { - if( uxOptionsLength == 0U ) + if( ( pxTCPHeader->ucTCPFlags & tcpTCP_FLAG_SYN ) != ( uint8_t ) 0U ) { - /* coverity[break_stmt] : Break statement terminating the loop */ - break; + xHasSYNFlag = pdTRUE; } - uxResult = prvSingleStepTCPHeaderOptions( pucPtr, uxOptionsLength, pxSocket, xHasSYNFlag ); - if( uxResult == 0UL ) + else { - break; + xHasSYNFlag = pdFALSE; + } + /* The length check is only necessary in case the option data are + corrupted, we don't like to run into invalid memory and crash. */ + for( ;; ) + { + if( uxOptionsLength == 0U ) + { + /* coverity[break_stmt] : Break statement terminating the loop */ + break; + } + uxResult = prvSingleStepTCPHeaderOptions( pucPtr, uxOptionsLength, pxSocket, xHasSYNFlag ); + if( uxResult == 0UL ) + { + break; + } + uxOptionsLength -= uxResult; + pucPtr = &( pucPtr[ uxResult ] ); } - uxOptionsLength -= uxResult; - pucPtr = &( pucPtr[ uxResult ] ); } } } + + return; } /*-----------------------------------------------------------*/ @@ -1207,25 +1213,25 @@ static size_t prvSingleStepTCPHeaderOptions( const uint8_t * const pucPtr, UBaseType_t uxNewMSS; size_t uxRemainingOptionsBytes = uxTotalLength; uint8_t ucLen; -size_t uxIndex = 0U; +size_t uxIndex; TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); +BaseType_t xReturn = pdFALSE; if( pucPtr[ 0U ] == tcpTCP_OPT_END ) { /* End of options. */ - return 0U; + uxIndex = 0U; } - if( pucPtr[ 0U ] == tcpTCP_OPT_NOOP ) + else if( pucPtr[ 0U ] == tcpTCP_OPT_NOOP ) { /* NOP option, inserted to make the length a multiple of 4. */ - return 1U; + uxIndex = 1U; } - - /* Any other well-formed option must be at least two bytes: the option - type byte followed by a length byte. */ - if( uxRemainingOptionsBytes < 2U ) + else if( uxRemainingOptionsBytes < 2U ) { - return 0U; + /* Any other well-formed option must be at least two bytes: the option + type byte followed by a length byte. */ + uxIndex = 0U; } #if( ipconfigUSE_TCP_WIN != 0 ) else if( pucPtr[ 0 ] == tcpTCP_OPT_WSOPT ) @@ -1234,15 +1240,18 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); /* Confirm that the option fits in the remaining buffer space. */ if( ( uxRemainingOptionsBytes < tcpTCP_OPT_WSOPT_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_WSOPT_LEN ) ) { - return 0U; + uxIndex = 0U; } - /* Option is only valid in SYN phase. */ - if( xHasSYNFlag != 0 ) + else { - pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ]; - pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED; + /* Option is only valid in SYN phase. */ + if( xHasSYNFlag != 0 ) + { + pxSocket->u.xTCP.ucPeerWinScaleFactor = pucPtr[ 2 ]; + pxSocket->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED; + } + uxIndex = tcpTCP_OPT_WSOPT_LEN; } - uxIndex = tcpTCP_OPT_WSOPT_LEN; } #endif /* ipconfigUSE_TCP_WIN */ else if( pucPtr[ 0 ] == tcpTCP_OPT_MSS ) @@ -1250,44 +1259,55 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); /* Confirm that the option fits in the remaining buffer space. */ if( ( uxRemainingOptionsBytes < tcpTCP_OPT_MSS_LEN ) || ( pucPtr[ 1 ] != tcpTCP_OPT_MSS_LEN ) ) { - return 0U; + uxIndex = 0U; } - - /* An MSS option with the correct option length. FreeRTOS_htons() - is not needed here because usChar2u16() already returns a host - endian number. */ - uxNewMSS = usChar2u16( &( pucPtr[ 2 ] ) ); - - if( pxSocket->u.xTCP.usInitMSS != uxNewMSS ) + else { - /* Perform a basic check on the the new MSS. */ - if( uxNewMSS == 0U ) + /* An MSS option with the correct option length. FreeRTOS_htons() + is not needed here because usChar2u16() already returns a host + endian number. */ + uxNewMSS = usChar2u16( &( pucPtr[ 2 ] ) ); + + if( pxSocket->u.xTCP.usInitMSS != uxNewMSS ) { - return 0U; - } + /* Perform a basic check on the the new MSS. */ + if( uxNewMSS == 0U ) + { + uxIndex = 0U; - FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) ); - } + /* Return Condition found. */ + xReturn = pdTRUE; + } + else + { + FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", pxSocket->u.xTCP.usInitMSS, uxNewMSS ) ); + } + } - if( pxSocket->u.xTCP.usInitMSS > uxNewMSS ) - { - /* our MSS was bigger than the MSS of the other party: adapt it. */ - pxSocket->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED; - if( pxSocket->u.xTCP.usCurMSS > uxNewMSS ) + /* If a 'return' condition has not been found. */ + if( xReturn == pdFALSE ) { - /* The peer advertises a smaller MSS than this socket was - using. Use that as well. */ - FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", pxSocket->u.xTCP.usCurMSS, uxNewMSS ) ); - pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS; + if( pxSocket->u.xTCP.usInitMSS > uxNewMSS ) + { + /* our MSS was bigger than the MSS of the other party: adapt it. */ + pxSocket->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED; + if( pxSocket->u.xTCP.usCurMSS > uxNewMSS ) + { + /* The peer advertises a smaller MSS than this socket was + using. Use that as well. */ + FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", pxSocket->u.xTCP.usCurMSS, uxNewMSS ) ); + pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS; + } + pxTCPWindow->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( pxTCPWindow->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) ); + pxTCPWindow->usMSSInit = ( uint16_t ) uxNewMSS; + pxTCPWindow->usMSS = ( uint16_t ) uxNewMSS; + pxSocket->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS; + pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS; + } + + uxIndex = tcpTCP_OPT_MSS_LEN; } - pxTCPWindow->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( pxTCPWindow->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) ); - pxTCPWindow->usMSSInit = ( uint16_t ) uxNewMSS; - pxTCPWindow->usMSS = ( uint16_t ) uxNewMSS; - pxSocket->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS; - pxSocket->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS; } - - uxIndex = tcpTCP_OPT_MSS_LEN; } else { @@ -1299,32 +1319,36 @@ TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); /* If the length field is too small or too big, the options are * malformed, don't process them further. */ - return 0U; + uxIndex = 0U; } - - #if( ipconfigUSE_TCP_WIN == 1 ) + else { - /* Selective ACK: the peer has received a packet but it is missing - * earlier packets. At least this packet does not need retransmission - * anymore. ulTCPWindowTxSack( ) takes care of this administration. - */ - if( pucPtr[ 0U ] == tcpTCP_OPT_SACK_A ) + uxIndex = 0U; + + #if( ipconfigUSE_TCP_WIN == 1 ) { - ucLen -= 2U; - uxIndex += 2U; - - while( ucLen >= ( uint8_t ) 8U ) + /* Selective ACK: the peer has received a packet but it is missing + * earlier packets. At least this packet does not need retransmission + * anymore. ulTCPWindowTxSack( ) takes care of this administration. + */ + if( pucPtr[ 0U ] == tcpTCP_OPT_SACK_A ) { - prvReadSackOption( pucPtr, uxIndex, pxSocket ); - uxIndex += 8U; - ucLen -= 8U; + ucLen -= 2U; + uxIndex += 2U; + + while( ucLen >= ( uint8_t ) 8U ) + { + prvReadSackOption( pucPtr, uxIndex, pxSocket ); + uxIndex += 8U; + ucLen -= 8U; + } + /* ucLen should be 0 by now. */ } - /* ucLen should be 0 by now. */ } - } - #endif /* ipconfigUSE_TCP_WIN == 1 */ + #endif /* ipconfigUSE_TCP_WIN == 1 */ - uxIndex += ( size_t ) ucLen; + uxIndex += ( size_t ) ucLen; + } } return uxIndex; } @@ -1660,14 +1684,14 @@ static NetworkBufferDescriptor_t *prvTCPBufferResize( const FreeRTOS_Socket_t *p int32_t lDataLen, UBaseType_t uxOptionsLength ) { NetworkBufferDescriptor_t *pxReturn; -int32_t lNeeded; +size_t uxNeeded; BaseType_t xResize; if( xBufferAllocFixedSize != pdFALSE ) { /* Network buffers are created with a fixed size and can hold the largest MTU. */ - lNeeded = ( int32_t ) ipTOTAL_ETHERNET_FRAME_SIZE; + uxNeeded = ( size_t ) ipTOTAL_ETHERNET_FRAME_SIZE; /* and therefore, the buffer won't be too small. Only ask for a new network buffer in case none was supplied. */ if( pxNetworkBuffer == NULL ) @@ -1683,11 +1707,16 @@ BaseType_t xResize; { /* Network buffers are created with a variable size. See if it must grow. */ - lNeeded = FreeRTOS_max_int32( ( int32_t ) sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ), - ipNUMERIC_CAST( int32_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen ); + uxNeeded = ipNUMERIC_CAST( size_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen; + + if( uxNeeded < sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) ) + { + uxNeeded = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ); + } + /* In case we were called from a TCP timer event, a buffer must be created. Otherwise, test 'xDataLength' of the provided buffer. */ - if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded ) ) + if( ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < uxNeeded ) ) { xResize = pdTRUE; } @@ -1702,12 +1731,12 @@ BaseType_t xResize; /* The caller didn't provide a network buffer or the provided buffer is too small. As we must send-out a data packet, a buffer will be created here. */ - pxReturn = pxGetNetworkBufferWithDescriptor( ( uint32_t ) lNeeded, 0U ); + pxReturn = pxGetNetworkBufferWithDescriptor( uxNeeded, 0U ); if( pxReturn != NULL ) { /* Set the actual packet size, in case the returned buffer is larger. */ - pxReturn->xDataLength = ( size_t ) lNeeded; + pxReturn->xDataLength = uxNeeded; /* Copy the existing data to the new created buffer. */ if( pxNetworkBuffer != NULL ) @@ -1765,6 +1794,7 @@ int32_t lStreamPos; pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket; } + /* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow ); lDataLen = 0; @@ -1792,6 +1822,9 @@ int32_t lStreamPos; { *ppxNetworkBuffer = pxNewBuffer; pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer; + + /* Map the byte stream onto ProtocolHeaders_t struct for easy + * access to the fields. */ pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); pucSendData = &( pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) + ipSIZE_OF_TCP_HEADER + uxOptionsLength ] ); @@ -2037,6 +2070,7 @@ int32_t lCount, lLength; */ static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer ) { +/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader ); @@ -2133,10 +2167,13 @@ uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr ); */ static BaseType_t prvCheckRxData( const NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData ) { +/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ( size_t ) ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); const TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader ); int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength; + +/* Map the buffer onto an IPHeader_t struct for easy access to fields. */ const IPHeader_t *pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) ); const size_t xIPHeaderLength = ipSIZE_OF_IPv4_HEADER; uint16_t usLength; @@ -2205,6 +2242,7 @@ uint16_t usLength; static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, const uint8_t *pucRecvData, NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength ) { +/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader; @@ -2282,6 +2320,7 @@ BaseType_t xResult = 0; /* Set the TCP options (if any) for the outgoing packet. */ static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer ) { +/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader; @@ -2344,6 +2383,7 @@ UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength; static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, const NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength, UBaseType_t uxOptionsLength ) { +/* Map the ethernet buffer onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader; @@ -2353,19 +2393,21 @@ uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ); BaseType_t xSendLength = 0; /* Either expect a ACK or a SYN+ACK. */ - uint16_t usExpect = ( uint16_t ) tcpTCP_FLAG_ACK; + uint8_t ucExpect = tcpTCP_FLAG_ACK; if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN ) { - usExpect |= ( uint16_t ) tcpTCP_FLAG_SYN; + ucExpect |= tcpTCP_FLAG_SYN; } - if( ipNUMERIC_CAST( uint16_t, ucTCPFlags & 0x17U ) != usExpect ) + const uint8_t ucFlagsMask = tcpTCP_FLAG_ACK | tcpTCP_FLAG_RST | tcpTCP_FLAG_SYN | tcpTCP_FLAG_FIN; + + if( ( ucTCPFlags & ucFlagsMask ) != ucExpect ) { /* eSYN_RECEIVED: flags 0010 expected, not 0002. */ /* eSYN_RECEIVED: flags ACK expected, not SYN. */ FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n", ( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eSYN_RECEIVED ) ? "eSYN_RECEIVED" : "eCONNECT_SYN", - usExpect, ucTCPFlags ) ); + ucExpect, ucTCPFlags ) ); vTCPStateChange( pxSocket, eCLOSE_WAIT ); /* Send RST with the expected sequence and ACK numbers, otherwise the packet will be ignored. */ @@ -2383,6 +2425,7 @@ BaseType_t xSendLength = 0; if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN ) { + /* Map the Last packet onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxLastHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); @@ -2460,6 +2503,7 @@ BaseType_t xSendLength = 0; static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, uint32_t ulReceiveLength, UBaseType_t uxOptionsLength ) { +/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ] ) ); TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader; @@ -2623,6 +2667,7 @@ uint16_t usWindow; static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, uint32_t ulReceiveLength, BaseType_t xByteCount ) { +/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */ const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) ); const TCPHeader_t *pxTCPHeader = &pxProtocolHeaders->xTCPHeader; @@ -2767,6 +2812,7 @@ BaseType_t xSendLength = xByteCount; */ static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer ) { +/* Map the buffer onto the ProtocolHeader_t struct for easy access to the fields. */ ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( ProtocolHeaders_t *, &( ( *ppxNetworkBuffer )->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( *ppxNetworkBuffer ) ] ) ); TCPHeader_t *pxTCPHeader = &( pxProtocolHeaders->xTCPHeader ); @@ -2951,14 +2997,15 @@ static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNe ( void ) ucTCPFlags; #else { + /* Map the ethernet buffer onto the TCPPacket_t struct for easy access to the fields. */ TCPPacket_t *pxTCPPacket = ipPOINTER_CAST( TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer ); - const BaseType_t xSendLength = ( BaseType_t ) + const uint32_t ulSendLength = ( uint32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ); /* Plus 0 options. */ pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags; pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER ) << 2; - prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE ); + prvTCPReturnPacket( NULL, pxNetworkBuffer, ulSendLength, pdFALSE ); } #endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */ @@ -3013,6 +3060,8 @@ BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxDescriptor ) { /* Function might modify the parameter. */ NetworkBufferDescriptor_t *pxNetworkBuffer = pxDescriptor; + +/* Map the buffer onto a ProtocolHeaders_t struct for easy access to the fields. */ const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); FreeRTOS_Socket_t *pxSocket; @@ -3031,209 +3080,211 @@ const IPHeader_t *pxIPHeader; /* Check for a minimum packet size. */ if( pxNetworkBuffer->xDataLength < ( ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) + ipSIZE_OF_TCP_HEADER ) ) { - return pdFAIL; + xResult = pdFAIL; } - - pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) ); - ulLocalIP = FreeRTOS_htonl( pxIPHeader->ulDestinationIPAddress ); - ulRemoteIP = FreeRTOS_htonl( pxIPHeader->ulSourceIPAddress ); - - /* Find the destination socket, and if not found: return a socket listing to - the destination PORT. */ - pxSocket = ( FreeRTOS_Socket_t * ) pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort ); - - if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ipNUMERIC_CAST( eIPTCPState_t, pxSocket->u.xTCP.ucTCPState ) ) == pdFALSE ) ) + else { - /* A TCP messages is received but either there is no socket with the - given port number or the there is a socket, but it is in one of these - non-active states: eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or - eTIME_WAIT. */ + /* Map the ethernet buffer onto the IPHeader_t struct for easy access to the fields. */ + pxIPHeader = ipPOINTER_CAST( const IPHeader_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER ] ) ); + ulLocalIP = FreeRTOS_htonl( pxIPHeader->ulDestinationIPAddress ); + ulRemoteIP = FreeRTOS_htonl( pxIPHeader->ulSourceIPAddress ); - FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%lxip:%d)\n", xLocalPort, ulRemoteIP, xRemotePort ) ); + /* Find the destination socket, and if not found: return a socket listing to + the destination PORT. */ + pxSocket = ( FreeRTOS_Socket_t * ) pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort ); - /* Send a RST to all packets that can not be handled. As a result - the other party will get a ECONN error. There are two exceptions: - 1) A packet that already has the RST flag set. - 2) A packet that only has the ACK flag set. - A packet with only the ACK flag set might be the last ACK in - a three-way hand-shake that closes a connection. */ - if( ( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) != tcpTCP_FLAG_ACK ) && - ( ( ucTCPFlags & tcpTCP_FLAG_RST ) == 0U ) ) + if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ipNUMERIC_CAST( eIPTCPState_t, pxSocket->u.xTCP.ucTCPState ) ) == pdFALSE ) ) { - ( void ) prvTCPSendReset( pxNetworkBuffer ); - } + /* A TCP messages is received but either there is no socket with the + given port number or the there is a socket, but it is in one of these + non-active states: eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or + eTIME_WAIT. */ - /* The packet can't be handled. */ - xResult = pdFAIL; - } - else - { - pxSocket->u.xTCP.ucRepCount = 0U; + FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%lxip:%d)\n", xLocalPort, ulRemoteIP, xRemotePort ) ); - if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eTCP_LISTEN ) - { - /* The matching socket is in a listening state. Test if the peer - has set the SYN flag. */ - if( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) != tcpTCP_FLAG_SYN ) + /* Send a RST to all packets that can not be handled. As a result + the other party will get a ECONN error. There are two exceptions: + 1) A packet that already has the RST flag set. + 2) A packet that only has the ACK flag set. + A packet with only the ACK flag set might be the last ACK in + a three-way hand-shake that closes a connection. */ + if( ( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) != tcpTCP_FLAG_ACK ) && + ( ( ucTCPFlags & tcpTCP_FLAG_RST ) == 0U ) ) { - /* What happens: maybe after a reboot, a client doesn't know the - connection had gone. Send a RST in order to get a new connect - request. */ - #if( ipconfigHAS_DEBUG_PRINTF == 1 ) - { - FreeRTOS_debug_printf( ( "TCP: Server can't handle flags: %s from %lxip:%u to port %u\n", - prvTCPFlagMeaning( ( UBaseType_t ) ucTCPFlags ), ulRemoteIP, xRemotePort, xLocalPort ) ); - } - #endif /* ipconfigHAS_DEBUG_PRINTF */ - - if( ( ucTCPFlags & tcpTCP_FLAG_RST ) == 0U ) - { - ( void ) prvTCPSendReset( pxNetworkBuffer ); - } - xResult = pdFAIL; + ( void ) prvTCPSendReset( pxNetworkBuffer ); } - else - { - /* prvHandleListen() will either return a newly created socket - (if bReuseSocket is false), otherwise it returns the current - socket which will later get connected. */ - pxSocket = prvHandleListen( pxSocket, pxNetworkBuffer ); - if( pxSocket == NULL ) - { - xResult = pdFAIL; - } - } - } /* if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN ). */ + /* The packet can't be handled. */ + xResult = pdFAIL; + } else { - /* This is not a socket in listening mode. Check for the RST - flag. */ - if( ( ucTCPFlags & tcpTCP_FLAG_RST ) != 0U ) - { - FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) ); + pxSocket->u.xTCP.ucRepCount = 0U; - /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */ - if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN ) + if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eTCP_LISTEN ) + { + /* The matching socket is in a listening state. Test if the peer + has set the SYN flag. */ + if( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) != tcpTCP_FLAG_SYN ) { - /* Per the above RFC, "In the SYN-SENT state ... the RST is - acceptable if the ACK field acknowledges the SYN." */ - if( ulAckNumber == ( pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1UL ) ) + /* What happens: maybe after a reboot, a client doesn't know the + connection had gone. Send a RST in order to get a new connect + request. */ + #if( ipconfigHAS_DEBUG_PRINTF == 1 ) + { + FreeRTOS_debug_printf( ( "TCP: Server can't handle flags: %s from %lxip:%u to port %u\n", + prvTCPFlagMeaning( ( UBaseType_t ) ucTCPFlags ), ulRemoteIP, xRemotePort, xLocalPort ) ); + } + #endif /* ipconfigHAS_DEBUG_PRINTF */ + + if( ( ucTCPFlags & tcpTCP_FLAG_RST ) == 0U ) { - vTCPStateChange( pxSocket, eCLOSED ); + ( void ) prvTCPSendReset( pxNetworkBuffer ); } + xResult = pdFAIL; } else { - /* Check whether the packet matches the next expected sequence number. */ - if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber ) + /* prvHandleListen() will either return a newly created socket + (if bReuseSocket is false), otherwise it returns the current + socket which will later get connected. */ + pxSocket = prvHandleListen( pxSocket, pxNetworkBuffer ); + + if( pxSocket == NULL ) { - vTCPStateChange( pxSocket, eCLOSED ); + xResult = pdFAIL; } - /* Otherwise, check whether the packet is within the receive window. */ - else if( ( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber ) && - ( ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber + - pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) ) ) + } + } /* if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN ). */ + else + { + /* This is not a socket in listening mode. Check for the RST + flag. */ + if( ( ucTCPFlags & tcpTCP_FLAG_RST ) != 0U ) + { + FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) ); + + /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */ + if( pxSocket->u.xTCP.ucTCPState == ( uint8_t ) eCONNECT_SYN ) { - /* Send a challenge ACK. */ - ( void ) prvTCPSendChallengeAck( pxNetworkBuffer ); + /* Per the above RFC, "In the SYN-SENT state ... the RST is + acceptable if the ACK field acknowledges the SYN." */ + if( ulAckNumber == ( pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1UL ) ) + { + vTCPStateChange( pxSocket, eCLOSED ); + } } else { - /* Nothing. */ + /* Check whether the packet matches the next expected sequence number. */ + if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber ) + { + vTCPStateChange( pxSocket, eCLOSED ); + } + /* Otherwise, check whether the packet is within the receive window. */ + else if( ( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber ) && + ( ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber + + pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) ) ) + { + /* Send a challenge ACK. */ + ( void ) prvTCPSendChallengeAck( pxNetworkBuffer ); + } + else + { + /* Nothing. */ + } } - } - /* Otherwise, do nothing. In any case, the packet cannot be handled. */ - xResult = pdFAIL; - } - else if( ( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) == tcpTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= ( uint8_t ) eESTABLISHED ) ) - { - /* SYN flag while this socket is already connected. */ - FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %lxip:%u\n", ulRemoteIP, xRemotePort ) ); + /* Otherwise, do nothing. In any case, the packet cannot be handled. */ + xResult = pdFAIL; + } + else if( ( ( ucTCPFlags & tcpTCP_FLAG_CTRL ) == tcpTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= ( uint8_t ) eESTABLISHED ) ) + { + /* SYN flag while this socket is already connected. */ + FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %lxip:%u\n", ulRemoteIP, xRemotePort ) ); - /* The packet cannot be handled. */ - xResult = pdFAIL; - } - else - { - /* Update the copy of the TCP header only (skipping eth and IP - headers). It might be used later on, whenever data must be sent - to the peer. */ - const BaseType_t lOffset = ipNUMERIC_CAST( BaseType_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ); - ( void ) memcpy( &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ lOffset ] ), - &( pxNetworkBuffer->pucEthernetBuffer[ lOffset ] ), - ipSIZE_OF_TCP_HEADER ); + /* The packet cannot be handled. */ + xResult = pdFAIL; + } + else + { + /* Update the copy of the TCP header only (skipping eth and IP + headers). It might be used later on, whenever data must be sent + to the peer. */ + const size_t lOffset = ipNUMERIC_CAST( size_t, ipSIZE_OF_ETH_HEADER + uxIPHeaderSizeSocket( pxSocket ) ); + ( void ) memcpy( &( pxSocket->u.xTCP.xPacket.u.ucLastPacket[ lOffset ] ), + &( pxNetworkBuffer->pucEthernetBuffer[ lOffset ] ), + ipSIZE_OF_TCP_HEADER ); + } } } - } - if( xResult != pdFAIL ) - { - uint16_t usWindow; + if( xResult != pdFAIL ) + { + uint16_t usWindow; - /* pxSocket is not NULL when xResult != pdFAIL. */ - configASSERT( pxSocket != NULL ); - /* Touch the alive timers because we received a message for this - socket. */ - prvTCPTouchSocket( pxSocket ); + /* pxSocket is not NULL when xResult != pdFAIL. */ + configASSERT( pxSocket != NULL ); + /* Touch the alive timers because we received a message for this + socket. */ + prvTCPTouchSocket( pxSocket ); - /* Parse the TCP option(s), if present. */ - /* _HT_ : if we're in the SYN phase, and peer does not send a MSS option, - then we MUST assume an MSS size of 536 bytes for backward compatibility. */ + /* Parse the TCP option(s), if present. */ + /* _HT_ : if we're in the SYN phase, and peer does not send a MSS option, + then we MUST assume an MSS size of 536 bytes for backward compatibility. */ - /* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as - the number 5 (words) in the higher nibble of the TCP-offset byte. */ - if( ( pxProtocolHeaders->xTCPHeader.ucTCPOffset & tcpTCP_OFFSET_LENGTH_BITS ) > tcpTCP_OFFSET_STANDARD_LENGTH ) - { - prvCheckOptions( pxSocket, pxNetworkBuffer ); - } - - usWindow = FreeRTOS_ntohs( pxProtocolHeaders->xTCPHeader.usWindow ); - pxSocket->u.xTCP.ulWindowSize = (uint32_t ) usWindow; - #if( ipconfigUSE_TCP_WIN == 1 ) - { - /* rfc1323 : The Window field in a SYN (i.e., a <SYN> or <SYN,ACK>) - segment itself is never scaled. */ - if( ( ucTCPFlags & ( uint8_t ) tcpTCP_FLAG_SYN ) == 0U ) + /* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as + the number 5 (words) in the higher nibble of the TCP-offset byte. */ + if( ( pxProtocolHeaders->xTCPHeader.ucTCPOffset & tcpTCP_OFFSET_LENGTH_BITS ) > tcpTCP_OFFSET_STANDARD_LENGTH ) { - pxSocket->u.xTCP.ulWindowSize = - ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor ); + prvCheckOptions( pxSocket, pxNetworkBuffer ); } - } - #endif /* ipconfigUSE_TCP_WIN */ - /* In prvTCPHandleState() the incoming messages will be handled - depending on the current state of the connection. */ - if( prvTCPHandleState( pxSocket, &pxNetworkBuffer ) > 0 ) - { - /* prvTCPHandleState() has sent a message, see if there are more to - be transmitted. */ + usWindow = FreeRTOS_ntohs( pxProtocolHeaders->xTCPHeader.usWindow ); + pxSocket->u.xTCP.ulWindowSize = (uint32_t ) usWindow; #if( ipconfigUSE_TCP_WIN == 1 ) { - ( void ) prvTCPSendRepeated( pxSocket, &pxNetworkBuffer ); + /* rfc1323 : The Window field in a SYN (i.e., a <SYN> or <SYN,ACK>) + segment itself is never scaled. */ + if( ( ucTCPFlags & ( uint8_t ) tcpTCP_FLAG_SYN ) == 0U ) + { + pxSocket->u.xTCP.ulWindowSize = + ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor ); + } } #endif /* ipconfigUSE_TCP_WIN */ - } - if( pxNetworkBuffer != NULL ) - { - /* We must check if the buffer is unequal to NULL, because the - socket might keep a reference to it in case a delayed ACK must be - sent. */ - vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ); - #ifndef _lint - /* Clear pointers that are freed. */ - pxNetworkBuffer = NULL; - #endif - } + /* In prvTCPHandleState() the incoming messages will be handled + depending on the current state of the connection. */ + if( prvTCPHandleState( pxSocket, &pxNetworkBuffer ) > 0 ) + { + /* prvTCPHandleState() has sent a message, see if there are more to + be transmitted. */ + #if( ipconfigUSE_TCP_WIN == 1 ) + { + ( void ) prvTCPSendRepeated( pxSocket, &pxNetworkBuffer ); + } + #endif /* ipconfigUSE_TCP_WIN */ + } - /* And finally, calculate when this socket wants to be woken up. */ - ( void ) prvTCPNextTimeout ( pxSocket ); - /* Return pdPASS to tell that the network buffer is 'consumed'. */ - xResult = pdPASS; - } + if( pxNetworkBuffer != NULL ) + { + /* We must check if the buffer is unequal to NULL, because the + socket might keep a reference to it in case a delayed ACK must be + sent. */ + vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ); + #ifndef _lint + /* Clear pointers that are freed. */ + pxNetworkBuffer = NULL; + #endif + } + /* And finally, calculate when this socket wants to be woken up. */ + ( void ) prvTCPNextTimeout ( pxSocket ); + /* Return pdPASS to tell that the network buffer is 'consumed'. */ + xResult = pdPASS; + } + } /* pdPASS being returned means the buffer has been consumed. */ return xResult; } @@ -3241,6 +3292,7 @@ const IPHeader_t *pxIPHeader; static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer ) { +/* Map the ethernet buffer onto a TCPPacket_t struct for easy access to the fields. */ const TCPPacket_t * pxTCPPacket = ipPOINTER_CAST( const TCPPacket_t *, pxNetworkBuffer->pucEthernetBuffer ); FreeRTOS_Socket_t *pxReturn = NULL; uint32_t ulInitialSequenceNumber; @@ -3307,6 +3359,7 @@ uint32_t ulInitialSequenceNumber; if( ( ulInitialSequenceNumber != 0U ) && ( pxReturn != NULL ) ) { + /* Map the byte stream onto the ProtocolHeaders_t for easy access to the fields. */ const ProtocolHeaders_t *pxProtocolHeaders = ipPOINTER_CAST( const ProtocolHeaders_t *, &( pxNetworkBuffer->pucEthernetBuffer[ ipSIZE_OF_ETH_HEADER + xIPHeaderSize( pxNetworkBuffer ) ] ) ); diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h index 3ee86faa7..cd6b048e4 100644 --- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h +++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h @@ -401,6 +401,7 @@ socket events. */ (right) = tmp; \ } while ( ipFALSE_BOOL ) +/* WARNING: Do NOT use this macro when the array was received as a parameter. */ #ifndef ARRAY_SIZE #define ARRAY_SIZE(x) ( ( BaseType_t ) ( sizeof( x ) / sizeof( ( x )[ 0 ] ) ) ) #endif |